Top level declarations (#56)

* chore(): declarations

* fixes

* fix a jk

* fix components

* fix
This commit is contained in:
Marcos Susaña 2022-07-15 14:03:23 -04:00 committed by GitHub
parent ab9379f80b
commit 89c43eb3a5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
34 changed files with 293 additions and 281 deletions

View File

@ -1,29 +1,29 @@
import type { Snowflake } from "./Snowflake.ts"; import type { Snowflake } from "./Snowflake.ts";
import { baseEndpoints as Endpoints } from "../discordeno/mod.ts"; import { baseEndpoints as Endpoints } from "../discordeno/mod.ts";
export function USER_AVATAR(userId: Snowflake, icon: string) { export function USER_AVATAR(userId: Snowflake, icon: string): string {
return `${Endpoints.CDN_URL}/avatars/${userId}/${icon}`; return `${Endpoints.CDN_URL}/avatars/${userId}/${icon}`;
} }
export function EMOJI_URL(id: Snowflake, animated = false) { export function EMOJI_URL(id: Snowflake, animated = false): string {
return `https://cdn.discordapp.com/emojis/${id}.${animated ? "gif" : "png"}`; return `https://cdn.discordapp.com/emojis/${id}.${animated ? "gif" : "png"}`;
} }
export function USER_DEFAULT_AVATAR( export function USER_DEFAULT_AVATAR(
/** user discriminator */ /** user discriminator */
altIcon: number, altIcon: number,
) { ): string {
return `${Endpoints.CDN_URL}/embed/avatars/${altIcon}.png`; return `${Endpoints.CDN_URL}/embed/avatars/${altIcon}.png`;
} }
export function GUILD_BANNER(guildId: Snowflake, icon: string) { export function GUILD_BANNER(guildId: Snowflake, icon: string): string {
return `${Endpoints.CDN_URL}/banners/${guildId}/${icon}`; return `${Endpoints.CDN_URL}/banners/${guildId}/${icon}`;
} }
export function GUILD_SPLASH(guildId: Snowflake, icon: string) { export function GUILD_SPLASH(guildId: Snowflake, icon: string): string {
return `${Endpoints.CDN_URL}/splashes/${guildId}/${icon}`; return `${Endpoints.CDN_URL}/splashes/${guildId}/${icon}`;
} }
export function GUILD_ICON(guildId: Snowflake, icon: string) { export function GUILD_ICON(guildId: Snowflake, icon: string): string {
return `${Endpoints.CDN_URL}/icons/${guildId}/${icon}`; return `${Endpoints.CDN_URL}/icons/${guildId}/${icon}`;
} }

View File

@ -3,11 +3,11 @@ import type { Snowflake } from "./Snowflake.ts";
// cdn endpoints // cdn endpoints
export * from "./Cdn.ts"; export * from "./Cdn.ts";
export function USER(userId: Snowflake) { export function USER(userId: Snowflake): string {
return `/users/${userId}`; return `/users/${userId}`;
} }
export function GATEWAY_BOT() { export function GATEWAY_BOT(): string {
return "/gateway/bot"; return "/gateway/bot";
} }
@ -30,28 +30,28 @@ export interface GetMessagesOptions {
limit?: number; limit?: number;
} }
export function CHANNEL(channelId: Snowflake) { export function CHANNEL(channelId: Snowflake): string {
return `/channels/${channelId}`; return `/channels/${channelId}`;
} }
export function CHANNEL_INVITES(channelId: Snowflake) { export function CHANNEL_INVITES(channelId: Snowflake): string {
return `/channels/${channelId}/invites`; return `/channels/${channelId}/invites`;
} }
export function CHANNEL_TYPING(channelId: Snowflake) { export function CHANNEL_TYPING(channelId: Snowflake): string {
return `/channels/${channelId}/typing`; return `/channels/${channelId}/typing`;
} }
export function CHANNEL_CREATE_THREAD(channelId: Snowflake) { export function CHANNEL_CREATE_THREAD(channelId: Snowflake): string {
return `/channels/${channelId}/threads`; return `/channels/${channelId}/threads`;
} }
export function MESSAGE_CREATE_THREAD(channelId: Snowflake, messageId: Snowflake) { export function MESSAGE_CREATE_THREAD(channelId: Snowflake, messageId: Snowflake): string {
return `/channels/${channelId}/messages/${messageId}/threads`; return `/channels/${channelId}/messages/${messageId}/threads`;
} }
/** used to send messages */ /** used to send messages */
export function CHANNEL_MESSAGES(channelId: Snowflake, options?: GetMessagesOptions) { export function CHANNEL_MESSAGES(channelId: Snowflake, options?: GetMessagesOptions): string {
let url = `/channels/${channelId}/messages?`; let url = `/channels/${channelId}/messages?`;
if (options) { if (options) {
@ -65,17 +65,17 @@ export function CHANNEL_MESSAGES(channelId: Snowflake, options?: GetMessagesOpti
} }
/** used to edit messages */ /** used to edit messages */
export function CHANNEL_MESSAGE(channelId: Snowflake, messageId: Snowflake) { export function CHANNEL_MESSAGE(channelId: Snowflake, messageId: Snowflake): string {
return `/channels/${channelId}/messages/${messageId}`; return `/channels/${channelId}/messages/${messageId}`;
} }
/** used to kick members */ /** used to kick members */
export function GUILD_MEMBER(guildId: Snowflake, userId: Snowflake) { export function GUILD_MEMBER(guildId: Snowflake, userId: Snowflake): string {
return `/guilds/${guildId}/members/${userId}`; return `/guilds/${guildId}/members/${userId}`;
} }
/** used to ban members */ /** used to ban members */
export function GUILD_BAN(guildId: Snowflake, userId: Snowflake) { export function GUILD_BAN(guildId: Snowflake, userId: Snowflake): string {
return `/guilds/${guildId}/bans/${userId}`; return `/guilds/${guildId}/bans/${userId}`;
} }
@ -86,7 +86,7 @@ export interface GetBans {
} }
/** used to unban members */ /** used to unban members */
export function GUILD_BANS(guildId: Snowflake, options?: GetBans) { export function GUILD_BANS(guildId: Snowflake, options?: GetBans): string {
let url = `/guilds/${guildId}/bans?`; let url = `/guilds/${guildId}/bans?`;
if (options) { if (options) {
@ -98,11 +98,11 @@ export function GUILD_BANS(guildId: Snowflake, options?: GetBans) {
return url; return url;
} }
export function GUILD_ROLE(guildId: Snowflake, roleId: Snowflake) { export function GUILD_ROLE(guildId: Snowflake, roleId: Snowflake): string {
return `/guilds/${guildId}/roles/${roleId}`; return `/guilds/${guildId}/roles/${roleId}`;
} }
export function GUILD_ROLES(guildId: Snowflake) { export function GUILD_ROLES(guildId: Snowflake): string {
return `/guilds/${guildId}/roles`; return `/guilds/${guildId}/roles`;
} }
@ -110,11 +110,11 @@ export function USER_DM() {
return `/users/@me/channels`; return `/users/@me/channels`;
} }
export function GUILD_EMOJIS(guildId: Snowflake) { export function GUILD_EMOJIS(guildId: Snowflake): string {
return `/guilds/${guildId}/emojis`; return `/guilds/${guildId}/emojis`;
} }
export function GUILD_EMOJI(guildId: Snowflake, emojiId: Snowflake) { export function GUILD_EMOJI(guildId: Snowflake, emojiId: Snowflake): string {
return `/guilds/${guildId}/emojis/${emojiId}`; return `/guilds/${guildId}/emojis/${emojiId}`;
} }
@ -124,18 +124,18 @@ export interface GetInvite {
scheduledEventId?: Snowflake; scheduledEventId?: Snowflake;
} }
export function GUILDS() { export function GUILDS(): string {
return `/guilds`; return `/guilds`;
} }
export function AUTO_MODERATION_RULES(guildId: Snowflake, ruleId?: Snowflake) { export function AUTO_MODERATION_RULES(guildId: Snowflake, ruleId?: Snowflake): string {
if (ruleId) { if (ruleId) {
return `/guilds/${guildId}/auto-moderation/rules/${ruleId}`; return `/guilds/${guildId}/auto-moderation/rules/${ruleId}`;
} }
return `/guilds/${guildId}/auto-moderation/rules`; return `/guilds/${guildId}/auto-moderation/rules`;
} }
export function INVITE(inviteCode: string, options?: GetInvite) { export function INVITE(inviteCode: string, options?: GetInvite): string {
let url = `/invites/${inviteCode}?`; let url = `/invites/${inviteCode}?`;
if (options) { if (options) {
@ -147,19 +147,19 @@ export function INVITE(inviteCode: string, options?: GetInvite) {
return url; return url;
} }
export function GUILD_INVITES(guildId: Snowflake) { export function GUILD_INVITES(guildId: Snowflake): string {
return `/guilds/${guildId}/invites`; return `/guilds/${guildId}/invites`;
} }
export function INTERACTION_ID_TOKEN(interactionId: Snowflake, token: string) { export function INTERACTION_ID_TOKEN(interactionId: Snowflake, token: string): string {
return `/interactions/${interactionId}/${token}/callback`; return `/interactions/${interactionId}/${token}/callback`;
} }
export function WEBHOOK_MESSAGE(webhookId: Snowflake, token: string, messageId: Snowflake) { export function WEBHOOK_MESSAGE(webhookId: Snowflake, token: string, messageId: Snowflake): string {
return `/webhooks/${webhookId}/${token}/messages/${messageId}`; return `/webhooks/${webhookId}/${token}/messages/${messageId}`;
} }
export function WEBHOOK_TOKEN(webhookId: Snowflake, token?: string) { export function WEBHOOK_TOKEN(webhookId: Snowflake, token?: string): string {
if (!token) return `/webhooks/${webhookId}`; if (!token) return `/webhooks/${webhookId}`;
return `/webhooks/${webhookId}/${token}`; return `/webhooks/${webhookId}/${token}`;
} }
@ -169,7 +169,7 @@ export interface WebhookOptions {
threadId?: Snowflake; threadId?: Snowflake;
} }
export function WEBHOOK(webhookId: Snowflake, token: string, options?: WebhookOptions) { export function WEBHOOK(webhookId: Snowflake, token: string, options?: WebhookOptions): string {
let url = `/webhooks/${webhookId}/${token}`; let url = `/webhooks/${webhookId}/${token}`;
if (options?.wait) url += `?wait=${options.wait}`; if (options?.wait) url += `?wait=${options.wait}`;
@ -179,7 +179,7 @@ export function WEBHOOK(webhookId: Snowflake, token: string, options?: WebhookOp
return url; return url;
} }
export function USER_NICK(guildId: Snowflake) { export function USER_NICK(guildId: Snowflake): string {
return `/guilds/${guildId}/members/@me`; return `/guilds/${guildId}/members/@me`;
} }
@ -191,7 +191,7 @@ export interface GetGuildPruneCountQuery {
includeRoles?: Snowflake | Snowflake[]; includeRoles?: Snowflake | Snowflake[];
} }
export function GUILD_PRUNE(guildId: Snowflake, options?: GetGuildPruneCountQuery) { export function GUILD_PRUNE(guildId: Snowflake, options?: GetGuildPruneCountQuery): string {
let url = `/guilds/${guildId}/prune?`; let url = `/guilds/${guildId}/prune?`;
if (options?.days) url += `days=${options.days}`; if (options?.days) url += `days=${options.days}`;
@ -200,15 +200,15 @@ export function GUILD_PRUNE(guildId: Snowflake, options?: GetGuildPruneCountQuer
return url; return url;
} }
export function CHANNEL_PIN(channelId: Snowflake, messageId: Snowflake) { export function CHANNEL_PIN(channelId: Snowflake, messageId: Snowflake): string {
return `/channels/${channelId}/pins/${messageId}`; return `/channels/${channelId}/pins/${messageId}`;
} }
export function CHANNEL_PINS(channelId: Snowflake) { export function CHANNEL_PINS(channelId: Snowflake): string {
return `/channels/${channelId}/pins`; return `/channels/${channelId}/pins`;
} }
export function CHANNEL_MESSAGE_REACTION_ME(channelId: Snowflake, messageId: Snowflake, emoji: string) { export function CHANNEL_MESSAGE_REACTION_ME(channelId: Snowflake, messageId: Snowflake, emoji: string): string {
return `/channels/${channelId}/messages/${messageId}/reactions/${encodeURIComponent(emoji)}/@me`; return `/channels/${channelId}/messages/${messageId}/reactions/${encodeURIComponent(emoji)}/@me`;
} }
@ -238,7 +238,7 @@ export function CHANNEL_MESSAGE_REACTION(
messageId: Snowflake, messageId: Snowflake,
emoji: string, emoji: string,
options?: GetReactions, options?: GetReactions,
) { ): string {
let url = `/channels/${channelId}/messages/${messageId}/reactions/${encodeURIComponent(emoji)}?`; let url = `/channels/${channelId}/messages/${messageId}/reactions/${encodeURIComponent(emoji)}?`;
if (options?.after) url += `after=${options.after}`; if (options?.after) url += `after=${options.after}`;
@ -247,27 +247,27 @@ export function CHANNEL_MESSAGE_REACTION(
return url; return url;
} }
export function CHANNEL_MESSAGE_CROSSPOST(channelId: Snowflake, messageId: Snowflake) { export function CHANNEL_MESSAGE_CROSSPOST(channelId: Snowflake, messageId: Snowflake): string {
return `/channels/${channelId}/messages/${messageId}/crosspost`; return `/channels/${channelId}/messages/${messageId}/crosspost`;
} }
export function GUILD_MEMBER_ROLE(guildId: Snowflake, memberId: Snowflake, roleId: Snowflake) { export function GUILD_MEMBER_ROLE(guildId: Snowflake, memberId: Snowflake, roleId: Snowflake): string {
return `/guilds/${guildId}/members/${memberId}/roles/${roleId}`; return `/guilds/${guildId}/members/${memberId}/roles/${roleId}`;
} }
export function CHANNEL_WEBHOOKS(channelId: Snowflake) { export function CHANNEL_WEBHOOKS(channelId: Snowflake): string {
return `/channels/${channelId}/webhooks`; return `/channels/${channelId}/webhooks`;
} }
export function THREAD_START_PUBLIC(channelId: Snowflake, messageId: Snowflake) { export function THREAD_START_PUBLIC(channelId: Snowflake, messageId: Snowflake): string {
return `/channels/${channelId}/messages/${messageId}/threads`; return `/channels/${channelId}/messages/${messageId}/threads`;
} }
export function THREAD_START_PRIVATE(channelId: Snowflake) { export function THREAD_START_PRIVATE(channelId: Snowflake): string {
return `/channels/${channelId}/threads`; return `/channels/${channelId}/threads`;
} }
export function THREAD_ACTIVE(guildId: Snowflake) { export function THREAD_ACTIVE(guildId: Snowflake): string {
return `/guilds/${guildId}/threads/active`; return `/guilds/${guildId}/threads/active`;
} }
@ -276,23 +276,23 @@ export interface ListArchivedThreads {
limit?: number; limit?: number;
} }
export function THREAD_ME(channelId: Snowflake) { export function THREAD_ME(channelId: Snowflake): string {
return `/channels/${channelId}/thread-members/@me`; return `/channels/${channelId}/thread-members/@me`;
} }
export function THREAD_MEMBERS(channelId: Snowflake) { export function THREAD_MEMBERS(channelId: Snowflake): string {
return `/channels/${channelId}/thread-members`; return `/channels/${channelId}/thread-members`;
} }
export function THREAD_USER(channelId: Snowflake, userId: Snowflake) { export function THREAD_USER(channelId: Snowflake, userId: Snowflake): string {
return `/channels/${channelId}/thread-members/${userId}`; return `/channels/${channelId}/thread-members/${userId}`;
} }
export function THREAD_ARCHIVED(channelId: Snowflake) { export function THREAD_ARCHIVED(channelId: Snowflake): string {
return `/channels/${channelId}/threads/archived`; return `/channels/${channelId}/threads/archived`;
} }
export function THREAD_ARCHIVED_PUBLIC(channelId: Snowflake, options?: ListArchivedThreads) { export function THREAD_ARCHIVED_PUBLIC(channelId: Snowflake, options?: ListArchivedThreads): string {
let url = `/channels/${channelId}/threads/archived/public?`; let url = `/channels/${channelId}/threads/archived/public?`;
if (options) { if (options) {
@ -303,7 +303,7 @@ export function THREAD_ARCHIVED_PUBLIC(channelId: Snowflake, options?: ListArchi
return url; return url;
} }
export function THREAD_ARCHIVED_PRIVATE(channelId: Snowflake, options?: ListArchivedThreads) { export function THREAD_ARCHIVED_PRIVATE(channelId: Snowflake, options?: ListArchivedThreads): string {
let url = `/channels/${channelId}/threads/archived/private?`; let url = `/channels/${channelId}/threads/archived/private?`;
if (options) { if (options) {
@ -314,7 +314,7 @@ export function THREAD_ARCHIVED_PRIVATE(channelId: Snowflake, options?: ListArch
return url; return url;
} }
export function THREAD_ARCHIVED_PRIVATE_JOINED(channelId: Snowflake, options?: ListArchivedThreads) { export function THREAD_ARCHIVED_PRIVATE_JOINED(channelId: Snowflake, options?: ListArchivedThreads): string {
let url = `/channels/${channelId}/users/@me/threads/archived/private?`; let url = `/channels/${channelId}/users/@me/threads/archived/private?`;
if (options) { if (options) {
@ -325,29 +325,29 @@ export function THREAD_ARCHIVED_PRIVATE_JOINED(channelId: Snowflake, options?: L
return url; return url;
} }
export function FORUM_START(channelId: Snowflake) { export function FORUM_START(channelId: Snowflake): string {
return `/channels/${channelId}/threads?has_message=true`; return `/channels/${channelId}/threads?has_message=true`;
} }
export function STAGE_INSTANCES() { export function STAGE_INSTANCES(): string {
return `/stage-instances`; return `/stage-instances`;
} }
export function STAGE_INSTANCE(channelId: Snowflake) { export function STAGE_INSTANCE(channelId: Snowflake): string {
return `/stage-instances/${channelId}`; return `/stage-instances/${channelId}`;
} }
export function APPLICATION_COMMANDS(appId: Snowflake, commandId?: Snowflake) { export function APPLICATION_COMMANDS(appId: Snowflake, commandId?: Snowflake): string {
if (commandId) return `/applications/${appId}/commands/${commandId}`; if (commandId) return `/applications/${appId}/commands/${commandId}`;
return `/applications/${appId}/commands`; return `/applications/${appId}/commands`;
} }
export function GUILD_APPLICATION_COMMANDS(appId: Snowflake, guildId: Snowflake, commandId?: Snowflake) { export function GUILD_APPLICATION_COMMANDS(appId: Snowflake, guildId: Snowflake, commandId?: Snowflake): string {
if (commandId) return `/applications/${appId}/guilds/${guildId}/commands/${commandId}`; if (commandId) return `/applications/${appId}/guilds/${guildId}/commands/${commandId}`;
return `/applications/${appId}/guilds/${guildId}/commands`; return `/applications/${appId}/guilds/${guildId}/commands`;
} }
export function GUILD_APPLICATION_COMMANDS_PERMISSIONS(appId: Snowflake, guildId: Snowflake, commandId?: Snowflake) { export function GUILD_APPLICATION_COMMANDS_PERMISSIONS(appId: Snowflake, guildId: Snowflake, commandId?: Snowflake): string {
if (commandId) return `/applications/${appId}/guilds/${guildId}/commands/${commandId}/permissions`; if (commandId) return `/applications/${appId}/guilds/${guildId}/commands/${commandId}/permissions`;
return `/applications/${appId}/guilds/${guildId}/commands/permissions`; return `/applications/${appId}/guilds/${guildId}/commands/permissions`;
} }
@ -356,7 +356,7 @@ export function APPLICATION_COMMANDS_LOCALIZATIONS(
appId: Snowflake, appId: Snowflake,
commandId: Snowflake, commandId: Snowflake,
withLocalizations?: boolean, withLocalizations?: boolean,
) { ): string {
let url = `/applications/${appId}/commands/${commandId}?`; let url = `/applications/${appId}/commands/${commandId}?`;
if (withLocalizations !== undefined) { if (withLocalizations !== undefined) {
@ -371,7 +371,7 @@ export function GUILD_APPLICATION_COMMANDS_LOCALIZATIONS(
guildId: Snowflake, guildId: Snowflake,
commandId: Snowflake, commandId: Snowflake,
withLocalizations?: boolean, withLocalizations?: boolean,
) { ): string {
let url = `/applications/${appId}/guilds/${guildId}/commands/${commandId}?`; let url = `/applications/${appId}/guilds/${guildId}/commands/${commandId}?`;
if (withLocalizations !== undefined) { if (withLocalizations !== undefined) {
@ -381,15 +381,15 @@ export function GUILD_APPLICATION_COMMANDS_LOCALIZATIONS(
return url; return url;
} }
export function STICKER(id: Snowflake) { export function STICKER(id: Snowflake): string {
return `stickers/${id}`; return `stickers/${id}`;
} }
export function STICKER_PACKS() { export function STICKER_PACKS(): string {
return `stickers-packs`; return `stickers-packs`;
} }
export function GUILD_STICKERS(guildId: Snowflake, stickerId?: Snowflake) { export function GUILD_STICKERS(guildId: Snowflake, stickerId?: Snowflake): string {
if (stickerId) return `/guilds/${guildId}/stickers/${stickerId}`; if (stickerId) return `/guilds/${guildId}/stickers/${stickerId}`;
return `/guilds/${guildId}/stickers`; return `/guilds/${guildId}/stickers`;
} }

View File

@ -256,14 +256,14 @@ export class Session extends EventEmitter {
} }
async fetchUser(id: Snowflake): Promise<User | undefined> { async fetchUser(id: Snowflake): Promise<User | undefined> {
const user = await this.rest.runMethod<DiscordUser>(this.rest, "GET", Routes.USER(id)); const user: DiscordUser = await this.rest.runMethod<DiscordUser>(this.rest, "GET", Routes.USER(id));
if (!user.id) return; if (!user.id) return;
return new User(this, user); return new User(this, user);
} }
createApplicationCommand(options: CreateApplicationCommand | CreateContextApplicationCommand, guildId?: Snowflake) { createApplicationCommand(options: CreateApplicationCommand | CreateContextApplicationCommand, guildId?: Snowflake): Promise<DiscordApplicationCommand> {
return this.rest.runMethod<DiscordApplicationCommand>( return this.rest.runMethod<DiscordApplicationCommand>(
this.rest, this.rest,
"POST", "POST",
@ -291,7 +291,7 @@ export class Session extends EventEmitter {
); );
} }
deleteApplicationCommand(id: Snowflake, guildId?: Snowflake) { deleteApplicationCommand(id: Snowflake, guildId?: Snowflake): Promise<undefined> {
return this.rest.runMethod<undefined>( return this.rest.runMethod<undefined>(
this.rest, this.rest,
"DELETE", "DELETE",
@ -306,7 +306,7 @@ export class Session extends EventEmitter {
id: Snowflake, id: Snowflake,
bearerToken: string, bearerToken: string,
options: ApplicationCommandPermissions[], options: ApplicationCommandPermissions[],
) { ): Promise<DiscordGuildApplicationCommandPermissions> {
return this.rest.runMethod<DiscordGuildApplicationCommandPermissions>( return this.rest.runMethod<DiscordGuildApplicationCommandPermissions>(
this.rest, this.rest,
"PUT", "PUT",
@ -320,7 +320,7 @@ export class Session extends EventEmitter {
); );
} }
fetchApplicationCommand(id: Snowflake, options?: GetApplicationCommand) { fetchApplicationCommand(id: Snowflake, options?: GetApplicationCommand): Promise<DiscordApplicationCommand> {
return this.rest.runMethod<DiscordApplicationCommand>( return this.rest.runMethod<DiscordApplicationCommand>(
this.rest, this.rest,
"GET", "GET",
@ -335,7 +335,7 @@ export class Session extends EventEmitter {
); );
} }
fetchApplicationCommandPermissions(guildId: Snowflake) { fetchApplicationCommandPermissions(guildId: Snowflake): Promise<DiscordGuildApplicationCommandPermissions[]> {
return this.rest.runMethod<DiscordGuildApplicationCommandPermissions[]>( return this.rest.runMethod<DiscordGuildApplicationCommandPermissions[]>(
this.rest, this.rest,
"GET", "GET",
@ -343,7 +343,7 @@ export class Session extends EventEmitter {
); );
} }
fetchApplicationCommandPermission(guildId: Snowflake, id: Snowflake) { fetchApplicationCommandPermission(guildId: Snowflake, id: Snowflake): Promise<DiscordGuildApplicationCommandPermissions> {
return this.rest.runMethod<DiscordGuildApplicationCommandPermissions>( return this.rest.runMethod<DiscordGuildApplicationCommandPermissions>(
this.rest, this.rest,
"GET", "GET",
@ -355,7 +355,7 @@ export class Session extends EventEmitter {
id: Snowflake, id: Snowflake,
options: AtLeastOne<CreateApplicationCommand> | AtLeastOne<CreateContextApplicationCommand>, options: AtLeastOne<CreateApplicationCommand> | AtLeastOne<CreateContextApplicationCommand>,
guildId?: Snowflake, guildId?: Snowflake,
) { ): Promise<DiscordApplicationCommand> {
return this.rest.runMethod<DiscordApplicationCommand>( return this.rest.runMethod<DiscordApplicationCommand>(
this.rest, this.rest,
"PATCH", "PATCH",
@ -379,7 +379,7 @@ export class Session extends EventEmitter {
upsertApplicationCommands( upsertApplicationCommands(
options: Array<UpsertApplicationCommands | CreateContextApplicationCommand>, options: Array<UpsertApplicationCommands | CreateContextApplicationCommand>,
guildId?: Snowflake, guildId?: Snowflake,
) { ): Promise<DiscordApplicationCommand[]> {
return this.rest.runMethod<DiscordApplicationCommand[]>( return this.rest.runMethod<DiscordApplicationCommand[]>(
this.rest, this.rest,
"PUT", "PUT",
@ -402,7 +402,7 @@ export class Session extends EventEmitter {
); );
} }
fetchCommands(guildId?: Snowflake) { fetchCommands(guildId?: Snowflake): Promise<DiscordApplicationCommand[]> {
return this.rest.runMethod<DiscordApplicationCommand[]>( return this.rest.runMethod<DiscordApplicationCommand[]>(
this.rest, this.rest,
"GET", "GET",
@ -417,7 +417,7 @@ export class Session extends EventEmitter {
return cmd.type === ApplicationCommandTypes.Message || cmd.type === ApplicationCommandTypes.User; return cmd.type === ApplicationCommandTypes.Message || cmd.type === ApplicationCommandTypes.User;
} }
async start() { async start(): Promise<void> {
const getGatewayBot = () => this.rest.runMethod<DiscordGetGatewayBot>(this.rest, "GET", Routes.GATEWAY_BOT()); const getGatewayBot = () => this.rest.runMethod<DiscordGetGatewayBot>(this.rest, "GET", Routes.GATEWAY_BOT());
// check if is empty // check if is empty

View File

@ -80,7 +80,7 @@ export class Util {
} }
static iconBigintToHash(icon: bigint) { static iconBigintToHash(icon: bigint) {
const hash = icon.toString(16); const hash: string = icon.toString(16);
return hash.startsWith("a") ? `a_${hash.substring(1)}` : hash.substring(1); return hash.startsWith("a") ? `a_${hash.substring(1)}` : hash.substring(1);
} }

View File

@ -41,7 +41,7 @@ export class GuildEmoji extends Emoji implements Model {
return this; return this;
} }
get url() { get url(): string {
return Routes.EMOJI_URL(this.id, this.animated); return Routes.EMOJI_URL(this.id, this.animated);
} }
} }

View File

@ -48,11 +48,11 @@ export class Member implements Model {
return this.user.id; return this.user.id;
} }
get nicknameOrUsername() { get nicknameOrUsername(): string {
return this.nickname ?? this.user.username; return this.nickname ?? this.user.username;
} }
get joinedAt() { get joinedAt(): Date {
return new Date(this.joinedTimestamp); return new Date(this.joinedTimestamp);
} }
@ -68,7 +68,7 @@ export class Member implements Model {
return this; return this;
} }
async unban() { async unban(): Promise<void> {
await Guild.prototype.unbanMember.call({ id: this.guildId, session: this.session }, this.user.id); await Guild.prototype.unbanMember.call({ id: this.guildId, session: this.session }, this.user.id);
} }
@ -82,11 +82,11 @@ export class Member implements Model {
return member; return member;
} }
async addRole(roleId: Snowflake, options: { reason?: string } = {}) { async addRole(roleId: Snowflake, options: { reason?: string } = {}): Promise<void> {
await Guild.prototype.addRole.call({ id: this.guildId, session: this.session }, this.user.id, roleId, options); await Guild.prototype.addRole.call({ id: this.guildId, session: this.session }, this.user.id, roleId, options);
} }
async removeRole(roleId: Snowflake, options: { reason?: string } = {}) { async removeRole(roleId: Snowflake, options: { reason?: string } = {}): Promise<void> {
await Guild.prototype.removeRole.call( await Guild.prototype.removeRole.call(
{ id: this.guildId, session: this.session }, { id: this.guildId, session: this.session },
this.user.id, this.user.id,
@ -96,7 +96,7 @@ export class Member implements Model {
} }
/** gets the user's avatar */ /** gets the user's avatar */
avatarURL(options: { format?: ImageFormat; size?: ImageSize } = { size: 128 }) { avatarURL(options: { format?: ImageFormat; size?: ImageSize } = { size: 128 }): string {
let url: string; let url: string;
if (this.user.bot) { if (this.user.bot) {
@ -112,7 +112,7 @@ export class Member implements Model {
return Util.formatImageURL(url, options.size, options.format); return Util.formatImageURL(url, options.size, options.format);
} }
toString() { toString(): string {
return `<@!${this.user.id}>`; return `<@!${this.user.id}>`;
} }
} }

View File

@ -176,36 +176,36 @@ export class Message implements Model {
type: MessageActivityTypes; type: MessageActivityTypes;
}; };
get createdTimestamp() { get createdTimestamp(): number {
return Snowflake.snowflakeToTimestamp(this.id); return Snowflake.snowflakeToTimestamp(this.id);
} }
get createdAt() { get createdAt(): Date {
return new Date(this.createdTimestamp); return new Date(this.createdTimestamp);
} }
get sentAt() { get sentAt(): Date {
return new Date(this.timestamp); return new Date(this.timestamp);
} }
get editedAt() { get editedAt(): Date | undefined {
return this.editedTimestamp ? new Date(this.editedTimestamp) : undefined; return this.editedTimestamp ? new Date(this.editedTimestamp) : undefined;
} }
get edited() { get edited(): number | undefined {
return this.editedTimestamp; return this.editedTimestamp;
} }
get url() { get url(): string {
return `https://discord.com/channels/${this.guildId ?? "@me"}/${this.channelId}/${this.id}`; return `https://discord.com/channels/${this.guildId ?? "@me"}/${this.channelId}/${this.id}`;
} }
/** Compatibility with Discordeno */ /** Compatibility with Discordeno */
get isBot() { get isBot(): boolean {
return this.author.bot; return this.author.bot;
} }
async pin() { async pin(): Promise<void> {
await this.session.rest.runMethod<undefined>( await this.session.rest.runMethod<undefined>(
this.session.rest, this.session.rest,
"PUT", "PUT",
@ -213,7 +213,7 @@ export class Message implements Model {
); );
} }
async unpin() { async unpin(): Promise<void> {
await this.session.rest.runMethod<undefined>( await this.session.rest.runMethod<undefined>(
this.session.rest, this.session.rest,
"DELETE", "DELETE",
@ -305,7 +305,7 @@ export class Message implements Model {
return this.addReaction; return this.addReaction;
} }
async addReaction(reaction: ReactionResolvable) { async addReaction(reaction: ReactionResolvable): Promise<void> {
const r = typeof reaction === "string" ? reaction : `${reaction.name}:${reaction.id}`; const r = typeof reaction === "string" ? reaction : `${reaction.name}:${reaction.id}`;
await this.session.rest.runMethod<undefined>( await this.session.rest.runMethod<undefined>(
@ -316,7 +316,7 @@ export class Message implements Model {
); );
} }
async removeReaction(reaction: ReactionResolvable, options?: { userId: Snowflake }) { async removeReaction(reaction: ReactionResolvable, options?: { userId: Snowflake }): Promise<void> {
const r = typeof reaction === "string" ? reaction : `${reaction.name}:${reaction.id}`; const r = typeof reaction === "string" ? reaction : `${reaction.name}:${reaction.id}`;
await this.session.rest.runMethod<undefined>( await this.session.rest.runMethod<undefined>(
@ -348,7 +348,7 @@ export class Message implements Model {
return users.map((user) => new User(this.session, user)); return users.map((user) => new User(this.session, user));
} }
async removeReactionEmoji(reaction: ReactionResolvable) { async removeReactionEmoji(reaction: ReactionResolvable): Promise<void> {
const r = typeof reaction === "string" ? reaction : `${reaction.name}:${reaction.id}`; const r = typeof reaction === "string" ? reaction : `${reaction.name}:${reaction.id}`;
await this.session.rest.runMethod<undefined>( await this.session.rest.runMethod<undefined>(
@ -358,7 +358,7 @@ export class Message implements Model {
); );
} }
async nukeReactions() { async nukeReactions(): Promise<void> {
await this.session.rest.runMethod<undefined>( await this.session.rest.runMethod<undefined>(
this.session.rest, this.session.rest,
"DELETE", "DELETE",
@ -366,7 +366,7 @@ export class Message implements Model {
); );
} }
async crosspost() { async crosspost(): Promise<Message> {
const message = await this.session.rest.runMethod<DiscordMessage>( const message = await this.session.rest.runMethod<DiscordMessage>(
this.session.rest, this.session.rest,
"POST", "POST",
@ -376,7 +376,7 @@ export class Message implements Model {
return new Message(this.session, message); return new Message(this.session, message);
} }
async fetch() { async fetch(): Promise<(Message | undefined)> {
const message = await this.session.rest.runMethod<DiscordMessage>( const message = await this.session.rest.runMethod<DiscordMessage>(
this.session.rest, this.session.rest,
"GET", "GET",

View File

@ -1,3 +1,4 @@
// deno-lint-ignore-file no-empty-interface
import type { Session } from "../Session.ts"; import type { Session } from "../Session.ts";
import type { DiscordMemberWithUser, DiscordMessageReactionAdd, DiscordReaction } from "../../discordeno/mod.ts"; import type { DiscordMemberWithUser, DiscordMessageReactionAdd, DiscordReaction } from "../../discordeno/mod.ts";
import Emoji from "./Emoji.ts"; import Emoji from "./Emoji.ts";

View File

@ -15,7 +15,7 @@ export class Permissions {
this.bitfield = Permissions.resolve(bitfield); this.bitfield = Permissions.resolve(bitfield);
} }
has(bit: PermissionResolvable) { has(bit: PermissionResolvable): boolean {
if (this.bitfield & BigInt(Permissions.Flags.ADMINISTRATOR)) { if (this.bitfield & BigInt(Permissions.Flags.ADMINISTRATOR)) {
return true; return true;
} }

View File

@ -35,15 +35,15 @@ export class Role implements Model {
managed: boolean; managed: boolean;
permissions: Permissions; permissions: Permissions;
get createdTimestamp() { get createdTimestamp(): number {
return Snowflake.snowflakeToTimestamp(this.id); return Snowflake.snowflakeToTimestamp(this.id);
} }
get createdAt() { get createdAt(): Date {
return new Date(this.createdTimestamp); return new Date(this.createdTimestamp);
} }
get hexColor() { get hexColor(): string {
return `#${this.color.toString(16).padStart(6, "0")}`; return `#${this.color.toString(16).padStart(6, "0")}`;
} }
@ -51,20 +51,20 @@ export class Role implements Model {
await Guild.prototype.deleteRole.call({ id: this.guildId, session: this.session }, this.id); await Guild.prototype.deleteRole.call({ id: this.guildId, session: this.session }, this.id);
} }
async edit(options: ModifyGuildRole) { async edit(options: ModifyGuildRole): Promise<Role> {
const role = await Guild.prototype.editRole.call({ id: this.guildId, session: this.session }, this.id, options); const role = await Guild.prototype.editRole.call({ id: this.guildId, session: this.session }, this.id, options);
return role; return role;
} }
async add(memberId: Snowflake, options: { reason?: string } = {}) { async add(memberId: Snowflake, options: { reason?: string } = {}): Promise<void> {
await Guild.prototype.addRole.call({ id: this.guildId, session: this.session }, memberId, this.id, options); await Guild.prototype.addRole.call({ id: this.guildId, session: this.session }, memberId, this.id, options);
} }
async remove(memberId: Snowflake, options: { reason?: string } = {}) { async remove(memberId: Snowflake, options: { reason?: string } = {}): Promise<void> {
await Guild.prototype.removeRole.call({ id: this.guildId, session: this.session }, memberId, this.id, options); await Guild.prototype.removeRole.call({ id: this.guildId, session: this.session }, memberId, this.id, options);
} }
toString() { toString(): string {
switch (this.id) { switch (this.id) {
case this.guildId: case this.guildId:
return "@everyone"; return "@everyone";

View File

@ -39,7 +39,7 @@ export class StageInstance implements Model {
discoverableDisabled: boolean; discoverableDisabled: boolean;
guildScheduledEventId: Snowflake; guildScheduledEventId: Snowflake;
async edit(options: { topic?: string; privacyLevel?: PrivacyLevels }) { async edit(options: { topic?: string; privacyLevel?: PrivacyLevels }): Promise<StageInstance> {
const stageInstance = await this.session.rest.runMethod<DiscordStageInstanceB>( const stageInstance = await this.session.rest.runMethod<DiscordStageInstanceB>(
this.session.rest, this.session.rest,
"PATCH", "PATCH",
@ -53,7 +53,7 @@ export class StageInstance implements Model {
return new StageInstance(this.session, stageInstance); return new StageInstance(this.session, stageInstance);
} }
async delete() { async delete(): Promise<void> {
await this.session.rest.runMethod<undefined>(this.session.rest, "DELETE", Routes.STAGE_INSTANCE(this.id)); await this.session.rest.runMethod<undefined>(this.session.rest, "DELETE", Routes.STAGE_INSTANCE(this.id));
} }
} }

View File

@ -21,11 +21,11 @@ export class ThreadMember implements Model {
flags: number; flags: number;
timestamp: number; timestamp: number;
get threadId() { get threadId(): Snowflake {
return this.id; return this.id;
} }
async quitThread(memberId: Snowflake = this.session.botId) { async quitThread(memberId: Snowflake = this.session.botId): Promise<void> {
await this.session.rest.runMethod<undefined>( await this.session.rest.runMethod<undefined>(
this.session.rest, this.session.rest,
"DELETE", "DELETE",
@ -33,7 +33,7 @@ export class ThreadMember implements Model {
); );
} }
async fetchMember(memberId: Snowflake = this.session.botId) { async fetchMember(memberId: Snowflake = this.session.botId): Promise<ThreadMember> {
const member = await this.session.rest.runMethod<DiscordThreadMember>( const member = await this.session.rest.runMethod<DiscordThreadMember>(
this.session.rest, this.session.rest,
"GET", "GET",

View File

@ -36,12 +36,12 @@ export class User implements Model {
banner?: string; banner?: string;
/** gets the user's username#discriminator */ /** gets the user's username#discriminator */
get tag() { get tag(): string {
return `${this.username}#${this.discriminator}}`; return `${this.username}#${this.discriminator}}`;
} }
/** gets the user's avatar */ /** gets the user's avatar */
avatarURL(options: { format?: ImageFormat; size?: ImageSize } = { size: 128 }) { avatarURL(options: { format?: ImageFormat; size?: ImageSize } = { size: 128 }): string {
let url: string; let url: string;
if (!this.avatarHash) { if (!this.avatarHash) {
@ -53,7 +53,7 @@ export class User implements Model {
return Util.formatImageURL(url, options.size, options.format); return Util.formatImageURL(url, options.size, options.format);
} }
toString() { toString(): string {
return `<@${this.id}>`; return `<@${this.id}>`;
} }
} }

View File

@ -47,7 +47,7 @@ export class Webhook implements Model {
guildId?: Snowflake; guildId?: Snowflake;
user?: User; user?: User;
async execute(options?: WebhookOptions & CreateMessage & { avatarUrl?: string; username?: string }) { async execute(options?: WebhookOptions & CreateMessage & { avatarUrl?: string; username?: string }): Promise<(Message | undefined)> {
if (!this.token) { if (!this.token) {
return; return;
} }
@ -57,12 +57,11 @@ export class Webhook implements Model {
embeds: options?.embeds, embeds: options?.embeds,
tts: options?.tts, tts: options?.tts,
allowed_mentions: options?.allowedMentions, allowed_mentions: options?.allowedMentions,
// @ts-ignore: TODO: component builder or something
components: options?.components, components: options?.components,
file: options?.files, file: options?.files,
}; };
const message = await this.session.rest.sendRequest<DiscordMessage>(this.session.rest, { const message = this.session.rest.sendRequest<DiscordMessage>(this.session.rest, {
url: Routes.WEBHOOK(this.id, this.token!, { url: Routes.WEBHOOK(this.id, this.token!, {
wait: options?.wait, wait: options?.wait,
threadId: options?.threadId, threadId: options?.threadId,
@ -76,10 +75,10 @@ export class Webhook implements Model {
}), }),
}); });
return (options?.wait ?? true) ? new Message(this.session, message) : undefined; return (options?.wait ?? true) ? new Message(this.session, await(message)) : undefined;
} }
async fetch() { async fetch(): Promise<Webhook> {
const message = await this.session.rest.runMethod<DiscordWebhook>( const message = await this.session.rest.runMethod<DiscordWebhook>(
this.session.rest, this.session.rest,
"GET", "GET",
@ -89,7 +88,7 @@ export class Webhook implements Model {
return new Webhook(this.session, message); return new Webhook(this.session, message);
} }
async fetchMessage(messageId: Snowflake) { async fetchMessage(messageId: Snowflake): Promise<Message | void> {
if (!this.token) { if (!this.token) {
return; return;
} }

View File

@ -25,7 +25,7 @@ export class WelcomeChannel implements Model {
emoji: Emoji; emoji: Emoji;
/** alias for WelcomeScreenChannel.channelId */ /** alias for WelcomeScreenChannel.channelId */
get id() { get id(): Snowflake {
return this.channelId; return this.channelId;
} }
} }

View File

@ -28,7 +28,7 @@ export class EmbedBuilder {
if (!this.#data.fields) this.#data.fields = []; if (!this.#data.fields) this.#data.fields = [];
} }
setAuthor(author: EmbedAuthor) { setAuthor(author: EmbedAuthor): EmbedBuilder {
this.#data.author = { this.#data.author = {
name: author.name, name: author.name,
icon_url: author.iconUrl, icon_url: author.iconUrl,
@ -38,22 +38,22 @@ export class EmbedBuilder {
return this; return this;
} }
setColor(color: number) { setColor(color: number): EmbedBuilder {
this.#data.color = color; this.#data.color = color;
return this; return this;
} }
setDescription(description: string) { setDescription(description: string): EmbedBuilder {
this.#data.description = description; this.#data.description = description;
return this; return this;
} }
addField(field: DiscordEmbedField) { addField(field: DiscordEmbedField): EmbedBuilder {
this.#data.fields!.push(field); this.#data.fields!.push(field);
return this; return this;
} }
setFooter(footer: EmbedFooter) { setFooter(footer: EmbedFooter): EmbedBuilder {
this.#data.footer = { this.#data.footer = {
text: footer.text, text: footer.text,
icon_url: footer.iconUrl, icon_url: footer.iconUrl,
@ -62,38 +62,38 @@ export class EmbedBuilder {
return this; return this;
} }
setImage(image: string) { setImage(image: string): EmbedBuilder {
this.#data.image = { url: image }; this.#data.image = { url: image };
return this; return this;
} }
setProvider(provider: DiscordEmbedProvider) { setProvider(provider: DiscordEmbedProvider): EmbedBuilder {
this.#data.provider = provider; this.#data.provider = provider;
return this; return this;
} }
setThumbnail(thumbnail: string) { setThumbnail(thumbnail: string): EmbedBuilder {
this.#data.thumbnail = { url: thumbnail }; this.#data.thumbnail = { url: thumbnail };
return this; return this;
} }
setTimestamp(timestamp: string | Date) { setTimestamp(timestamp: string | Date): EmbedBuilder {
this.#data.timestamp = timestamp instanceof Date ? timestamp.toISOString() : timestamp; this.#data.timestamp = timestamp instanceof Date ? timestamp.toISOString() : timestamp;
return this; return this;
} }
setTitle(title: string, url?: string) { setTitle(title: string, url?: string): EmbedBuilder {
this.#data.title = title; this.#data.title = title;
if (url) this.setUrl(url); if (url) this.setUrl(url);
return this; return this;
} }
setUrl(url: string) { setUrl(url: string): EmbedBuilder {
this.#data.url = url; this.#data.url = url;
return this; return this;
} }
setVideo(video: EmbedVideo) { setVideo(video: EmbedVideo): EmbedBuilder {
this.#data.video = { this.#data.video = {
height: video.height, height: video.height,
proxy_url: video.proxyUrl, proxy_url: video.proxyUrl,

View File

@ -8,38 +8,38 @@ export class InputTextBuilder {
#data: DiscordInputTextComponent; #data: DiscordInputTextComponent;
type: MessageComponentTypes.InputText; type: MessageComponentTypes.InputText;
setStyle(style: TextStyles) { setStyle(style: TextStyles): InputTextBuilder {
this.#data.style = style; this.#data.style = style;
return this; return this;
} }
setLabel(label: string) { setLabel(label: string): InputTextBuilder {
this.#data.label = label; this.#data.label = label;
return this; return this;
} }
setPlaceholder(placeholder: string) { setPlaceholder(placeholder: string): InputTextBuilder {
this.#data.placeholder = placeholder; this.#data.placeholder = placeholder;
return this; return this;
} }
setLength(max?: number, min?: number) { setLength(max?: number, min?: number): InputTextBuilder {
this.#data.max_length = max; this.#data.max_length = max;
this.#data.min_length = min; this.#data.min_length = min;
return this; return this;
} }
setCustomId(id: string) { setCustomId(id: string): InputTextBuilder {
this.#data.custom_id = id; this.#data.custom_id = id;
return this; return this;
} }
setValue(value: string) { setValue(value: string): InputTextBuilder {
this.#data.value = value; this.#data.value = value;
return this; return this;
} }
setRequired(required = true) { setRequired(required = true): InputTextBuilder {
this.#data.required = required; this.#data.required = required;
return this; return this;
} }

View File

@ -9,12 +9,12 @@ export class ActionRowBuilder<T extends ComponentBuilder> {
components: T[]; components: T[];
type: MessageComponentTypes.ActionRow; type: MessageComponentTypes.ActionRow;
addComponents(...components: T[]) { addComponents(...components: T[]): ActionRowBuilder<T> {
this.components.push(...components); this.components.push(...components);
return this; return this;
} }
setComponents(...components: T[]) { setComponents(...components: T[]): ActionRowBuilder<T> {
this.components.splice( this.components.splice(
0, 0,
this.components.length, this.components.length,

View File

@ -1,10 +1,10 @@
import type { ButtonStyles, DiscordButtonComponent, MessageComponentTypes } from "../../../../discordeno/mod.ts"; import { type ButtonStyles, type DiscordButtonComponent, MessageComponentTypes } from "../../../../discordeno/mod.ts";
import type { ComponentEmoji } from "../../../Util.ts"; import type { ComponentEmoji } from "../../../Util.ts";
export class ButtonBuilder { export class ButtonBuilder {
constructor() { constructor() {
this.#data = {} as DiscordButtonComponent; this.#data = {} as DiscordButtonComponent;
this.type = 2; this.type = MessageComponentTypes.Button;
} }
#data: DiscordButtonComponent; #data: DiscordButtonComponent;
type: MessageComponentTypes.Button; type: MessageComponentTypes.Button;
@ -13,27 +13,27 @@ export class ButtonBuilder {
return this; return this;
} }
setLabel(label: string) { setLabel(label: string): ButtonBuilder {
this.#data.label = label; this.#data.label = label;
return this; return this;
} }
setCustomId(id: string) { setCustomId(id: string): ButtonBuilder {
this.#data.custom_id = id; this.#data.custom_id = id;
return this; return this;
} }
setEmoji(emoji: ComponentEmoji) { setEmoji(emoji: ComponentEmoji): ButtonBuilder {
this.#data.emoji = emoji; this.#data.emoji = emoji;
return this; return this;
} }
setDisabled(disabled = true) { setDisabled(disabled = true): ButtonBuilder {
this.#data.disabled = disabled; this.#data.disabled = disabled;
return this; return this;
} }
setURL(url: string) { setURL(url: string): ButtonBuilder {
this.#data.url = url; this.#data.url = url;
return this; return this;
} }

View File

@ -1,38 +1,38 @@
import type { DiscordSelectMenuComponent, MessageComponentTypes } from "../../../../discordeno/mod.ts"; import { type DiscordSelectMenuComponent, MessageComponentTypes } from "../../../../discordeno/mod.ts";
import type { SelectMenuOptionBuilder } from "./SelectMenuOptionBuilder.ts"; import type { SelectMenuOptionBuilder } from "./SelectMenuOptionBuilder.ts";
export class SelectMenuBuilder { export class SelectMenuBuilder {
constructor() { constructor() {
this.#data = {} as DiscordSelectMenuComponent; this.#data = {} as DiscordSelectMenuComponent;
this.type = 3; this.type = MessageComponentTypes.SelectMenu;
this.options = []; this.options = [];
} }
#data: DiscordSelectMenuComponent; #data: DiscordSelectMenuComponent;
type: MessageComponentTypes.SelectMenu; type: MessageComponentTypes.SelectMenu;
options: SelectMenuOptionBuilder[]; options: SelectMenuOptionBuilder[];
setPlaceholder(placeholder: string) { setPlaceholder(placeholder: string): SelectMenuBuilder {
this.#data.placeholder = placeholder; this.#data.placeholder = placeholder;
return this; return this;
} }
setValues(max?: number, min?: number) { setValues(max?: number, min?: number): SelectMenuBuilder {
this.#data.max_values = max; this.#data.max_values = max;
this.#data.min_values = min; this.#data.min_values = min;
return this; return this;
} }
setDisabled(disabled = true) { setDisabled(disabled = true): SelectMenuBuilder {
this.#data.disabled = disabled; this.#data.disabled = disabled;
return this; return this;
} }
setCustomId(id: string) { setCustomId(id: string): SelectMenuBuilder {
this.#data.custom_id = id; this.#data.custom_id = id;
return this; return this;
} }
setOptions(...options: SelectMenuOptionBuilder[]) { setOptions(...options: SelectMenuOptionBuilder[]): SelectMenuBuilder {
this.options.splice( this.options.splice(
0, 0,
this.options.length, this.options.length,
@ -41,10 +41,11 @@ export class SelectMenuBuilder {
return this; return this;
} }
addOptions(...options: SelectMenuOptionBuilder[]) { addOptions(...options: SelectMenuOptionBuilder[]): SelectMenuBuilder {
this.options.push( this.options.push(
...options, ...options,
); );
return this;
} }
toJSON(): DiscordSelectMenuComponent { toJSON(): DiscordSelectMenuComponent {

View File

@ -7,32 +7,32 @@ export class SelectMenuOptionBuilder {
} }
#data: DiscordSelectOption; #data: DiscordSelectOption;
setLabel(label: string) { setLabel(label: string): SelectMenuOptionBuilder {
this.#data.label = label; this.#data.label = label;
return this; return this;
} }
setValue(value: string) { setValue(value: string): SelectMenuOptionBuilder {
this.#data.value = value; this.#data.value = value;
return this; return this;
} }
setDescription(description: string) { setDescription(description: string): SelectMenuOptionBuilder {
this.#data.description = description; this.#data.description = description;
return this; return this;
} }
setDefault(Default = true) { setDefault(Default = true): SelectMenuOptionBuilder {
this.#data.default = Default; this.#data.default = Default;
return this; return this;
} }
setEmoji(emoji: ComponentEmoji) { setEmoji(emoji: ComponentEmoji): SelectMenuOptionBuilder {
this.#data.emoji = emoji; this.#data.emoji = emoji;
return this; return this;
} }
toJSON() { toJSON(): DiscordSelectOption {
return { ...this.#data }; return { ...this.#data };
} }
} }

View File

@ -25,31 +25,31 @@ export abstract class ApplicationCommandBuilder implements CreateApplicationComm
this.dmPermission = dmPermission; this.dmPermission = dmPermission;
} }
public setType(type: ApplicationCommandTypes) { public setType(type: ApplicationCommandTypes): ApplicationCommandBuilder {
return (this.type = type), this; return (this.type = type), this;
} }
public setName(name: string) { public setName(name: string): ApplicationCommandBuilder {
return (this.name = name), this; return (this.name = name), this;
} }
public setDescription(description: string) { public setDescription(description: string): ApplicationCommandBuilder {
return (this.description = description), this; return (this.description = description), this;
} }
public setDefaultMemberPermission(perm: PermissionStrings[]) { public setDefaultMemberPermission(perm: PermissionStrings[]): ApplicationCommandBuilder {
return (this.defaultMemberPermissions = perm), this; return (this.defaultMemberPermissions = perm), this;
} }
public setNameLocalizations(l: Localization) { public setNameLocalizations(l: Localization): ApplicationCommandBuilder {
return (this.nameLocalizations = l), this; return (this.nameLocalizations = l), this;
} }
public setDescriptionLocalizations(l: Localization) { public setDescriptionLocalizations(l: Localization): ApplicationCommandBuilder {
return (this.descriptionLocalizations = l), this; return (this.descriptionLocalizations = l), this;
} }
public setDmPermission(perm: boolean) { public setDmPermission(perm: boolean): ApplicationCommandBuilder {
return (this.dmPermission = perm), this; return (this.dmPermission = perm), this;
} }
} }
@ -64,7 +64,7 @@ export class MessageApplicationCommandBuilder {
this.name = name; this.name = name;
} }
public setName(name: string) { public setName(name: string): MessageApplicationCommandBuilder {
return (this.name = name), this; return (this.name = name), this;
} }

View File

@ -5,12 +5,12 @@ export class ChoiceBuilder {
public name?: string; public name?: string;
public value?: string; public value?: string;
public setName(name: string) { public setName(name: string): ChoiceBuilder {
this.name = name; this.name = name;
return this; return this;
} }
public setValue(value: string) { public setValue(value: string): ChoiceBuilder {
this.value = value; this.value = value;
return this; return this;
} }
@ -36,19 +36,19 @@ export class OptionBuilder {
this.description = description; this.description = description;
} }
public setType(type: ApplicationCommandOptionTypes) { public setType(type: ApplicationCommandOptionTypes): OptionBuilder {
return (this.type = type), this; return (this.type = type), this;
} }
public setName(name: string) { public setName(name: string): OptionBuilder {
return (this.name = name), this; return (this.name = name), this;
} }
public setDescription(description: string) { public setDescription(description: string): OptionBuilder {
return (this.description = description), this; return (this.description = description), this;
} }
public setRequired(required: boolean) { public setRequired(required: boolean): OptionBuilder {
return (this.required = required), this; return (this.required = required), this;
} }
@ -86,15 +86,15 @@ export class OptionBuilderLimitedValues extends OptionBuilder {
this.description = description; this.description = description;
} }
public setMinValue(n: number) { public setMinValue(n: number): OptionBuilderLimitedValues {
return (this.minValue = n), this; return (this.minValue = n), this;
} }
public setMaxValue(n: number) { public setMaxValue(n: number): OptionBuilderLimitedValues {
return (this.maxValue = n), this; return (this.maxValue = n), this;
} }
public addChoice(fn: (choice: ChoiceBuilder) => ChoiceBuilder) { public addChoice(fn: (choice: ChoiceBuilder) => ChoiceBuilder): OptionBuilderLimitedValues {
const choice = fn(new ChoiceBuilder()); const choice = fn(new ChoiceBuilder());
this.choices ??= []; this.choices ??= [];
this.choices.push(choice); this.choices.push(choice);
@ -125,7 +125,7 @@ export class OptionBuilderString extends OptionBuilder {
this; this;
} }
public addChoice(fn: (choice: ChoiceBuilder) => ChoiceBuilder) { public addChoice(fn: (choice: ChoiceBuilder) => ChoiceBuilder): OptionBuilderString {
const choice = fn(new ChoiceBuilder()); const choice = fn(new ChoiceBuilder());
this.choices ??= []; this.choices ??= [];
this.choices.push(choice); this.choices.push(choice);
@ -154,7 +154,7 @@ export class OptionBuilderChannel extends OptionBuilder {
this; this;
} }
public addChannelTypes(...channels: ChannelTypes[]) { public addChannelTypes(...channels: ChannelTypes[]): OptionBuilderChannel {
this.channelTypes ??= []; this.channelTypes ??= [];
this.channelTypes.push(...channels); this.channelTypes.push(...channels);
return this; return this;
@ -183,75 +183,75 @@ export class OptionBased {
) )
& OptionBuilderLike[]; & OptionBuilderLike[];
public addOption(fn: (option: OptionBuilder) => OptionBuilder, type?: ApplicationCommandOptionTypes) { public addOption(fn: (option: OptionBuilder) => OptionBuilder, type?: ApplicationCommandOptionTypes): OptionBased {
const option = fn(new OptionBuilder(type)); const option = fn(new OptionBuilder(type));
this.options ??= []; this.options ??= [];
this.options.push(option); this.options.push(option);
return this; return this;
} }
public addNestedOption(fn: (option: OptionBuilder) => OptionBuilder) { public addNestedOption(fn: (option: OptionBuilder) => OptionBuilder): OptionBased {
const option = fn(new OptionBuilder(ApplicationCommandOptionTypes.SubCommand)); const option = fn(new OptionBuilder(ApplicationCommandOptionTypes.SubCommand));
this.options ??= []; this.options ??= [];
this.options.push(option); this.options.push(option);
return this; return this;
} }
public addStringOption(fn: (option: OptionBuilderString) => OptionBuilderString) { public addStringOption(fn: (option: OptionBuilderString) => OptionBuilderString): OptionBased {
const option = fn(new OptionBuilderString(ApplicationCommandOptionTypes.String)); const option = fn(new OptionBuilderString(ApplicationCommandOptionTypes.String));
this.options ??= []; this.options ??= [];
this.options.push(option); this.options.push(option);
return this; return this;
} }
public addIntegerOption(fn: (option: OptionBuilderLimitedValues) => OptionBuilderLimitedValues) { public addIntegerOption(fn: (option: OptionBuilderLimitedValues) => OptionBuilderLimitedValues): OptionBased {
const option = fn(new OptionBuilderLimitedValues(ApplicationCommandOptionTypes.Integer)); const option = fn(new OptionBuilderLimitedValues(ApplicationCommandOptionTypes.Integer));
this.options ??= []; this.options ??= [];
this.options.push(option); this.options.push(option);
return this; return this;
} }
public addNumberOption(fn: (option: OptionBuilderLimitedValues) => OptionBuilderLimitedValues) { public addNumberOption(fn: (option: OptionBuilderLimitedValues) => OptionBuilderLimitedValues): OptionBased {
const option = fn(new OptionBuilderLimitedValues(ApplicationCommandOptionTypes.Number)); const option = fn(new OptionBuilderLimitedValues(ApplicationCommandOptionTypes.Number));
this.options ??= []; this.options ??= [];
this.options.push(option); this.options.push(option);
return this; return this;
} }
public addBooleanOption(fn: (option: OptionBuilder) => OptionBuilder) { public addBooleanOption(fn: (option: OptionBuilder) => OptionBuilder): OptionBased {
return this.addOption(fn, ApplicationCommandOptionTypes.Boolean); return this.addOption(fn, ApplicationCommandOptionTypes.Boolean);
} }
public addSubCommand(fn: (option: OptionBuilderNested) => OptionBuilderNested) { public addSubCommand(fn: (option: OptionBuilderNested) => OptionBuilderNested): OptionBased {
const option = fn(new OptionBuilderNested(ApplicationCommandOptionTypes.SubCommand)); const option = fn(new OptionBuilderNested(ApplicationCommandOptionTypes.SubCommand));
this.options ??= []; this.options ??= [];
this.options.push(option); this.options.push(option);
return this; return this;
} }
public addSubCommandGroup(fn: (option: OptionBuilderNested) => OptionBuilderNested) { public addSubCommandGroup(fn: (option: OptionBuilderNested) => OptionBuilderNested): OptionBased {
const option = fn(new OptionBuilderNested(ApplicationCommandOptionTypes.SubCommandGroup)); const option = fn(new OptionBuilderNested(ApplicationCommandOptionTypes.SubCommandGroup));
this.options ??= []; this.options ??= [];
this.options.push(option); this.options.push(option);
return this; return this;
} }
public addUserOption(fn: (option: OptionBuilder) => OptionBuilder) { public addUserOption(fn: (option: OptionBuilder) => OptionBuilder): OptionBased {
return this.addOption(fn, ApplicationCommandOptionTypes.User); return this.addOption(fn, ApplicationCommandOptionTypes.User);
} }
public addChannelOption(fn: (option: OptionBuilderChannel) => OptionBuilderChannel) { public addChannelOption(fn: (option: OptionBuilderChannel) => OptionBuilderChannel): OptionBased {
const option = fn(new OptionBuilderChannel(ApplicationCommandOptionTypes.Channel)); const option = fn(new OptionBuilderChannel(ApplicationCommandOptionTypes.Channel));
this.options ??= []; this.options ??= [];
this.options.push(option); this.options.push(option);
return this; return this;
} }
public addRoleOption(fn: (option: OptionBuilder) => OptionBuilder) { public addRoleOption(fn: (option: OptionBuilder) => OptionBuilder): OptionBased {
return this.addOption(fn, ApplicationCommandOptionTypes.Role); return this.addOption(fn, ApplicationCommandOptionTypes.Role);
} }
public addMentionableOption(fn: (option: OptionBuilder) => OptionBuilder) { public addMentionableOption(fn: (option: OptionBuilder) => OptionBuilder): OptionBased {
return this.addOption(fn, ApplicationCommandOptionTypes.Mentionable); return this.addOption(fn, ApplicationCommandOptionTypes.Mentionable);
} }

View File

@ -145,7 +145,7 @@ export class TextChannel {
* Mixin * Mixin
*/ */
// deno-lint-ignore ban-types // deno-lint-ignore ban-types
static applyTo(klass: Function, ignore: Array<keyof TextChannel> = []) { static applyTo(klass: Function, ignore: Array<keyof TextChannel> = []): void {
const methods: Array<keyof TextChannel> = [ const methods: Array<keyof TextChannel> = [
"fetchPins", "fetchPins",
"createInvite", "createInvite",
@ -178,7 +178,7 @@ export class TextChannel {
return messages[0] ? messages.map((x: DiscordMessage) => new Message(this.session, x)) : []; return messages[0] ? messages.map((x: DiscordMessage) => new Message(this.session, x)) : [];
} }
async createInvite(options?: DiscordInviteOptions) { async createInvite(options?: DiscordInviteOptions): Promise<Invite> {
const invite = await this.session.rest.runMethod<DiscordInvite>( const invite = await this.session.rest.runMethod<DiscordInvite>(
this.session.rest, this.session.rest,
"POST", "POST",
@ -209,7 +209,7 @@ export class TextChannel {
return messages[0] ? messages.map((x) => new Message(this.session, x)) : []; return messages[0] ? messages.map((x) => new Message(this.session, x)) : [];
} }
async sendTyping() { async sendTyping(): Promise<void> {
await this.session.rest.runMethod<undefined>( await this.session.rest.runMethod<undefined>(
this.session.rest, this.session.rest,
"POST", "POST",
@ -217,22 +217,26 @@ export class TextChannel {
); );
} }
async pinMessage(messageId: Snowflake) { async pinMessage(messageId: Snowflake): Promise<void> {
await Message.prototype.pin.call({ id: messageId, channelId: this.id, session: this.session }); await Message.prototype.pin.call({ id: messageId, channelId: this.id, session: this.session });
} }
async unpinMessage(messageId: Snowflake) { async unpinMessage(messageId: Snowflake): Promise<void> {
await Message.prototype.unpin.call({ id: messageId, channelId: this.id, session: this.session }); await Message.prototype.unpin.call({ id: messageId, channelId: this.id, session: this.session });
} }
async addReaction(messageId: Snowflake, reaction: ReactionResolvable) { async addReaction(messageId: Snowflake, reaction: ReactionResolvable): Promise<void> {
await Message.prototype.addReaction.call( await Message.prototype.addReaction.call(
{ channelId: this.id, id: messageId, session: this.session }, { channelId: this.id, id: messageId, session: this.session },
reaction, reaction,
); );
} }
async removeReaction(messageId: Snowflake, reaction: ReactionResolvable, options?: { userId: Snowflake }) { async removeReaction(
messageId: Snowflake,
reaction: ReactionResolvable,
options?: { userId: Snowflake },
): Promise<void> {
await Message.prototype.removeReaction.call( await Message.prototype.removeReaction.call(
{ channelId: this.id, id: messageId, session: this.session }, { channelId: this.id, id: messageId, session: this.session },
reaction, reaction,
@ -240,18 +244,22 @@ export class TextChannel {
); );
} }
async removeReactionEmoji(messageId: Snowflake, reaction: ReactionResolvable) { async removeReactionEmoji(messageId: Snowflake, reaction: ReactionResolvable): Promise<void> {
await Message.prototype.removeReactionEmoji.call( await Message.prototype.removeReactionEmoji.call(
{ channelId: this.id, id: messageId, session: this.session }, { channelId: this.id, id: messageId, session: this.session },
reaction, reaction,
); );
} }
async nukeReactions(messageId: Snowflake) { async nukeReactions(messageId: Snowflake): Promise<void> {
await Message.prototype.nukeReactions.call({ channelId: this.id, id: messageId }); await Message.prototype.nukeReactions.call({ channelId: this.id, id: messageId });
} }
async fetchReactions(messageId: Snowflake, reaction: ReactionResolvable, options?: Routes.GetReactions) { async fetchReactions(
messageId: Snowflake,
reaction: ReactionResolvable,
options?: Routes.GetReactions,
): Promise<User[]> {
const users = await Message.prototype.fetchReactions.call( const users = await Message.prototype.fetchReactions.call(
{ channelId: this.id, id: messageId, session: this.session }, { channelId: this.id, id: messageId, session: this.session },
reaction, reaction,
@ -261,15 +269,15 @@ export class TextChannel {
return users; return users;
} }
sendMessage(options: CreateMessage) { sendMessage(options: CreateMessage): Promise<Message> {
return Message.prototype.reply.call({ channelId: this.id, session: this.session }, options); return Message.prototype.reply.call({ channelId: this.id, session: this.session }, options);
} }
editMessage(messageId: Snowflake, options: EditMessage) { editMessage(messageId: Snowflake, options: EditMessage): Promise<Message> {
return Message.prototype.edit.call({ channelId: this.id, id: messageId, session: this.session }, options); return Message.prototype.edit.call({ channelId: this.id, id: messageId, session: this.session }, options);
} }
async createWebhook(options: CreateWebhook) { async createWebhook(options: CreateWebhook): Promise<Webhook> {
const webhook = await this.session.rest.runMethod<DiscordWebhook>( const webhook = await this.session.rest.runMethod<DiscordWebhook>(
this.session.rest, this.session.rest,
"POST", "POST",
@ -343,6 +351,14 @@ export interface ThreadCreateOptions {
rateLimitPerUser?: number; rateLimitPerUser?: number;
messageId: Snowflake; messageId: Snowflake;
} }
/**
* @link https://discord.com/developers/docs/resources/channel#list-public-archived-threads-response-body
*/
export interface ReturnThreadsArchive {
threads: Record<Snowflake, ThreadChannel>;
members: Record<Snowflake, ThreadMember>;
hasMore: boolean;
}
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) {
@ -403,7 +419,7 @@ export class GuildChannel extends BaseChannel implements Model {
async getArchivedThreads( async getArchivedThreads(
options: Routes.ListArchivedThreads & { type: "public" | "private" | "privateJoinedThreads" }, options: Routes.ListArchivedThreads & { type: "public" | "private" | "privateJoinedThreads" },
) { ): Promise<ReturnThreadsArchive> {
let func: (channelId: Snowflake, options: Routes.ListArchivedThreads) => string; let func: (channelId: Snowflake, options: Routes.ListArchivedThreads) => string;
switch (options.type) { switch (options.type) {
@ -487,7 +503,7 @@ export abstract class BaseVoiceChannel extends GuildChannel {
/** /**
* This function was gathered from Discordeno it may not work * This function was gathered from Discordeno it may not work
*/ */
async connect(options?: UpdateVoiceState) { async connect(options?: UpdateVoiceState): Promise<void> {
const shardId = calculateShardId(this.session.gateway, BigInt(super.guildId)); const shardId = calculateShardId(this.session.gateway, BigInt(super.guildId));
const shard = this.session.gateway.manager.shards.get(shardId); const shard = this.session.gateway.manager.shards.get(shardId);
@ -522,7 +538,7 @@ export class DMChannel extends BaseChannel implements Model {
user: User; user: User;
lastMessageId?: Snowflake; lastMessageId?: Snowflake;
async close() { async close(): Promise<DMChannel> {
const channel = await this.session.rest.runMethod<DiscordChannel>( const channel = await this.session.rest.runMethod<DiscordChannel>(
this.session.rest, this.session.rest,
"DELETE", "DELETE",
@ -613,7 +629,7 @@ export class ThreadChannel extends GuildChannel implements Model {
member?: ThreadMember; member?: ThreadMember;
ownerId?: Snowflake; ownerId?: Snowflake;
async joinThread() { async joinThread(): Promise<void> {
await this.session.rest.runMethod<undefined>( await this.session.rest.runMethod<undefined>(
this.session.rest, this.session.rest,
"PUT", "PUT",
@ -621,7 +637,7 @@ export class ThreadChannel extends GuildChannel implements Model {
); );
} }
async addToThread(guildMemberId: Snowflake) { async addToThread(guildMemberId: Snowflake): Promise<void> {
await this.session.rest.runMethod<undefined>( await this.session.rest.runMethod<undefined>(
this.session.rest, this.session.rest,
"PUT", "PUT",
@ -629,7 +645,7 @@ export class ThreadChannel extends GuildChannel implements Model {
); );
} }
async leaveToThread(guildMemberId: Snowflake) { async leaveToThread(guildMemberId: Snowflake): Promise<void> {
await this.session.rest.runMethod<undefined>( await this.session.rest.runMethod<undefined>(
this.session.rest, this.session.rest,
"DELETE", "DELETE",
@ -637,11 +653,11 @@ export class ThreadChannel extends GuildChannel implements Model {
); );
} }
removeMember(memberId: Snowflake = this.session.botId) { removeMember(memberId: Snowflake = this.session.botId): Promise<void> {
return ThreadMember.prototype.quitThread.call({ id: this.id, session: this.session }, memberId); return ThreadMember.prototype.quitThread.call({ id: this.id, session: this.session }, memberId);
} }
fetchMember(memberId: Snowflake = this.session.botId) { fetchMember(memberId: Snowflake = this.session.botId): Promise<ThreadMember> {
return ThreadMember.prototype.fetchMember.call({ id: this.id, session: this.session }, memberId); return ThreadMember.prototype.fetchMember.call({ id: this.id, session: this.session }, memberId);
} }

View File

@ -1,11 +1,11 @@
import type { Session } from "../../Session.ts"; import type { Session } from "../../Session.ts";
import type { DiscordComponent } from "../../../discordeno/mod.ts"; import type { DiscordInputTextComponent } from "../../../discordeno/mod.ts";
import type { TextInputComponent } from "./Component.ts"; import type { TextInputComponent } from "./Component.ts";
import { MessageComponentTypes, TextStyles } from "../../../discordeno/mod.ts"; import { MessageComponentTypes, TextStyles } from "../../../discordeno/mod.ts";
import BaseComponent from "./Component.ts"; import BaseComponent from "./Component.ts";
export class TextInput extends BaseComponent implements TextInputComponent { export class TextInput extends BaseComponent implements TextInputComponent {
constructor(session: Session, data: DiscordComponent) { constructor(session: Session, data: DiscordInputTextComponent) {
super(data.type); super(data.type);
this.session = session; this.session = session;
@ -17,11 +17,10 @@ export class TextInput extends BaseComponent implements TextInputComponent {
this.placeholder = data.placeholder; this.placeholder = data.placeholder;
this.value = data.value; this.value = data.value;
// @ts-ignore: vendor bug
this.minLength = data.min_length; this.minLength = data.min_length;
// @ts-ignore: vendor bug
this.maxLength = data.max_length; this.maxLength = data.max_length;
} }
readonly session: Session; readonly session: Session;

View File

@ -23,7 +23,7 @@ import { Snowflake } from "../Snowflake.ts";
import Util from "../Util.ts"; import Util from "../Util.ts";
import * as Routes from "../Routes.ts"; import * as Routes from "../Routes.ts";
import WelcomeScreen from "./WelcomeScreen.ts"; import WelcomeScreen from "./WelcomeScreen.ts";
import { GuildChannel, ThreadChannel } from "./channels.ts"; import { GuildChannel, ThreadChannel, ReturnThreadsArchive } from "./channels.ts";
import ThreadMember from "./ThreadMember.ts"; import ThreadMember from "./ThreadMember.ts";
import Member from "./Member.ts"; import Member from "./Member.ts";
import Role from "./Role.ts"; import Role from "./Role.ts";
@ -53,23 +53,23 @@ export abstract class BaseGuild implements Model {
iconHash?: bigint; iconHash?: bigint;
features: GuildFeatures[]; features: GuildFeatures[];
get createdTimestamp() { get createdTimestamp(): number {
return Snowflake.snowflakeToTimestamp(this.id); return Snowflake.snowflakeToTimestamp(this.id);
} }
get createdAt() { get createdAt(): Date {
return new Date(this.createdTimestamp); return new Date(this.createdTimestamp);
} }
get partnered() { get partnered(): boolean {
return this.features.includes(GuildFeatures.Partnered); return this.features.includes(GuildFeatures.Partnered);
} }
get verified() { get verified(): boolean {
return this.features.includes(GuildFeatures.Verified); return this.features.includes(GuildFeatures.Verified);
} }
iconURL(options: { size?: ImageSize; format?: ImageFormat } = { size: 128 }) { iconURL(options: { size?: ImageSize; format?: ImageFormat } = { size: 128 }): string | void {
if (this.iconHash) { if (this.iconHash) {
return Util.formatImageURL( return Util.formatImageURL(
Routes.GUILD_ICON(this.id, Util.iconBigintToHash(this.iconHash)), Routes.GUILD_ICON(this.id, Util.iconBigintToHash(this.iconHash)),
@ -79,7 +79,7 @@ export abstract class BaseGuild implements Model {
} }
} }
toString() { toString(): string {
return this.name; return this.name;
} }
} }
@ -109,7 +109,7 @@ export class AnonymousGuild extends BaseGuild implements Model {
description?: string; description?: string;
premiumSubscriptionCount?: number; premiumSubscriptionCount?: number;
splashURL(options: { size?: ImageSize; format?: ImageFormat } = { size: 128 }) { splashURL(options: { size?: ImageSize; format?: ImageFormat } = { size: 128 }): string | void {
if (this.splashHash) { if (this.splashHash) {
return Util.formatImageURL( return Util.formatImageURL(
Routes.GUILD_SPLASH(this.id, Util.iconBigintToHash(this.splashHash)), Routes.GUILD_SPLASH(this.id, Util.iconBigintToHash(this.splashHash)),
@ -119,7 +119,7 @@ export class AnonymousGuild extends BaseGuild implements Model {
} }
} }
bannerURL(options: { size?: ImageSize; format?: ImageFormat } = { size: 128 }) { bannerURL(options: { size?: ImageSize; format?: ImageFormat } = { size: 128 }): string | void {
if (this.bannerHash) { if (this.bannerHash) {
return Util.formatImageURL( return Util.formatImageURL(
Routes.GUILD_BANNER(this.id, Util.iconBigintToHash(this.bannerHash)), Routes.GUILD_BANNER(this.id, Util.iconBigintToHash(this.bannerHash)),
@ -354,7 +354,7 @@ export class Guild extends BaseGuild implements Model {
/** /**
* 'null' would reset the nickname * 'null' would reset the nickname
*/ */
async editBotNickname(options: { nick: string | null; reason?: string }) { async editBotNickname(options: { nick: string | null; reason?: string }): Promise<(string | undefined)> {
const result = await this.session.rest.runMethod<{ nick?: string } | undefined>( const result = await this.session.rest.runMethod<{ nick?: string } | undefined>(
this.session.rest, this.session.rest,
"PATCH", "PATCH",
@ -448,7 +448,7 @@ export class Guild extends BaseGuild implements Model {
return new Role(this.session, role, this.id); return new Role(this.session, role, this.id);
} }
async addRole(memberId: Snowflake, roleId: Snowflake, { reason }: { reason?: string } = {}) { async addRole(memberId: Snowflake, roleId: Snowflake, { reason }: { reason?: string } = {}): Promise<void> {
await this.session.rest.runMethod<undefined>( await this.session.rest.runMethod<undefined>(
this.session.rest, this.session.rest,
"PUT", "PUT",
@ -457,7 +457,7 @@ export class Guild extends BaseGuild implements Model {
); );
} }
async removeRole(memberId: Snowflake, roleId: Snowflake, { reason }: { reason?: string } = {}) { async removeRole(memberId: Snowflake, roleId: Snowflake, { reason }: { reason?: string } = {}): Promise<void> {
await this.session.rest.runMethod<undefined>( await this.session.rest.runMethod<undefined>(
this.session.rest, this.session.rest,
"DELETE", "DELETE",
@ -469,7 +469,7 @@ export class Guild extends BaseGuild implements Model {
/** /**
* Returns the roles moved * Returns the roles moved
*/ */
async moveRoles(options: ModifyRolePositions[]) { async moveRoles(options: ModifyRolePositions[]): Promise<Role[]> {
const roles = await this.session.rest.runMethod<DiscordRole[]>( const roles = await this.session.rest.runMethod<DiscordRole[]>(
this.session.rest, this.session.rest,
"PATCH", "PATCH",
@ -512,7 +512,7 @@ export class Guild extends BaseGuild implements Model {
/** /**
* Bans the member * Bans the member
*/ */
async banMember(memberId: Snowflake, options: CreateGuildBan) { async banMember(memberId: Snowflake, options: CreateGuildBan): Promise<void> {
await this.session.rest.runMethod<undefined>( await this.session.rest.runMethod<undefined>(
this.session.rest, this.session.rest,
"PUT", "PUT",
@ -529,7 +529,7 @@ export class Guild extends BaseGuild implements Model {
/** /**
* Kicks the member * Kicks the member
*/ */
async kickMember(memberId: Snowflake, { reason }: { reason?: string }) { async kickMember(memberId: Snowflake, { reason }: { reason?: string }): Promise<void> {
await this.session.rest.runMethod<undefined>( await this.session.rest.runMethod<undefined>(
this.session.rest, this.session.rest,
"DELETE", "DELETE",
@ -541,7 +541,7 @@ export class Guild extends BaseGuild implements Model {
/* /*
* Unbans the member * Unbans the member
* */ * */
async unbanMember(memberId: Snowflake) { async unbanMember(memberId: Snowflake): Promise<void> {
await this.session.rest.runMethod<undefined>( await this.session.rest.runMethod<undefined>(
this.session.rest, this.session.rest,
"DELETE", "DELETE",
@ -549,7 +549,7 @@ export class Guild extends BaseGuild implements Model {
); );
} }
async editMember(memberId: Snowflake, options: ModifyGuildMember) { async editMember(memberId: Snowflake, options: ModifyGuildMember): Promise<Member> {
const member = await this.session.rest.runMethod<DiscordMemberWithUser>( const member = await this.session.rest.runMethod<DiscordMemberWithUser>(
this.session.rest, this.session.rest,
"PATCH", "PATCH",
@ -594,7 +594,7 @@ export class Guild extends BaseGuild implements Model {
return result.pruned; return result.pruned;
} }
async getActiveThreads() { async getActiveThreads(): Promise<Omit<ReturnThreadsArchive, 'hasMore'>> {
const { threads, members } = await this.session.rest.runMethod<DiscordListActiveThreads>( const { threads, members } = await this.session.rest.runMethod<DiscordListActiveThreads>(
this.session.rest, this.session.rest,
"GET", "GET",
@ -604,23 +604,17 @@ export class Guild extends BaseGuild implements Model {
return { return {
threads: Object.fromEntries( threads: Object.fromEntries(
threads.map((thread) => [thread.id, new ThreadChannel(this.session, thread, this.id)]), threads.map((thread) => [thread.id, new ThreadChannel(this.session, thread, this.id)]),
) as Record<Snowflake, ThreadChannel>, ),
members: Object.fromEntries( members: Object.fromEntries(
members.map((threadMember) => [threadMember.id, new ThreadMember(this.session, threadMember)]), members.map((threadMember) => [threadMember.id, new ThreadMember(this.session, threadMember)]),
) as Record<Snowflake, ThreadMember>, ),
}; };
} }
/** *
* Makes the bot leave the guild
*/
async leave() {
}
/** * /** *
* Deletes a guild * Deletes a guild
*/ */
async delete() { async delete(): Promise<void> {
await this.session.rest.runMethod<undefined>( await this.session.rest.runMethod<undefined>(
this.session.rest, this.session.rest,
"DELETE", "DELETE",
@ -633,7 +627,7 @@ export class Guild extends BaseGuild implements Model {
* This was modified from discord.js to make it compatible * This was modified from discord.js to make it compatible
* precondition: Bot should be in less than 10 servers * precondition: Bot should be in less than 10 servers
*/ */
static async create(session: Session, options: GuildCreateOptions) { static async create(session: Session, options: GuildCreateOptions): Promise<Guild> {
const guild = await session.rest.runMethod<DiscordGuild>(session.rest, "POST", Routes.GUILDS(), { const guild = await session.rest.runMethod<DiscordGuild>(session.rest, "POST", Routes.GUILDS(), {
name: options.name, name: options.name,
afk_channel_id: options.afkChannelId, afk_channel_id: options.afkChannelId,
@ -675,7 +669,7 @@ export class Guild extends BaseGuild implements Model {
/** /**
* Edits a guild and returns its data * Edits a guild and returns its data
*/ */
async edit(session: Session, options: GuildEditOptions) { async edit(session: Session, options: GuildEditOptions): Promise<Guild> {
const guild = await session.rest.runMethod<DiscordGuild>(session.rest, "PATCH", Routes.GUILDS(), { const guild = await session.rest.runMethod<DiscordGuild>(session.rest, "PATCH", Routes.GUILDS(), {
name: options.name, name: options.name,
afk_channel_id: options.afkChannelId, afk_channel_id: options.afkChannelId,

View File

@ -23,7 +23,7 @@ export class AutoCompleteInteraction extends BaseInteraction implements Model {
commandType: ApplicationCommandTypes; commandType: ApplicationCommandTypes;
commandGuildId?: Snowflake; commandGuildId?: Snowflake;
async respond(choices: ApplicationCommandOptionChoice[]) { async respond(choices: ApplicationCommandOptionChoice[]): Promise<void> {
await this.session.rest.runMethod<undefined>( await this.session.rest.runMethod<undefined>(
this.session.rest, this.session.rest,
"POST", "POST",

View File

@ -51,11 +51,11 @@ export abstract class BaseInteraction implements Model {
readonly version: 1; readonly version: 1;
get createdTimestamp() { get createdTimestamp(): number {
return Snowflake.snowflakeToTimestamp(this.id); return Snowflake.snowflakeToTimestamp(this.id);
} }
get createdAt() { get createdAt(): Date {
return new Date(this.createdTimestamp); return new Date(this.createdTimestamp);
} }

View File

@ -6,6 +6,7 @@ import type {
DiscordInteraction, DiscordInteraction,
DiscordMemberWithUser, DiscordMemberWithUser,
InteractionTypes, InteractionTypes,
DiscordMessageComponents,
} from "../../../discordeno/mod.ts"; } from "../../../discordeno/mod.ts";
import type { CreateMessage } from "../Message.ts"; import type { CreateMessage } from "../Message.ts";
import type { MessageFlags } from "../../Util.ts"; import type { MessageFlags } from "../../Util.ts";
@ -35,7 +36,7 @@ export interface InteractionApplicationCommandCallbackData
extends Pick<CreateMessage, "allowedMentions" | "content" | "embeds" | "files"> { extends Pick<CreateMessage, "allowedMentions" | "content" | "embeds" | "files"> {
customId?: string; customId?: string;
title?: string; title?: string;
// components?: MessageComponents; components?: DiscordMessageComponents;
flags?: MessageFlags; flags?: MessageFlags;
choices?: ApplicationCommandOptionChoice[]; choices?: ApplicationCommandOptionChoice[];
} }

View File

@ -85,8 +85,8 @@ export class CommandInteractionOptionResolver {
type: ApplicationCommandOptionTypes, type: ApplicationCommandOptionTypes,
properties: Array<keyof CommandInteractionOption>, properties: Array<keyof CommandInteractionOption>,
required: boolean, required: boolean,
) { ): CommandInteractionOption | void {
const option = this.get(name, required); const option: (CommandInteractionOption | undefined) = this.get(name, required);
if (!option) { if (!option) {
return; return;
@ -106,7 +106,7 @@ export class CommandInteractionOptionResolver {
get(name: string | number, required: true): CommandInteractionOption; get(name: string | number, required: true): CommandInteractionOption;
get(name: string | number, required: boolean): CommandInteractionOption | undefined; get(name: string | number, required: boolean): CommandInteractionOption | undefined;
get(name: string | number, required?: boolean) { get(name: string | number, required?: boolean) {
const option = this.hoistedOptions.find((o) => const option: (CommandInteractionOption | undefined) = this.hoistedOptions.find((o) =>
typeof name === "number" ? o.name === name.toString() : o.name === name typeof name === "number" ? o.name === name.toString() : o.name === name
); );
@ -125,7 +125,7 @@ export class CommandInteractionOptionResolver {
getString(name: string | number, required: true): string; getString(name: string | number, required: true): string;
getString(name: string | number, required?: boolean): string | undefined; getString(name: string | number, required?: boolean): string | undefined;
getString(name: string | number, required = false) { getString(name: string | number, required = false) {
const option = this.getTypedOption(name, ApplicationCommandOptionTypes.String, ["Otherwise"], required); const option: (CommandInteractionOption | void) = this.getTypedOption(name, ApplicationCommandOptionTypes.String, ["Otherwise"], required);
return option?.Otherwise ?? undefined; return option?.Otherwise ?? undefined;
} }
@ -134,7 +134,7 @@ export class CommandInteractionOptionResolver {
getNumber(name: string | number, required: true): number; getNumber(name: string | number, required: true): number;
getNumber(name: string | number, required?: boolean): number | undefined; getNumber(name: string | number, required?: boolean): number | undefined;
getNumber(name: string | number, required = false) { getNumber(name: string | number, required = false) {
const option = this.getTypedOption(name, ApplicationCommandOptionTypes.Number, ["Otherwise"], required); const option: (CommandInteractionOption | void) = this.getTypedOption(name, ApplicationCommandOptionTypes.Number, ["Otherwise"], required);
return option?.Otherwise ?? undefined; return option?.Otherwise ?? undefined;
} }
@ -143,7 +143,7 @@ export class CommandInteractionOptionResolver {
getInteger(name: string | number, required: true): number; getInteger(name: string | number, required: true): number;
getInteger(name: string | number, required?: boolean): number | undefined; getInteger(name: string | number, required?: boolean): number | undefined;
getInteger(name: string | number, required = false) { getInteger(name: string | number, required = false) {
const option = this.getTypedOption(name, ApplicationCommandOptionTypes.Integer, ["Otherwise"], required); const option: (CommandInteractionOption | void) = this.getTypedOption(name, ApplicationCommandOptionTypes.Integer, ["Otherwise"], required);
return option?.Otherwise ?? undefined; return option?.Otherwise ?? undefined;
} }
@ -152,7 +152,7 @@ export class CommandInteractionOptionResolver {
getBoolean(name: string | number, required: true): boolean; getBoolean(name: string | number, required: true): boolean;
getBoolean(name: string | number, required?: boolean): boolean | undefined; getBoolean(name: string | number, required?: boolean): boolean | undefined;
getBoolean(name: string | number, required = false) { getBoolean(name: string | number, required = false) {
const option = this.getTypedOption(name, ApplicationCommandOptionTypes.Boolean, ["Otherwise"], required); const option: (CommandInteractionOption | void) = this.getTypedOption(name, ApplicationCommandOptionTypes.Boolean, ["Otherwise"], required);
return option?.Otherwise ?? undefined; return option?.Otherwise ?? undefined;
} }
@ -161,7 +161,7 @@ export class CommandInteractionOptionResolver {
getUser(name: string | number, required: true): bigint; getUser(name: string | number, required: true): bigint;
getUser(name: string | number, required?: boolean): bigint | undefined; getUser(name: string | number, required?: boolean): bigint | undefined;
getUser(name: string | number, required = false) { getUser(name: string | number, required = false) {
const option = this.getTypedOption(name, ApplicationCommandOptionTypes.User, ["Otherwise"], required); const option: (CommandInteractionOption | void) = this.getTypedOption(name, ApplicationCommandOptionTypes.User, ["Otherwise"], required);
return option?.Otherwise ?? undefined; return option?.Otherwise ?? undefined;
} }
@ -170,7 +170,7 @@ export class CommandInteractionOptionResolver {
getChannel(name: string | number, required: true): bigint; getChannel(name: string | number, required: true): bigint;
getChannel(name: string | number, required?: boolean): bigint | undefined; getChannel(name: string | number, required?: boolean): bigint | undefined;
getChannel(name: string | number, required = false) { getChannel(name: string | number, required = false) {
const option = this.getTypedOption(name, ApplicationCommandOptionTypes.Channel, ["Otherwise"], required); const option: (CommandInteractionOption | void) = this.getTypedOption(name, ApplicationCommandOptionTypes.Channel, ["Otherwise"], required);
return option?.Otherwise ?? undefined; return option?.Otherwise ?? undefined;
} }
@ -179,7 +179,7 @@ export class CommandInteractionOptionResolver {
getMentionable(name: string | number, required: true): string; getMentionable(name: string | number, required: true): string;
getMentionable(name: string | number, required?: boolean): string | undefined; getMentionable(name: string | number, required?: boolean): string | undefined;
getMentionable(name: string | number, required = false) { getMentionable(name: string | number, required = false) {
const option = this.getTypedOption(name, ApplicationCommandOptionTypes.Mentionable, ["Otherwise"], required); const option: (CommandInteractionOption | void) = this.getTypedOption(name, ApplicationCommandOptionTypes.Mentionable, ["Otherwise"], required);
return option?.Otherwise ?? undefined; return option?.Otherwise ?? undefined;
} }
@ -188,7 +188,7 @@ export class CommandInteractionOptionResolver {
getRole(name: string | number, required: true): bigint; getRole(name: string | number, required: true): bigint;
getRole(name: string | number, required?: boolean): bigint | undefined; getRole(name: string | number, required?: boolean): bigint | undefined;
getRole(name: string | number, required = false) { getRole(name: string | number, required = false) {
const option = this.getTypedOption(name, ApplicationCommandOptionTypes.Role, ["Otherwise"], required); const option: (CommandInteractionOption | void) = this.getTypedOption(name, ApplicationCommandOptionTypes.Role, ["Otherwise"], required);
return option?.Otherwise ?? undefined; return option?.Otherwise ?? undefined;
} }
@ -197,14 +197,14 @@ export class CommandInteractionOptionResolver {
getAttachment(name: string | number, required: true): string; getAttachment(name: string | number, required: true): string;
getAttachment(name: string | number, required?: boolean): string | undefined; getAttachment(name: string | number, required?: boolean): string | undefined;
getAttachment(name: string | number, required = false) { getAttachment(name: string | number, required = false) {
const option = this.getTypedOption(name, ApplicationCommandOptionTypes.Attachment, ["Otherwise"], required); const option: (CommandInteractionOption | void) = this.getTypedOption(name, ApplicationCommandOptionTypes.Attachment, ["Otherwise"], required);
return option?.Otherwise ?? undefined; return option?.Otherwise ?? undefined;
} }
/** searches for the focused option */ /** searches for the focused option */
getFocused(full = false) { getFocused(full = false): string | number | bigint | boolean | undefined | CommandInteractionOption {
const focusedOption = this.hoistedOptions.find((option) => option.focused); const focusedOption: (CommandInteractionOption | void) = this.hoistedOptions.find((option) => option.focused);
if (!focusedOption) { if (!focusedOption) {
throw new TypeError("No option found"); throw new TypeError("No option found");
@ -213,7 +213,7 @@ export class CommandInteractionOptionResolver {
return full ? focusedOption : focusedOption.Otherwise; return full ? focusedOption : focusedOption.Otherwise;
} }
getSubCommand(required = true) { getSubCommand(required = true): (string | CommandInteractionOption[] | undefined)[] {
if (required && !this.#subcommand) { if (required && !this.#subcommand) {
throw new TypeError("Option marked as required was undefined"); throw new TypeError("Option marked as required was undefined");
} }
@ -221,7 +221,7 @@ export class CommandInteractionOptionResolver {
return [this.#subcommand, this.hoistedOptions]; return [this.#subcommand, this.hoistedOptions];
} }
getSubCommandGroup(required = false) { getSubCommandGroup(required = false): (string | CommandInteractionOption[] | undefined)[] {
if (required && !this.#group) { if (required && !this.#group) {
throw new TypeError("Option marked as required was undefined"); throw new TypeError("Option marked as required was undefined");
} }

View File

@ -27,23 +27,24 @@ export class ComponentInteraction extends BaseInteraction implements Model {
message: Message; message: Message;
responded = false; responded = false;
isButton() { //TODO: create interface/class for components types
isButton(): boolean {
return this.componentType === MessageComponentTypes.Button; return this.componentType === MessageComponentTypes.Button;
} }
isActionRow() { isActionRow(): boolean {
return this.componentType === MessageComponentTypes.ActionRow; return this.componentType === MessageComponentTypes.ActionRow;
} }
isTextInput() { isTextInput(): boolean {
return this.componentType === MessageComponentTypes.InputText; return this.componentType === MessageComponentTypes.InputText;
} }
isSelectMenu() { isSelectMenu(): boolean {
return this.componentType === MessageComponentTypes.SelectMenu; return this.componentType === MessageComponentTypes.SelectMenu;
} }
sendFollowUp(options: InteractionApplicationCommandCallbackData) { sendFollowUp(options: InteractionApplicationCommandCallbackData): Promise<Message> {
return CommandInteraction.prototype.sendFollowUp.call(this, options); return CommandInteraction.prototype.sendFollowUp.call(this, options);
} }

View File

@ -22,7 +22,7 @@ export class PingInteraction extends BaseInteraction implements Model {
commandType: ApplicationCommandTypes; commandType: ApplicationCommandTypes;
commandGuildId?: Snowflake; commandGuildId?: Snowflake;
async pong() { async pong(): Promise<void> {
await this.session.rest.runMethod<undefined>( await this.session.rest.runMethod<undefined>(
this.session.rest, this.session.rest,
"POST", "POST",

View File

@ -18,7 +18,7 @@ export class EventEmitter {
return this.#addListener(event, func); return this.#addListener(event, func);
} }
#removeListener(event: string, func: Function) { #removeListener(event: string, func: Function): EventEmitter {
if (this.listeners.has(event)) { if (this.listeners.has(event)) {
const listener = this.listeners.get(event); const listener = this.listeners.get(event);
@ -34,11 +34,11 @@ export class EventEmitter {
return this; return this;
} }
off(event: string, func: Function) { off(event: string, func: Function): EventEmitter {
return this.#removeListener(event, func); return this.#removeListener(event, func);
} }
once(event: string, func: Function) { once(event: string, func: Function): EventEmitter {
// it is important for this to be an arrow function // it is important for this to be an arrow function
const closure = () => { const closure = () => {
func(); func();
@ -52,7 +52,7 @@ export class EventEmitter {
return this; return this;
} }
emit(event: string, ...args: unknown[]) { emit(event: string, ...args: unknown[]): boolean {
const listener = this.listeners.get(event); const listener = this.listeners.get(event);
if (!listener) { if (!listener) {
@ -64,7 +64,7 @@ export class EventEmitter {
return true; return true;
} }
listenerCount(eventName: string) { listenerCount(eventName: string): number {
return this.listeners.get(eventName)?.length ?? 0; return this.listeners.get(eventName)?.length ?? 0;
} }

View File

@ -1,5 +1,5 @@
/** Converts a url to base 64. Useful for example, uploading/creating server emojis. */ /** Converts a url to base 64. Useful for example, uploading/creating server emojis. */
export async function urlToBase64(url: string) { export async function urlToBase64(url: string): Promise<string> {
const buffer = await fetch(url).then((res) => res.arrayBuffer()); const buffer = await fetch(url).then((res) => res.arrayBuffer());
const imageStr = encode(buffer); const imageStr = encode(buffer);
const type = url.substring(url.lastIndexOf(".") + 1); const type = url.substring(url.lastIndexOf(".") + 1);
@ -8,7 +8,7 @@ export async function urlToBase64(url: string) {
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. // Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
// deno-fmt-ignore // deno-fmt-ignore
const base64abc = [ const base64abc: string[] = [
"A", "B", "C", "A", "B", "C",
"D", "E", "F", "D", "E", "F",
"G", "H", "I", "G", "H", "I",
@ -38,14 +38,14 @@ const base64abc = [
* @param data * @param data
*/ */
export function encode(data: ArrayBuffer | string): string { export function encode(data: ArrayBuffer | string): string {
const uint8 = typeof data === "string" const uint8: Uint8Array = typeof data === "string"
? new TextEncoder().encode(data) ? new TextEncoder().encode(data)
: data instanceof Uint8Array : data instanceof Uint8Array
? data ? data
: new Uint8Array(data); : new Uint8Array(data);
let result = "", let result = "",
i; i;
const l = uint8.length; const l: number = uint8.length;
for (i = 2; i < l; i += 3) { for (i = 2; i < l; i += 3) {
result += base64abc[uint8[i - 2] >> 2]; result += base64abc[uint8[i - 2] >> 2];
result += base64abc[((uint8[i - 2] & 0x03) << 4) | (uint8[i - 1] >> 4)]; result += base64abc[((uint8[i - 2] & 0x03) << 4) | (uint8[i - 1] >> 4)];