This commit is contained in:
Skillz
2023-02-28 11:48:27 -06:00
12 changed files with 780 additions and 20 deletions
+2 -2
View File
@@ -31,7 +31,7 @@ jobs:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./site
working-directory: ./website
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
@@ -55,7 +55,7 @@ jobs:
- name: Upload artifact
uses: actions/upload-pages-artifact@v1
with:
path: ./site/build
path: ./website/build
deploy:
environment:
name: github-pages
+12 -9
View File
@@ -27,6 +27,8 @@ import { delay, getBotIdFromToken, iconBigintToHash, iconHashToBigInt } from '@d
import EventEmitter from 'node:events'
import Base from './Base.js'
import Collection from './Collection.js'
import type { IntentStrings } from './Constants.js';
import { Intents } from './Constants.js'
import {
CHANNEL,
CHANNEL_BULK_DELETE,
@@ -261,6 +263,8 @@ export class Client extends EventEmitter {
constructor(token: string, options: ClientOptions) {
super()
this.token = token
this.options = {
apiVersion: options.apiVersion ?? 10,
allowedMentions: this._formatAllowedMentions(options.allowedMentions),
@@ -268,7 +272,7 @@ export class Client extends EventEmitter {
defaultImageSize: options.defaultImageSize ?? 128,
proxyURL: options.proxyURL,
proxyRestAuthorization: options.proxyRestAuthorization,
applicationId: options.applicationId,
applicationId: options.applicationId ?? this.id,
messageLimit: options.messageLimit,
seedVoiceConnections: options.seedVoiceConnections ?? true,
shardConcurrency: options.shardConcurrency ?? 'auto',
@@ -278,13 +282,12 @@ export class Client extends EventEmitter {
firstShardID: options.firstShardID ?? 0,
lastShardID: options.lastShardID,
maxResumeAttempts: options.maxResumeAttempts ?? Infinity,
intents: options.intents ?? 0,
intents: typeof options.intents === "number" ? options.intents : Array.isArray(options.intents) ? options.intents.reduce<GatewayIntents>((bits, intent) => (typeof intent === "number" ? intent | bits : Intents[intent]), 0) : 0,
autoreconnect: options.autoreconnect ?? true,
guildCreateTimeout: options.guildCreateTimeout ?? 2000,
reconnectDelay: options.reconnectDelay ?? ((lastDelay, attempts) => Math.pow(attempts + 1, 0.7) * 20000),
}
this.token = token
this.guildShardMap = {}
this.requestHandler = new RequestHandler(this, {})
@@ -2343,15 +2346,15 @@ export interface ClientOptions {
/** The message limit you would like to set. */
messageLimit?: number
/** The api version you would like to use. */
apiVersion: ApiVersions
apiVersion?: ApiVersions
/** The url to the REST proxy to send requests to. This url should nly include the initial domain:port portion until api/v.... */
proxyURL: string
proxyURL?: string
/** The password/authorization to confirm that these request made to your rest proxy are indeed from you and not a hacker. */
proxyRestAuthorization: string
proxyRestAuthorization?: string
/** The application id(NOT the bot id). The bot id and application id are the same for newer bots but older bots have different ids. */
applicationId: BigString
applicationId?: BigString
/** Whether or not to seed voice connections. */
seedVoiceConnections: boolean
seedVoiceConnections?: boolean
/** The concurrency to use when starting the bot. */
shardConcurrency?: 'auto' | number
/** How many shards to use max. */
@@ -2365,7 +2368,7 @@ export interface ClientOptions {
/** How many times to attempt resuming. */
maxResumeAttempts?: number
/** The intents to use when connection to gateway. */
intents?: GatewayIntents
intents?: GatewayIntents | number | Array<IntentStrings | number>
/** Whether or not to automatically reconnect to gateway. */
autoreconnect?: boolean
/**
+561
View File
@@ -0,0 +1,561 @@
export const GATEWAY_VERSION = 9;
export const REST_VERSION = 9;
export const ActivityTypes = {
GAME: 0,
STREAMING: 1,
LISTENING: 2,
WATCHING: 3,
CUSTOM: 4,
COMPETING: 5
};
export const ApplicationCommandOptionTypes = {
SUB_COMMAND: 1,
SUB_COMMAND_GROUP: 2,
STRING: 3,
INTEGER: 4,
BOOLEAN: 5,
USER: 6,
CHANNEL: 7,
ROLE: 8,
MENTIONABLE: 9,
NUMBER: 10
};
export const ApplicationCommandPermissionTypes = {
ROLE: 1,
USER: 2
};
export const ApplicationCommandTypes = {
CHAT_INPUT: 1,
USER: 2,
MESSAGE: 3
};
export const AuditLogActions = {
GUILD_UPDATE: 1,
CHANNEL_CREATE: 10,
CHANNEL_UPDATE: 11,
CHANNEL_DELETE: 12,
CHANNEL_OVERWRITE_CREATE: 13,
CHANNEL_OVERWRITE_UPDATE: 14,
CHANNEL_OVERWRITE_DELETE: 15,
MEMBER_KICK: 20,
MEMBER_PRUNE: 21,
MEMBER_BAN_ADD: 22,
MEMBER_BAN_REMOVE: 23,
MEMBER_UPDATE: 24,
MEMBER_ROLE_UPDATE: 25,
MEMBER_MOVE: 26,
MEMBER_DISCONNECT: 27,
BOT_ADD: 28,
ROLE_CREATE: 30,
ROLE_UPDATE: 31,
ROLE_DELETE: 32,
INVITE_CREATE: 40,
INVITE_UPDATE: 41,
INVITE_DELETE: 42,
WEBHOOK_CREATE: 50,
WEBHOOK_UPDATE: 51,
WEBHOOK_DELETE: 52,
EMOJI_CREATE: 60,
EMOJI_UPDATE: 61,
EMOJI_DELETE: 62,
MESSAGE_DELETE: 72,
MESSAGE_BULK_DELETE: 73,
MESSAGE_PIN: 74,
MESSAGE_UNPIN: 75,
INTEGRATION_CREATE: 80,
INTEGRATION_UPDATE: 81,
INTEGRATION_DELETE: 82,
STAGE_INSTANCE_CREATE: 83,
STAGE_INSTANCE_UPDATE: 84,
STAGE_INSTANCE_DELETE: 85,
STICKER_CREATE: 90,
STICKER_UPDATE: 91,
STICKER_DELETE: 92,
GUILD_SCHEDULED_EVENT_CREATE: 100,
GUILD_SCHEDULED_EVENT_UPDATE: 101,
GUILD_SCHEDULED_EVENT_DELETE: 102,
THREAD_CREATE: 110,
THREAD_UPDATE: 111,
THREAD_DELETE: 112,
APPLICATION_COMMAND_PERMISSION_UPDATE: 121
};
export const ButtonStyles = {
PRIMARY: 1,
SECONDARY: 2,
SUCCESS: 3,
DANGER: 4,
LINK: 5
};
export const ChannelTypes = {
GUILD_TEXT: 0,
DM: 1,
GUILD_VOICE: 2,
GROUP_DM: 3,
GUILD_CATEGORY: 4,
GUILD_NEWS: 5,
GUILD_STORE: 6,
GUILD_NEWS_THREAD: 10,
GUILD_PUBLIC_THREAD: 11,
GUILD_PRIVATE_THREAD: 12,
GUILD_STAGE_VOICE: 13, GUILD_STAGE: 13 // [DEPRECATED]
};
export const ComponentTypes = {
ACTION_ROW: 1,
BUTTON: 2,
SELECT_MENU: 3
};
export const ConnectionVisibilityTypes = {
NONE: 0,
EVERYONE: 1
};
export const DefaultMessageNotificationLevels = {
ALL_MESSAGES: 0,
ONLY_MENTIONS: 1
};
export const ExplicitContentFilterLevels = {
DISABLED: 0,
MEMBERS_WITHOUT_ROLES: 1,
ALL_MEMBERS: 2
};
export const GatewayOPCodes = {
DISPATCH: 0, EVENT: 0, // [DEPRECATED]
HEARTBEAT: 1,
IDENTIFY: 2,
PRESENCE_UPDATE: 3, STATUS_UPDATE: 3, // [DEPRECATED]
VOICE_STATE_UPDATE: 4,
VOICE_SERVER_PING: 5,
RESUME: 6,
RECONNECT: 7,
REQUEST_GUILD_MEMBERS: 8, GET_GUILD_MEMBERS: 8, // [DEPRECATED]
INVALID_SESSION: 9,
HELLO: 10,
HEARTBEAT_ACK: 11,
SYNC_GUILD: 12,
SYNC_CALL: 13
};
export const GuildFeatures = [
"ANIMATED_ICON",
"BANNER",
"COMMERCE",
"COMMUNITY",
"DISCOVERABLE",
"FEATURABLE",
"INVITE_SPLASH",
"MEMBER_VERIFICATION_GATE_ENABLED",
"MONETIZATION_ENABLED",
"MORE_STICKERS",
"NEWS",
"PARTNERED",
"PREVIEW_ENABLED",
"PRIVATE_THREADS",
"ROLE_ICONS",
"ROLE_SUBSCRIPTIONS_ENABLED",
"SEVEN_DAY_THREAD_ARCHIVE",
"THREE_DAY_THREAD_ARCHIVE",
"TICKETED_EVENTS_ENABLED",
"VANITY_URL",
"VERIFIED",
"VIP_REGIONS",
"WELCOME_SCREEN_ENABLED"
];
export const GuildIntegrationExpireBehavior = {
REMOVE_ROLE: 0,
KICK: 1
};
export const GuildIntegrationTypes = [
"twitch",
"youtube",
"discord"
];
export const GuildNSFWLevels = {
DEFAULT: 0,
EXPLICIT: 1,
SAFE: 2,
AGE_RESTRICTED: 3
};
export const ImageFormats = [
"jpg",
"jpeg",
"png",
"webp",
"gif"
];
export const ImageSizeBoundaries = {
MINIMUM: 16,
MAXIMUM: 4096
};
export const Intents = {
guilds: 1 << 0,
guildMembers: 1 << 1,
guildBans: 1 << 2,
guildEmojisAndStickers: 1 << 3, guildEmojis: 1 << 3, // [DEPRECATED]
guildIntegrations: 1 << 4,
guildWebhooks: 1 << 5,
guildInvites: 1 << 6,
guildVoiceStates: 1 << 7,
guildPresences: 1 << 8,
guildMessages: 1 << 9,
guildMessageReactions: 1 << 10,
guildMessageTyping: 1 << 11,
directMessages: 1 << 12,
directMessageReactions: 1 << 13,
directMessageTyping: 1 << 14,
guildScheduledEvents: 1 << 16,
// Override these below
allNonPrivileged: 0,
allPrivileged: 0,
all: 0,
};
Intents.allNonPrivileged = Intents.guilds
| Intents.guildBans
| Intents.guildEmojisAndStickers
| Intents.guildIntegrations
| Intents.guildWebhooks
| Intents.guildInvites
| Intents.guildVoiceStates
| Intents.guildMessages
| Intents.guildMessageReactions
| Intents.guildMessageTyping
| Intents.directMessages
| Intents.directMessageReactions
| Intents.directMessageTyping
| Intents.guildScheduledEvents;
Intents.allPrivileged = Intents.guildMembers
| Intents.guildPresences;
Intents.all = Intents.allNonPrivileged | Intents.allPrivileged;
export const InteractionResponseTypes = {
PONG: 1,
CHANNEL_MESSAGE_WITH_SOURCE: 4,
DEFERRED_CHANNEL_MESSAGE_WITH_SOURCE: 5,
DEFERRED_UPDATE_MESSAGE: 6,
UPDATE_MESSAGE: 7,
APPLICATION_COMMAND_AUTOCOMPLETE_RESULT: 8
};
export const InteractionTypes = {
PING: 1,
APPLICATION_COMMAND: 2,
MESSAGE_COMPONENT: 3,
APPLICATION_COMMAND_AUTOCOMPLETE: 4
};
export const MFALevels = {
NONE: 0,
ELEVATED: 1
};
export const MessageActivityFlags = {
INSTANCE: 1 << 0,
JOIN: 1 << 1,
SPECTATE: 1 << 2,
JOIN_REQUEST: 1 << 3,
SYNC: 1 << 4,
PLAY: 1 << 5,
PARTY_PRIVACY_FRIENDS: 1 << 6,
PARTY_PRIVACY_VOICE_CHANNEL: 1 << 7,
EMBEDDED: 1 << 8
};
export const MessageActivityTypes = {
JOIN: 1,
SPECTATE: 2,
LISTEN: 3,
JOIN_REQUEST: 5
};
export const MessageTypes = {
DEFAULT: 0,
RECIPIENT_ADD: 1,
RECIPIENT_REMOVE: 2,
CALL: 3,
CHANNEL_NAME_CHANGE: 4,
CHANNEL_ICON_CHANGE: 5,
CHANNEL_PINNED_MESSAGE: 6,
GUILD_MEMBER_JOIN: 7,
USER_PREMIUM_GUILD_SUBSCRIPTION: 8,
USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_1: 9,
USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_2: 10,
USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_3: 11,
CHANNEL_FOLLOW_ADD: 12,
GUILD_DISCOVERY_DISQUALIFIED: 14,
GUILD_DISCOVERY_REQUALIFIED: 15,
GUILD_DISCOVERY_GRACE_PERIOD_INITIAL_WARNING: 16,
GUILD_DISCOVERY_GRACE_PERIOD_FINAL_WARNING: 17,
THREAD_CREATED: 18,
REPLY: 19,
CHAT_INPUT_COMMAND: 20,
THREAD_STARTER_MESSAGE: 21,
GUILD_INVITE_REMINDER: 22,
CONTEXT_MENU_COMMAND: 23
};
export const PermissionOverwriteTypes = {
ROLE: 0,
USER: 1
};
export const Permissions = {
createInstantInvite: 1n << 0n,
kickMembers: 1n << 1n,
banMembers: 1n << 2n,
administrator: 1n << 3n,
manageChannels: 1n << 4n,
manageGuild: 1n << 5n,
addReactions: 1n << 6n,
viewAuditLog: 1n << 7n, viewAuditLogs: 1n << 7n, // [DEPRECATED]
voicePrioritySpeaker: 1n << 8n,
voiceStream: 1n << 9n, stream: 1n << 9n, // [DEPRECATED]
viewChannel: 1n << 10n, readMessages: 1n << 10n, // [DEPRECATED]
sendMessages: 1n << 11n,
sendTTSMessages: 1n << 12n,
manageMessages: 1n << 13n,
embedLinks: 1n << 14n,
attachFiles: 1n << 15n,
readMessageHistory: 1n << 16n,
mentionEveryone: 1n << 17n,
useExternalEmojis: 1n << 18n, externalEmojis: 1n << 18n, // [DEPRECATED]
viewGuildInsights: 1n << 19n,
voiceConnect: 1n << 20n,
voiceSpeak: 1n << 21n,
voiceMuteMembers: 1n << 22n,
voiceDeafenMembers: 1n << 23n,
voiceMoveMembers: 1n << 24n,
voiceUseVAD: 1n << 25n,
changeNickname: 1n << 26n,
manageNicknames: 1n << 27n,
manageRoles: 1n << 28n,
manageWebhooks: 1n << 29n,
manageEmojisAndStickers: 1n << 30n, manageEmojis: 1n << 30n, // [DEPRECATED]
useApplicationCommands: 1n << 31n, useSlashCommands: 1n << 31n, // [DEPRECATED]
voiceRequestToSpeak: 1n << 32n,
manageEvents: 1n << 33n,
manageThreads: 1n << 34n,
createPublicThreads: 1n << 35n,
createPrivateThreads: 1n << 36n,
useExternalStickers: 1n << 37n,
sendMessagesInThreads: 1n << 38n,
startEmbeddedActivities: 1n << 39n,
moderateMembers: 1n << 40n,
// Override these below
all: 0n,
allText: 0n,
allVoice: 0n,
allGuild: 0n,
};
Permissions.allGuild = Permissions.kickMembers
| Permissions.banMembers
| Permissions.administrator
| Permissions.manageChannels
| Permissions.manageGuild
| Permissions.viewAuditLog
| Permissions.viewGuildInsights
| Permissions.changeNickname
| Permissions.manageNicknames
| Permissions.manageRoles
| Permissions.manageWebhooks
| Permissions.manageEmojisAndStickers
| Permissions.manageEvents
| Permissions.moderateMembers;
Permissions.allText = Permissions.createInstantInvite
| Permissions.manageChannels
| Permissions.addReactions
| Permissions.viewChannel
| Permissions.sendMessages
| Permissions.sendTTSMessages
| Permissions.manageMessages
| Permissions.embedLinks
| Permissions.attachFiles
| Permissions.readMessageHistory
| Permissions.mentionEveryone
| Permissions.useExternalEmojis
| Permissions.manageRoles
| Permissions.manageWebhooks
| Permissions.useApplicationCommands
| Permissions.manageThreads
| Permissions.createPublicThreads
| Permissions.createPrivateThreads
| Permissions.useExternalStickers
| Permissions.sendMessagesInThreads;
Permissions.allVoice = Permissions.createInstantInvite
| Permissions.manageChannels
| Permissions.voicePrioritySpeaker
| Permissions.voiceStream
| Permissions.viewChannel
| Permissions.voiceConnect
| Permissions.voiceSpeak
| Permissions.voiceMuteMembers
| Permissions.voiceDeafenMembers
| Permissions.voiceMoveMembers
| Permissions.voiceUseVAD
| Permissions.manageRoles
| Permissions.voiceRequestToSpeak
| Permissions.startEmbeddedActivities;
Permissions.all = Permissions.allGuild | Permissions.allText | Permissions.allVoice;
export const PremiumTiers = {
NONE: 0,
TIER_1: 1,
TIER_2: 2,
TIER_3: 3
};
export const GuildScheduledEventStatus = {
SCHEDULED: 1,
ACTIVE: 2,
COMPLETED: 3,
CANCELED: 4
};
export const GuildScheduledEventEntityTypes = {
STAGE_INSTANCE: 1,
VOICE: 2,
EXTERNAL: 3
};
export const GuildScheduledEventPrivacyLevel = {
PUBLIC: 1,
GUILD_ONLY: 2
};
export const PremiumTypes = {
NONE: 0,
NITRO_CLASSIC: 1,
NITRO: 2
};
export const StageInstancePrivacyLevel = {
PUBLIC: 1,
GUILD_ONLY: 2
};
export const StickerFormats = {
PNG: 1,
APNG: 2,
LOTTIE: 3
};
export const StickerTypes = {
STANDARD: 1,
GUILD: 2
};
export const SystemChannelFlags = {
SUPPRESS_JOIN_NOTIFICATIONS: 1 << 0,
SUPPRESS_PREMIUM_SUBSCRIPTIONS: 1 << 1,
SUPPRESS_GUILD_REMINDER_NOTIFICATIONS: 1 << 2,
SUPPRESS_JOIN_NOTIFICATION_REPLIES : 1 << 3
};
export const SystemJoinMessages = [
"%user% joined the party.",
"%user% is here.",
"Welcome, %user%. We hope you brought pizza.",
"A wild %user% appeared.",
"%user% just landed.",
"%user% just slid into the server.",
"%user% just showed up!",
"Welcome %user%. Say hi!",
"%user% hopped into the server.",
"Everyone welcome %user%!",
"Glad you're here, %user%.",
"Good to see you, %user%.",
"Yay you made it, %user%!"
];
export const ThreadMemberFlags = {
HAS_INTERACTED: 1 << 0,
ALL_MESSAGES: 1 << 1,
ONLY_MENTIONS: 1 << 2,
NO_MESSAGES: 1 << 3
};
export const UserFlags = {
NONE: 0,
DISCORD_STAFF: 1 << 0, DISCORD_EMPLOYEE: 1 << 0,
PARTNER: 1 << 1, PARTNERED_SERVER_OWNER: 1 << 1, DISCORD_PARTNER: 1 << 1, // [DEPRECATED]
HYPESQUAD: 1 << 2, HYPESQUAD_EVENTS: 1 << 2,
BUG_HUNTER_LEVEL_1: 1 << 3,
HOUSE_BRAVERY: 1 << 6, HYPESQUAD_ONLINE_HOUSE_1: 1 << 6,
HOUSE_BRILLIANCE: 1 << 7, HYPESQUAD_ONLINE_HOUSE_2: 1 << 7,
HOUSE_BALANCE: 1 << 8, HYPESQUAD_ONLINE_HOUSE_3: 1 << 8,
PREMIUM_EARLY_SUPPORTER: 1 << 9, EARLY_SUPPORTER: 1 << 9,
TEAM_PSEUDO_USER: 1 << 10, TEAM_USER: 1 << 10,
SYSTEM: 1 << 12,
BUG_HUNTER_LEVEL_2: 1 << 14,
VERIFIED_BOT: 1 << 16,
VERIFIED_DEVELOPER: 1 << 17, EARLY_VERIFIED_BOT_DEVELOPER: 1 << 17, VERIFIED_BOT_DEVELOPER: 1 << 17,
CERTIFIED_MODERATOR: 1 << 18, DISCORD_CERTIFIED_MODERATOR: 1 << 18,
BOT_HTTP_INTERACTIONS: 1 << 19
};
export const VerificationLevels = {
NONE: 0,
LOW: 1,
MEDIUM: 2,
HIGH: 3,
VERY_HIGH: 4
};
export const VideoQualityModes = {
AUTO: 1,
FULL: 2
};
export const VoiceOPCodes = {
IDENTIFY: 0,
SELECT_PROTOCOL: 1,
READY: 2,
HEARTBEAT: 3,
SESSION_DESCRIPTION: 4,
SPEAKING: 5,
HEARTBEAT_ACK: 6,
RESUME: 7,
HELLO: 8,
RESUMED: 9,
CLIENT_DISCONNECT: 13, DISCONNECT: 13 // [DEPRECATED]
};
export const WebhookTypes = {
INCOMING: 1,
CHANNEL_FOLLOWER: 2,
APPLICATION: 3
};
export type IntentStrings = keyof typeof Intents;
export type PermissionClientStrings = keyof typeof Permissions;
+4 -1
View File
@@ -21,7 +21,9 @@ import { MessageFlags, type GetMessageReactionOptions, type MessageContentEdit,
import type NewsChannel from './channels/News.js'
import type PrivateChannel from './channels/Private.js'
import type TextChannel from './channels/Text.js'
import type TextVoiceChannel from './channels/TextVoice.js'
import type NewsThreadChannel from './channels/threads/NewsThread.js'
import type PrivateThreadChannel from './channels/threads/PrivateThread.js'
import type PublicThreadChannel from './channels/threads/PublicThread.js'
import type Guild from './guilds/Guild.js'
import Member from './guilds/Member.js'
@@ -35,7 +37,7 @@ export class Message extends Base {
/** The type of the message */
type: MessageTypes
/** The channel the message is in. Can be partial with only the id if the channel is not cached. */
channel: PrivateChannel | TextChannel | NewsChannel | { id: string }
channel: PrivateChannel | TextChannel | NewsChannel | NewsThreadChannel | PublicThreadChannel | PrivateThreadChannel | TextVoiceChannel
/** The message content. */
content: string
/** An object containing the reactions on the message. Each key is a reaction emoji and each value is an object with properties `me` (Boolean) and `count` (Number) for that specific reaction emoji. */
@@ -111,6 +113,7 @@ export class Message extends Base {
this.type = data.type || MessageTypes.Default
this.timestamp = Date.parse(data.timestamp)
// @ts-expect-error eris js hack
this.channel = this.client.getChannel(data.channel_id) ?? {
id: data.channel_id,
}
+3 -2
View File
@@ -2,6 +2,7 @@
import { BitwisePermissionFlags } from '@discordeno/types'
import { Base } from '../Base.js'
import type { BigString } from '../Client.js'
import { PermissionClientStrings, Permissions } from '../Constants.js'
export class Permission {
allow: bigint
@@ -36,13 +37,13 @@ export class Permission {
}
/** Check if this permission allows a specific permission */
has(permission: bigint | keyof typeof BitwisePermissionFlags): boolean {
has(permission: bigint | PermissionClientStrings): boolean {
if (this.isAdmin) return true
if (typeof permission === 'bigint') {
return (this.allow & permission) === permission
}
return !!(this.allow & BigInt(BitwisePermissionFlags[permission]))
return !!(this.allow & Permissions[permission])
}
toString() {
@@ -36,7 +36,7 @@ export class PrivateChannel extends Channel {
}
/** Create a message in a text channel */
async createMessage(content: MessageContent, file: FileContent | FileContent[]): Promise<Message> {
async createMessage(content: MessageContent, file?: FileContent | FileContent[]): Promise<Message> {
return await this.client.createMessage.call(this.client, this.id, content, file)
}
@@ -109,7 +109,7 @@ export class TextChannel extends GuildChannel {
* @arg {String} file.name What to name the file
* @returns {Promise<Message>}
*/
async createMessage(content: MessageContent, file: FileContent | FileContent[]) {
async createMessage(content: MessageContent, file?: FileContent | FileContent[]) {
return this.client.createMessage.call(this.client, this.id, content, file)
}
@@ -24,6 +24,7 @@ import type Client from '../../Client.js'
import type { ImageFormat, ImageSize } from '../../Client.js'
import Collection from '../../Collection.js'
import { BANNER, GUILD_DISCOVERY_SPLASH, GUILD_ICON, GUILD_SPLASH } from '../../Endpoints.js'
import type Shard from '../../gateway/Shard.js'
import type {
AnyGuildChannel,
AnyThreadChannel,
@@ -139,7 +140,7 @@ export class Guild extends Base {
/** When this guild was joined at. */
joinedAt: number
/** The amount of members in the guild. */
memberCount?: number
memberCount: number
/** The approximate member count in the guild. */
approximateMemberCount?: number
/** The approximate presence count in the guild. */
@@ -185,15 +186,19 @@ export class Guild extends Base {
voiceStates = new Collection<BigString, VoiceState>()
/** The cached stage instances in this guild. */
stageInstances = new Collection<BigString, StageInstance>()
/** The shard that manages this guild. */
shard: Shard;
constructor(data: DiscordGuild, client: Client) {
super(data.id)
this.client = client
this.shard = client.shards.get(client.guildShardMap[this.id] || (Base.getDiscordEpoch(data.id) % (client.options.maxShards as number)) || 0)!;
this.ownerID = data.owner_id
this.unavailable = !!data.unavailable
this.joinedAt = Date.parse(data.joined_at!)
this.memberCount = data.member_count
this.memberCount = data.member_count ?? 0
this.applicationID = data.application_id
this.widgetEnabled = !!data.widget_enabled
+3
View File
@@ -4,6 +4,7 @@ export default Client
export * from './Base.js'
export * from './Client.js'
export * from './Collection.js'
export * from './Constants.js'
export * from './Endpoints.js'
export * from './gateway/Shard.js'
export * from './gateway/ShardManager.js'
@@ -46,3 +47,5 @@ export * from './Structures/users/User.js'
export * from './typings.js'
export * from './utils/BrowserWebSocket.js'
export * from './utils/Bucket.js'
export * from './utils/DiscordRESTError.js'
export * from './utils/generate.js'
+92
View File
@@ -37,6 +37,16 @@ import type GuildAuditLogEntry from './Structures/guilds/AuditLogEntry.js'
import type GuildIntegration from './Structures/guilds/Integration.js'
import type Member from './Structures/guilds/Member.js'
import type User from './Structures/users/User.js'
import type { Guild, Invite } from './index.js'
import type Role from './Structures/guilds/Role.js'
import type StageInstance from './Structures/guilds/StageInstance.js'
import type UnavailableGuild from './Structures/guilds/Unavailable.js'
import type AutocompleteInteraction from './Structures/interactions/Autocomplete.js'
import type CommandInteraction from './Structures/interactions/Command.js'
import type ComponentInteraction from './Structures/interactions/Component.js'
import type PingInteraction from './Structures/interactions/Ping.js'
import type UnknownInteraction from './Structures/interactions/Unknown.js'
import type { IncomingHttpHeaders } from 'node:http'
export type ApplicationCommandStructure = ChatInputApplicationCommandStructure | MessageApplicationCommandStructure | UserApplicationCommandStructure
export type ChatInputApplicationCommand = ApplicationCommand<ApplicationCommandTypes.ChatInput>
@@ -885,3 +895,85 @@ export const MessageFlags = {
EPHEMERAL: 64,
LOADING: 128,
}
export interface EventListeners {
channelCreate: [channel: AnyGuildChannel];
channelDelete: [channel: AnyChannel];
channelPinUpdate: [channel: TextableChannel, timestamp: number, oldTimestamp: number];
channelUpdate: [channel: AnyGuildChannel, oldChannel: any];
connect: [id: number];
debug: [message: string, id?: number];
disconnect: [];
error: [err: Error, id?: number];
guildAvailable: [guild: Guild];
guildBanAdd: [guild: Guild, user: User];
guildBanRemove: [guild: Guild, user: User];
guildCreate: [guild: Guild];
guildDelete: [guild: any];
guildEmojisUpdate: [guild: any, emojis: Emoji[], oldEmojis: Emoji[] | null];
guildMemberAdd: [guild: Guild, member: Member];
guildMemberChunk: [guild: Guild, member: Member[]];
guildMemberRemove: [guild: Guild, member: Member | any];
guildMemberUpdate: [guild: Guild, member: Member, oldMember: any | null];
guildRoleCreate: [guild: Guild, role: Role];
guildRoleDelete: [guild: Guild, role: Role];
guildRoleUpdate: [guild: Guild, role: Role, oldRole: any];
guildScheduledEventCreate: [event: any];
guildScheduledEventDelete: [event: any];
guildScheduledEventUpdate: [event: any, oldEvent: any | null];
guildScheduledEventUserAdd: [event: any, user: User | Uncached];
guildScheduledEventUserRemove: [event: any, user: User | Uncached];
guildStickersUpdate: [guild: any, stickers: Sticker[], oldStickers: Sticker[] | null];
guildUnavailable: [guild: UnavailableGuild];
guildUpdate: [guild: Guild, oldGuild: any];
hello: [trace: string[], id: number];
interactionCreate: [interaction: PingInteraction | CommandInteraction | ComponentInteraction | AutocompleteInteraction | UnknownInteraction];
inviteCreate: [guild: Guild, invite: Invite];
inviteDelete: [guild: Guild, invite: Invite];
messageCreate: [message: Message];
messageDelete: [message: any];
messageDeleteBulk: [messages: any[]];
messageReactionAdd: [message: any, emoji: PartialEmoji, reactor: Member | Uncached];
messageReactionRemove: [message: any, emoji: PartialEmoji, userID: string];
messageReactionRemoveAll: [message: any];
messageReactionRemoveEmoji: [message: any, emoji: PartialEmoji];
messageUpdate: [message: Message, oldMessage: any | null];
presenceUpdate: [other: Member, oldPresence: any | null];
rawREST: [request: any];
rawWS: [packet: any, id: number];
ready: [];
shardPreReady: [id: number];
stageInstanceCreate: [stageInstance: StageInstance];
stageInstanceDelete: [stageInstance: StageInstance];
stageInstanceUpdate: [stageInstance: StageInstance, oldStageInstance: any | null];
threadCreate: [channel: AnyThreadChannel];
threadDelete: [channel: AnyThreadChannel];
threadListSync: [guild: Guild, deletedThreads: Array<AnyThreadChannel | Uncached>, activeThreads: AnyThreadChannel[], joinedThreadsMember: ThreadMember[]];
threadMembersUpdate: [channel: AnyThreadChannel, addedMembers: ThreadMember[], removedMembers: Array<ThreadMember | Uncached>];
threadMemberUpdate: [channel: AnyThreadChannel, member: ThreadMember, oldMember: any];
threadUpdate: [channel: AnyThreadChannel, oldChannel: any | null];
typingStart: [channel: GuildTextableChannel | Uncached, user: User | Uncached, member: Member]
| [channel: PrivateChannel | Uncached, user: User | Uncached, member: null];
unavailableGuildCreate: [guild: UnavailableGuild];
unknown: [packet: any, id?: number];
userUpdate: [user: User, oldUser: PartialUser | null];
voiceChannelJoin: [member: Member, channel: AnyVoiceChannel];
voiceChannelLeave: [member: Member, channel: AnyVoiceChannel];
voiceChannelSwitch: [member: Member, newChannel: AnyVoiceChannel, oldChannel: AnyVoiceChannel];
voiceStateUpdate: [member: Member, oldState: any];
warn: [message: string, id?: number];
webhooksUpdate: [data: any];
}
export interface ClientEvents extends EventListeners {
shardDisconnect: [err: Error | undefined, id: number];
shardReady: [id: number];
shardResume: [id: number];
}
export interface HTTPResponse {
code: number;
message: string;
errors?: HTTPResponse
headers: IncomingHttpHeaders
}
@@ -0,0 +1,86 @@
import type { ClientRequest, IncomingHttpHeaders, IncomingMessage } from 'http'
import type { HTTPResponse } from '../typings.js'
export class DiscordRESTError extends Error {
code: number = -1
req!: ClientRequest
res!: IncomingMessage
response!: HTTPResponse
constructor(req: ClientRequest, res: IncomingMessage, response: HTTPResponse, stack: string) {
super()
Object.defineProperty(this, 'req', {
enumerable: false,
value: req,
})
Object.defineProperty(this, 'res', {
enumerable: false,
value: res,
})
Object.defineProperty(this, 'response', {
enumerable: false,
value: response,
})
Object.defineProperty(this, 'code', {
enumerable: false,
value: +response.code || -1,
})
let message = response.message || 'Unknown error'
if (response.errors) {
message += '\n ' + this.flattenErrors(response.errors).join('\n ')
} else {
const errors = this.flattenErrors(response)
if (errors.length > 0) {
message += '\n ' + errors.join('\n ')
}
}
Object.defineProperty(this, 'message', {
enumerable: false,
value: message,
})
if (stack) {
this.stack = this.name + ': ' + this.message + '\n' + stack
} else {
Error.captureStackTrace(this, DiscordRESTError)
}
}
get headers(): IncomingHttpHeaders {
return this.response.headers
}
get name(): string {
return `${this.constructor.name} [${this.code}]`
}
flattenErrors(errors: HTTPResponse, keyPrefix?: string): string[] {
let messages: string[] = []
for (const fieldName of Object.keys(errors)) {
if (fieldName === 'message' || fieldName === 'code') {
continue
}
const prefix = `${keyPrefix ?? ""}${fieldName}`;
// @ts-expect-error js hack from eris
if (errors[fieldName]._errors) {
// @ts-expect-error js hack from eris
messages = messages.concat(errors[fieldName]._errors.map((obj: any) => `${prefix}: ${obj.message as string}`))
// @ts-expect-error js hack from eris
} else if (Array.isArray(errors[fieldName])) {
// @ts-expect-error js hack from eris
messages = messages.concat(errors[fieldName].map((str: string) => `${prefix}: ${str}`))
// @ts-expect-error js hack from eris
} else if (typeof errors[fieldName] === 'object') {
// @ts-expect-error js hack from eris
messages = messages.concat(this.flattenErrors(errors[fieldName], `${prefix}.`))
}
}
return messages
}
}
export default DiscordRESTError
+8 -2
View File
@@ -665,11 +665,17 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage
const newObj: any = {}
for (const key of Object.keys(obj)) {
if (key === 'permissions') {
newObj.permissions = calculateBits(obj[key])
// Keys that dont require snake casing
if (['permissions', 'allow', 'deny'].includes(key)) {
newObj[key] = calculateBits(obj[key])
continue
}
if (key === 'defaultMemberPermissions') {
newObj.default_member_permissions = calculateBits(obj[key]);
continue;
}
newObj[camelToSnakeCase(key)] = rest.changeToDiscordFormat(obj[key])
}