lunibee 0.1.4 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -23
- package/dist/builders/components.d.ts +108 -0
- package/dist/builders/index.d.ts +1 -1
- package/dist/builders/index.js +178 -2
- package/dist/builders/index.js.map +3 -3
- package/dist/collection/index.d.ts +6 -0
- package/dist/collection/index.js +33 -2
- package/dist/collection/index.js.map +4 -4
- package/dist/core/events.d.ts +67 -3
- package/dist/core/index.d.ts +120 -90
- package/dist/core/index.js +816 -1021
- package/dist/core/index.js.map +20 -21
- package/dist/formatters/index.js.map +1 -1
- package/dist/index.d.ts +5 -4
- package/dist/index.js +2215 -1392
- package/dist/index.js.map +29 -26
- package/dist/managers/guild.d.ts +30 -0
- package/dist/managers/index.d.ts +56 -75
- package/dist/managers/index.js +339 -48
- package/dist/managers/index.js.map +16 -12
- package/dist/managers/message.d.ts +7 -12
- package/dist/managers/user.d.ts +20 -0
- package/dist/rest/index.d.ts +83 -1
- package/dist/rest/index.js +48 -8
- package/dist/rest/index.js.map +4 -4
- package/dist/rest/routes.d.ts +4 -1
- package/dist/sharding/index.js +4 -1
- package/dist/sharding/index.js.map +4 -4
- package/dist/structures/base.d.ts +99 -48
- package/dist/structures/embed.d.ts +65 -0
- package/dist/structures/index.d.ts +45 -25
- package/dist/structures/index.js +569 -36
- package/dist/structures/index.js.map +10 -8
- package/dist/structures/interactions.d.ts +72 -17
- package/dist/structures/resources.d.ts +9 -5
- package/dist/types/index.d.ts +530 -85
- package/dist/types/index.js +71 -1
- package/dist/types/index.js.map +3 -3
- package/dist/voice/index.js.map +1 -1
- package/dist/ws/index.js +4 -1
- package/dist/ws/index.js.map +4 -4
- package/package.json +15 -15
package/dist/core/index.js.map
CHANGED
|
@@ -1,29 +1,28 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../../packages/core/src/permissions.ts", "../../packages/
|
|
3
|
+
"sources": ["../../packages/core/src/permissions.ts", "../../packages/core/src/events.ts", "../../packages/types/src/index.ts", "../../packages/collection/src/index.ts", "../../packages/managers/src/base.ts", "../../packages/rest/src/routes.ts", "../../packages/rest/src/index.ts", "../../packages/structures/src/base.ts", "../../packages/structures/src/permissions.ts", "../../packages/structures/src/interactions.ts", "../../packages/structures/src/index.ts", "../../packages/managers/src/message.ts", "../../packages/managers/src/thread.ts", "../../packages/managers/src/user.ts", "../../packages/managers/src/guild.ts", "../../packages/managers/src/application.ts", "../../packages/managers/src/index.ts", "../../packages/ws/src/index.ts", "../../packages/core/src/index.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"/** Permission overwrite target types. */\r\nexport enum PermissionOverwriteType {\r\n Role = 0,\r\n Member = 1,\r\n}\r\n\r\n/** Lunibee idiomatic camelCase permission bitflags. */\r\nexport const Permission = {\r\n createInstantInvite: 1n << 0n,\r\n kickMembers: 1n << 1n,\r\n banMembers: 1n << 2n,\r\n administrator: 1n << 3n,\r\n manageChannels: 1n << 4n,\r\n manageGuild: 1n << 5n,\r\n addReactions: 1n << 6n,\r\n viewAuditLog: 1n << 7n,\r\n prioritySpeaker: 1n << 8n,\r\n stream: 1n << 9n,\r\n viewChannel: 1n << 10n,\r\n sendMessages: 1n << 11n,\r\n sendTTSMessages: 1n << 12n,\r\n manageMessages: 1n << 13n,\r\n embedLinks: 1n << 14n,\r\n attachFiles: 1n << 15n,\r\n readMessageHistory: 1n << 16n,\r\n mentionEveryone: 1n << 17n,\r\n useExternalEmojis: 1n << 18n,\r\n viewGuildInsights: 1n << 19n,\r\n connect: 1n << 20n,\r\n speak: 1n << 21n,\r\n muteMembers: 1n << 22n,\r\n deafenMembers: 1n << 23n,\r\n moveMembers: 1n << 24n,\r\n useVAD: 1n << 25n,\r\n changeNickname: 1n << 26n,\r\n manageNicknames: 1n << 27n,\r\n manageRoles: 1n << 28n,\r\n manageWebhooks: 1n << 29n,\r\n manageGuildExpressions: 1n << 30n,\r\n useApplicationCommands: 1n << 31n,\r\n requestToSpeak: 1n << 32n,\r\n manageEvents: 1n << 33n,\r\n manageThreads: 1n << 34n,\r\n createPublicThreads: 1n << 35n,\r\n createPrivateThreads: 1n << 36n,\r\n useExternalStickers: 1n << 37n,\r\n sendMessagesInThreads: 1n << 38n,\r\n useEmbeddedActivities: 1n << 39n,\r\n moderateMembers: 1n << 40n,\r\n viewCreatorMonetizationAnalytics: 1n << 41n,\r\n useSoundboard: 1n << 42n,\r\n createGuildExpressions: 1n << 43n,\r\n createEvents: 1n << 44n,\r\n useExternalSounds: 1n << 45n,\r\n sendVoiceMessages: 1n << 46n,\r\n sendPolls: 1n << 49n,\r\n useExternalApps: 1n << 50n,\r\n} as const;\r\n\r\n/** Canonical PascalCase permission constants. */\r\nexport const Permissions = {\r\n CreateInstantInvite: 1n << 0n,\r\n KickMembers: 1n << 1n,\r\n BanMembers: 1n << 2n,\r\n Administrator: 1n << 3n,\r\n ManageChannels: 1n << 4n,\r\n ManageGuild: 1n << 5n,\r\n AddReactions: 1n << 6n,\r\n ViewAuditLog: 1n << 7n,\r\n PrioritySpeaker: 1n << 8n,\r\n Stream: 1n << 9n,\r\n ViewChannel: 1n << 10n,\r\n SendMessages: 1n << 11n,\r\n SendTTSMessages: 1n << 12n,\r\n ManageMessages: 1n << 13n,\r\n EmbedLinks: 1n << 14n,\r\n AttachFiles: 1n << 15n,\r\n ReadMessageHistory: 1n << 16n,\r\n MentionEveryone: 1n << 17n,\r\n UseExternalEmojis: 1n << 18n,\r\n ViewGuildInsights: 1n << 19n,\r\n Connect: 1n << 20n,\r\n Speak: 1n << 21n,\r\n MuteMembers: 1n << 22n,\r\n DeafenMembers: 1n << 23n,\r\n MoveMembers: 1n << 24n,\r\n UseVAD: 1n << 25n,\r\n ChangeNickname: 1n << 26n,\r\n ManageNicknames: 1n << 27n,\r\n ManageRoles: 1n << 28n,\r\n ManageWebhooks: 1n << 29n,\r\n ManageGuildExpressions: 1n << 30n,\r\n UseApplicationCommands: 1n << 31n,\r\n RequestToSpeak: 1n << 32n,\r\n ManageEvents: 1n << 33n,\r\n ManageThreads: 1n << 34n,\r\n CreatePublicThreads: 1n << 35n,\r\n CreatePrivateThreads: 1n << 36n,\r\n UseExternalStickers: 1n << 37n,\r\n SendMessagesInThreads: 1n << 38n,\r\n UseEmbeddedActivities: 1n << 39n,\r\n ModerateMembers: 1n << 40n,\r\n ViewCreatorMonetizationAnalytics: 1n << 41n,\r\n UseSoundboard: 1n << 42n,\r\n CreateGuildExpressions: 1n << 43n,\r\n CreateEvents: 1n << 44n,\r\n UseExternalSounds: 1n << 45n,\r\n SendVoiceMessages: 1n << 46n,\r\n SendPolls: 1n << 49n,\r\n UseExternalApps: 1n << 50n,\r\n} as const;\r\n\r\n/** Permission Flags Enum. */\r\nexport enum PermissionFlagsBits {\r\n CreateInstantInvite = \"1\",\r\n KickMembers = \"2\",\r\n BanMembers = \"4\",\r\n Administrator = \"8\",\r\n ManageChannels = \"16\",\r\n ManageGuild = \"32\",\r\n AddReactions = \"64\",\r\n ViewAuditLog = \"128\",\r\n PrioritySpeaker = \"256\",\r\n Stream = \"512\",\r\n ViewChannel = \"1024\",\r\n SendMessages = \"2048\",\r\n SendTTSMessages = \"4096\",\r\n ManageMessages = \"8192\",\r\n EmbedLinks = \"16384\",\r\n AttachFiles = \"32768\",\r\n ReadMessageHistory = \"65536\",\r\n MentionEveryone = \"131072\",\r\n UseExternalEmojis = \"262144\",\r\n ViewGuildInsights = \"524288\",\r\n Connect = \"1048576\",\r\n Speak = \"2097152\",\r\n MuteMembers = \"4194304\",\r\n DeafenMembers = \"8388608\",\r\n MoveMembers = \"16777216\",\r\n UseVAD = \"33554432\",\r\n ChangeNickname = \"67108864\",\r\n ManageNicknames = \"134217728\",\r\n ManageRoles = \"268435456\",\r\n ManageWebhooks = \"536870912\",\r\n ManageGuildExpressions = \"1073741824\",\r\n UseApplicationCommands = \"2147483648\",\r\n RequestToSpeak = \"4294967296\",\r\n ManageEvents = \"8589934592\",\r\n ManageThreads = \"17179869184\",\r\n CreatePublicThreads = \"34359738368\",\r\n CreatePrivateThreads = \"68719476736\",\r\n UseExternalStickers = \"137438953472\",\r\n SendMessagesInThreads = \"274877906944\",\r\n UseEmbeddedActivities = \"549755813888\",\r\n ModerateMembers = \"1099511627776\",\r\n ViewCreatorMonetizationAnalytics = \"2199023255552\",\r\n UseSoundboard = \"4398046511104\",\r\n CreateGuildExpressions = \"8796093022208\",\r\n CreateEvents = \"17592186044416\",\r\n UseExternalSounds = \"35184372088832\",\r\n SendVoiceMessages = \"70368744177664\",\r\n SendPolls = \"562949953421312\",\r\n UseExternalApps = \"1125899906842624\",\r\n}\r\n\r\nexport type PermissionName =\r\n | keyof typeof Permission\r\n | keyof typeof Permissions\r\n | keyof typeof PermissionFlagsBits;\r\n\r\nexport type PermissionResolvable =\r\n | bigint\r\n | number\r\n | string\r\n | PermissionName\r\n | PermissionFlagsBits\r\n | PermissionSet\r\n | PermissionResolvable[];\r\n\r\n/** Immutable permission bitfield with direct boolean getters. */\r\nexport class PermissionSet {\r\n /** Permission bitfield. */\r\n public readonly bitfield: bigint;\r\n\r\n /** Creates a permission set. @param value Initial permission bitfield or array of permissions. @throws {RangeError} If the value is negative. @throws {TypeError} If the value is not a valid integer. */\r\n public constructor(value: PermissionResolvable = 0n) {\r\n try {\r\n if (Array.isArray(value)) {\r\n let bit = 0n;\r\n for (const item of value) {\r\n bit |= this.#resolve(item);\r\n }\r\n this.bitfield = bit;\r\n } else if (value instanceof PermissionSet) {\r\n this.bitfield = value.bitfield;\r\n } else {\r\n const bitfield = this.#resolve(value);\r\n if (bitfield < 0n)\r\n throw new RangeError(\"Permission bitfield cannot be negative.\");\r\n this.bitfield = bitfield;\r\n }\r\n } catch (error) {\r\n if (error instanceof RangeError) throw error;\r\n throw new TypeError(\r\n \"Permission bitfield must be a valid non-negative integer.\",\r\n { cause: error },\r\n );\r\n }\r\n }\r\n\r\n // Direct camelCase boolean getters for instant checks (e.g. member.permissions.kickMembers)\r\n public get createInstantInvite(): boolean {\r\n return (\r\n (this.bitfield & Permission.createInstantInvite) ===\r\n Permission.createInstantInvite\r\n );\r\n }\r\n public get kickMembers(): boolean {\r\n return (this.bitfield & Permission.kickMembers) === Permission.kickMembers;\r\n }\r\n public get banMembers(): boolean {\r\n return (this.bitfield & Permission.banMembers) === Permission.banMembers;\r\n }\r\n public get administrator(): boolean {\r\n return (\r\n (this.bitfield & Permission.administrator) === Permission.administrator\r\n );\r\n }\r\n public get manageChannels(): boolean {\r\n return (\r\n (this.bitfield & Permission.manageChannels) === Permission.manageChannels\r\n );\r\n }\r\n public get manageGuild(): boolean {\r\n return (this.bitfield & Permission.manageGuild) === Permission.manageGuild;\r\n }\r\n public get addReactions(): boolean {\r\n return (\r\n (this.bitfield & Permission.addReactions) === Permission.addReactions\r\n );\r\n }\r\n public get viewAuditLog(): boolean {\r\n return (\r\n (this.bitfield & Permission.viewAuditLog) === Permission.viewAuditLog\r\n );\r\n }\r\n public get prioritySpeaker(): boolean {\r\n return (\r\n (this.bitfield & Permission.prioritySpeaker) ===\r\n Permission.prioritySpeaker\r\n );\r\n }\r\n public get stream(): boolean {\r\n return (this.bitfield & Permission.stream) === Permission.stream;\r\n }\r\n public get viewChannel(): boolean {\r\n return (this.bitfield & Permission.viewChannel) === Permission.viewChannel;\r\n }\r\n public get sendMessages(): boolean {\r\n return (\r\n (this.bitfield & Permission.sendMessages) === Permission.sendMessages\r\n );\r\n }\r\n public get sendTTSMessages(): boolean {\r\n return (\r\n (this.bitfield & Permission.sendTTSMessages) ===\r\n Permission.sendTTSMessages\r\n );\r\n }\r\n public get manageMessages(): boolean {\r\n return (\r\n (this.bitfield & Permission.manageMessages) === Permission.manageMessages\r\n );\r\n }\r\n public get embedLinks(): boolean {\r\n return (this.bitfield & Permission.embedLinks) === Permission.embedLinks;\r\n }\r\n public get attachFiles(): boolean {\r\n return (this.bitfield & Permission.attachFiles) === Permission.attachFiles;\r\n }\r\n public get readMessageHistory(): boolean {\r\n return (\r\n (this.bitfield & Permission.readMessageHistory) ===\r\n Permission.readMessageHistory\r\n );\r\n }\r\n public get mentionEveryone(): boolean {\r\n return (\r\n (this.bitfield & Permission.mentionEveryone) ===\r\n Permission.mentionEveryone\r\n );\r\n }\r\n public get useExternalEmojis(): boolean {\r\n return (\r\n (this.bitfield & Permission.useExternalEmojis) ===\r\n Permission.useExternalEmojis\r\n );\r\n }\r\n public get viewGuildInsights(): boolean {\r\n return (\r\n (this.bitfield & Permission.viewGuildInsights) ===\r\n Permission.viewGuildInsights\r\n );\r\n }\r\n public get connect(): boolean {\r\n return (this.bitfield & Permission.connect) === Permission.connect;\r\n }\r\n public get speak(): boolean {\r\n return (this.bitfield & Permission.speak) === Permission.speak;\r\n }\r\n public get muteMembers(): boolean {\r\n return (this.bitfield & Permission.muteMembers) === Permission.muteMembers;\r\n }\r\n public get deafenMembers(): boolean {\r\n return (\r\n (this.bitfield & Permission.deafenMembers) === Permission.deafenMembers\r\n );\r\n }\r\n public get moveMembers(): boolean {\r\n return (this.bitfield & Permission.moveMembers) === Permission.moveMembers;\r\n }\r\n public get useVAD(): boolean {\r\n return (this.bitfield & Permission.useVAD) === Permission.useVAD;\r\n }\r\n public get changeNickname(): boolean {\r\n return (\r\n (this.bitfield & Permission.changeNickname) === Permission.changeNickname\r\n );\r\n }\r\n public get manageNicknames(): boolean {\r\n return (\r\n (this.bitfield & Permission.manageNicknames) ===\r\n Permission.manageNicknames\r\n );\r\n }\r\n public get manageRoles(): boolean {\r\n return (this.bitfield & Permission.manageRoles) === Permission.manageRoles;\r\n }\r\n public get manageWebhooks(): boolean {\r\n return (\r\n (this.bitfield & Permission.manageWebhooks) === Permission.manageWebhooks\r\n );\r\n }\r\n public get manageGuildExpressions(): boolean {\r\n return (\r\n (this.bitfield & Permission.manageGuildExpressions) ===\r\n Permission.manageGuildExpressions\r\n );\r\n }\r\n public get useApplicationCommands(): boolean {\r\n return (\r\n (this.bitfield & Permission.useApplicationCommands) ===\r\n Permission.useApplicationCommands\r\n );\r\n }\r\n public get requestToSpeak(): boolean {\r\n return (\r\n (this.bitfield & Permission.requestToSpeak) === Permission.requestToSpeak\r\n );\r\n }\r\n public get manageEvents(): boolean {\r\n return (\r\n (this.bitfield & Permission.manageEvents) === Permission.manageEvents\r\n );\r\n }\r\n public get manageThreads(): boolean {\r\n return (\r\n (this.bitfield & Permission.manageThreads) === Permission.manageThreads\r\n );\r\n }\r\n public get createPublicThreads(): boolean {\r\n return (\r\n (this.bitfield & Permission.createPublicThreads) ===\r\n Permission.createPublicThreads\r\n );\r\n }\r\n public get createPrivateThreads(): boolean {\r\n return (\r\n (this.bitfield & Permission.createPrivateThreads) ===\r\n Permission.createPrivateThreads\r\n );\r\n }\r\n public get useExternalStickers(): boolean {\r\n return (\r\n (this.bitfield & Permission.useExternalStickers) ===\r\n Permission.useExternalStickers\r\n );\r\n }\r\n public get sendMessagesInThreads(): boolean {\r\n return (\r\n (this.bitfield & Permission.sendMessagesInThreads) ===\r\n Permission.sendMessagesInThreads\r\n );\r\n }\r\n public get useEmbeddedActivities(): boolean {\r\n return (\r\n (this.bitfield & Permission.useEmbeddedActivities) ===\r\n Permission.useEmbeddedActivities\r\n );\r\n }\r\n public get moderateMembers(): boolean {\r\n return (\r\n (this.bitfield & Permission.moderateMembers) ===\r\n Permission.moderateMembers\r\n );\r\n }\r\n public get viewCreatorMonetizationAnalytics(): boolean {\r\n return (\r\n (this.bitfield & Permission.viewCreatorMonetizationAnalytics) ===\r\n Permission.viewCreatorMonetizationAnalytics\r\n );\r\n }\r\n public get useSoundboard(): boolean {\r\n return (\r\n (this.bitfield & Permission.useSoundboard) === Permission.useSoundboard\r\n );\r\n }\r\n public get createGuildExpressions(): boolean {\r\n return (\r\n (this.bitfield & Permission.createGuildExpressions) ===\r\n Permission.createGuildExpressions\r\n );\r\n }\r\n public get createEvents(): boolean {\r\n return (\r\n (this.bitfield & Permission.createEvents) === Permission.createEvents\r\n );\r\n }\r\n public get useExternalSounds(): boolean {\r\n return (\r\n (this.bitfield & Permission.useExternalSounds) ===\r\n Permission.useExternalSounds\r\n );\r\n }\r\n public get sendVoiceMessages(): boolean {\r\n return (\r\n (this.bitfield & Permission.sendVoiceMessages) ===\r\n Permission.sendVoiceMessages\r\n );\r\n }\r\n public get sendPolls(): boolean {\r\n return (this.bitfield & Permission.sendPolls) === Permission.sendPolls;\r\n }\r\n public get useExternalApps(): boolean {\r\n return (\r\n (this.bitfield & Permission.useExternalApps) ===\r\n Permission.useExternalApps\r\n );\r\n }\r\n\r\n /** Checks whether all supplied permissions are present (AND). @param permissions Permission names or raw bits. @returns True when every requested permission is present. */\r\n public has(...permissions: PermissionResolvable[]): boolean {\r\n if (permissions.length === 1) {\r\n const p = permissions[0]!;\r\n const bit = typeof p === \"bigint\" ? p : this.#resolve(p);\r\n return (this.bitfield & bit) === bit;\r\n }\r\n for (let i = 0; i < permissions.length; i++) {\r\n const p = permissions[i]!;\r\n const bit = typeof p === \"bigint\" ? p : this.#resolve(p);\r\n if ((this.bitfield & bit) !== bit) return false;\r\n }\r\n return true;\r\n }\r\n\r\n /** Checks whether any supplied permission is present (OR). @param permissions Permission names or raw bits. @returns True when at least one requested permission is present. */\r\n public any(...permissions: PermissionResolvable[]): boolean {\r\n if (permissions.length === 1) {\r\n const p = permissions[0]!;\r\n const bit = typeof p === \"bigint\" ? p : this.#resolve(p);\r\n return (this.bitfield & bit) !== 0n;\r\n }\r\n for (let i = 0; i < permissions.length; i++) {\r\n const p = permissions[i]!;\r\n const bit = typeof p === \"bigint\" ? p : this.#resolve(p);\r\n if ((this.bitfield & bit) !== 0n) return true;\r\n }\r\n return false;\r\n }\r\n\r\n /** Returns a new set with permissions added. @param permissions Permission names or raw bits. @returns A new permission set. */\r\n public add(...permissions: PermissionResolvable[]): PermissionSet {\r\n let bitfield = this.bitfield;\r\n for (let i = 0; i < permissions.length; i++) {\r\n const p = permissions[i]!;\r\n bitfield |= typeof p === \"bigint\" ? p : this.#resolve(p);\r\n }\r\n return new PermissionSet(bitfield);\r\n }\r\n\r\n /** Returns a new set with permissions removed. @param permissions Permission names or raw bits. @returns A new permission set. */\r\n public remove(...permissions: PermissionResolvable[]): PermissionSet {\r\n let bitfield = this.bitfield;\r\n for (let i = 0; i < permissions.length; i++) {\r\n const p = permissions[i]!;\r\n bitfield &= ~(typeof p === \"bigint\" ? p : this.#resolve(p));\r\n }\r\n return new PermissionSet(bitfield);\r\n }\r\n\r\n /** Checks equality with another permission set or raw bitfield. @param other Permission set or raw bitfield. @returns True when both values are equal. */\r\n public equals(other: PermissionSet | bigint | number | string): boolean {\r\n return (\r\n this.bitfield ===\r\n (other instanceof PermissionSet\r\n ? other.bitfield\r\n : new PermissionSet(other).bitfield)\r\n );\r\n }\r\n\r\n /** Returns the decimal permission representation. @returns Decimal permission bitfield. */\r\n public toString(): string {\r\n return this.bitfield.toString();\r\n }\r\n\r\n /** Returns known permission names contained in this set. @returns Names of all enabled known permissions. */\r\n public toArray(): PermissionName[] {\r\n return (Object.keys(Permission) as PermissionName[]).filter((permission) =>\r\n this.has(permission),\r\n );\r\n }\r\n\r\n /** Resolves a named permission, enum value, or raw bit. @param permission Permission name, enum value, or raw bit. @returns Numeric permission bit. */\r\n #resolve(permission: PermissionResolvable): bigint {\r\n if (typeof permission === \"bigint\") return permission;\r\n if (typeof permission === \"number\") return BigInt(permission);\r\n if (permission instanceof PermissionSet) return permission.bitfield;\r\n if (Array.isArray(permission)) {\r\n let bit = 0n;\r\n for (let i = 0; i < permission.length; i++)\r\n bit |= this.#resolve(permission[i]!);\r\n return bit;\r\n }\r\n if (typeof permission === \"string\") {\r\n if (permission in Permission)\r\n return (Permission as Record<string, bigint>)[permission]!;\r\n if (permission in Permissions)\r\n return (Permissions as Record<string, bigint>)[permission]!;\r\n if (permission in PermissionFlagsBits)\r\n return BigInt(\r\n (PermissionFlagsBits as Record<string, string>)[permission]!,\r\n );\r\n const lower = permission.charAt(0).toLowerCase() + permission.slice(1);\r\n if (lower in Permission)\r\n return (Permission as Record<string, bigint>)[lower]!;\r\n return BigInt(permission);\r\n }\r\n return 0n;\r\n }\r\n}\r\n\r\n/** Permissions bitfield alias. */\r\nexport class PermissionsBitField extends PermissionSet {\r\n /** Permission flags bits enum. */\r\n public static readonly Flags = PermissionFlagsBits;\r\n /** Permission flags constants. */\r\n public static readonly All = Permission;\r\n\r\n /** Creates a permissions bitfield. @param value Initial permission bitfield or array of permissions. */\r\n public constructor(value: PermissionResolvable = 0n) {\r\n super(value);\r\n }\r\n}\r\n",
|
|
6
|
-
"
|
|
5
|
+
"/** Permission overwrite target types. */\nexport enum PermissionOverwriteType {\n Role = 0,\n Member = 1,\n}\n\n/** Lunibee idiomatic camelCase permission bitflags. */\nexport const Permission = {\n createInstantInvite: 1n << 0n,\n kickMembers: 1n << 1n,\n banMembers: 1n << 2n,\n administrator: 1n << 3n,\n manageChannels: 1n << 4n,\n manageGuild: 1n << 5n,\n addReactions: 1n << 6n,\n viewAuditLog: 1n << 7n,\n prioritySpeaker: 1n << 8n,\n stream: 1n << 9n,\n viewChannel: 1n << 10n,\n sendMessages: 1n << 11n,\n sendTTSMessages: 1n << 12n,\n manageMessages: 1n << 13n,\n embedLinks: 1n << 14n,\n attachFiles: 1n << 15n,\n readMessageHistory: 1n << 16n,\n mentionEveryone: 1n << 17n,\n useExternalEmojis: 1n << 18n,\n viewGuildInsights: 1n << 19n,\n connect: 1n << 20n,\n speak: 1n << 21n,\n muteMembers: 1n << 22n,\n deafenMembers: 1n << 23n,\n moveMembers: 1n << 24n,\n useVAD: 1n << 25n,\n changeNickname: 1n << 26n,\n manageNicknames: 1n << 27n,\n manageRoles: 1n << 28n,\n manageWebhooks: 1n << 29n,\n manageGuildExpressions: 1n << 30n,\n useApplicationCommands: 1n << 31n,\n requestToSpeak: 1n << 32n,\n manageEvents: 1n << 33n,\n manageThreads: 1n << 34n,\n createPublicThreads: 1n << 35n,\n createPrivateThreads: 1n << 36n,\n useExternalStickers: 1n << 37n,\n sendMessagesInThreads: 1n << 38n,\n useEmbeddedActivities: 1n << 39n,\n moderateMembers: 1n << 40n,\n viewCreatorMonetizationAnalytics: 1n << 41n,\n useSoundboard: 1n << 42n,\n createGuildExpressions: 1n << 43n,\n createEvents: 1n << 44n,\n useExternalSounds: 1n << 45n,\n sendVoiceMessages: 1n << 46n,\n sendPolls: 1n << 49n,\n useExternalApps: 1n << 50n,\n} as const;\n\n/** Canonical PascalCase permission constants. */\nexport const Permissions = {\n CreateInstantInvite: 1n << 0n,\n KickMembers: 1n << 1n,\n BanMembers: 1n << 2n,\n Administrator: 1n << 3n,\n ManageChannels: 1n << 4n,\n ManageGuild: 1n << 5n,\n AddReactions: 1n << 6n,\n ViewAuditLog: 1n << 7n,\n PrioritySpeaker: 1n << 8n,\n Stream: 1n << 9n,\n ViewChannel: 1n << 10n,\n SendMessages: 1n << 11n,\n SendTTSMessages: 1n << 12n,\n ManageMessages: 1n << 13n,\n EmbedLinks: 1n << 14n,\n AttachFiles: 1n << 15n,\n ReadMessageHistory: 1n << 16n,\n MentionEveryone: 1n << 17n,\n UseExternalEmojis: 1n << 18n,\n ViewGuildInsights: 1n << 19n,\n Connect: 1n << 20n,\n Speak: 1n << 21n,\n MuteMembers: 1n << 22n,\n DeafenMembers: 1n << 23n,\n MoveMembers: 1n << 24n,\n UseVAD: 1n << 25n,\n ChangeNickname: 1n << 26n,\n ManageNicknames: 1n << 27n,\n ManageRoles: 1n << 28n,\n ManageWebhooks: 1n << 29n,\n ManageGuildExpressions: 1n << 30n,\n UseApplicationCommands: 1n << 31n,\n RequestToSpeak: 1n << 32n,\n ManageEvents: 1n << 33n,\n ManageThreads: 1n << 34n,\n CreatePublicThreads: 1n << 35n,\n CreatePrivateThreads: 1n << 36n,\n UseExternalStickers: 1n << 37n,\n SendMessagesInThreads: 1n << 38n,\n UseEmbeddedActivities: 1n << 39n,\n ModerateMembers: 1n << 40n,\n ViewCreatorMonetizationAnalytics: 1n << 41n,\n UseSoundboard: 1n << 42n,\n CreateGuildExpressions: 1n << 43n,\n CreateEvents: 1n << 44n,\n UseExternalSounds: 1n << 45n,\n SendVoiceMessages: 1n << 46n,\n SendPolls: 1n << 49n,\n UseExternalApps: 1n << 50n,\n} as const;\n\n/** Permission Flags Enum. */\nexport enum PermissionFlagsBits {\n CreateInstantInvite = \"1\",\n KickMembers = \"2\",\n BanMembers = \"4\",\n Administrator = \"8\",\n ManageChannels = \"16\",\n ManageGuild = \"32\",\n AddReactions = \"64\",\n ViewAuditLog = \"128\",\n PrioritySpeaker = \"256\",\n Stream = \"512\",\n ViewChannel = \"1024\",\n SendMessages = \"2048\",\n SendTTSMessages = \"4096\",\n ManageMessages = \"8192\",\n EmbedLinks = \"16384\",\n AttachFiles = \"32768\",\n ReadMessageHistory = \"65536\",\n MentionEveryone = \"131072\",\n UseExternalEmojis = \"262144\",\n ViewGuildInsights = \"524288\",\n Connect = \"1048576\",\n Speak = \"2097152\",\n MuteMembers = \"4194304\",\n DeafenMembers = \"8388608\",\n MoveMembers = \"16777216\",\n UseVAD = \"33554432\",\n ChangeNickname = \"67108864\",\n ManageNicknames = \"134217728\",\n ManageRoles = \"268435456\",\n ManageWebhooks = \"536870912\",\n ManageGuildExpressions = \"1073741824\",\n UseApplicationCommands = \"2147483648\",\n RequestToSpeak = \"4294967296\",\n ManageEvents = \"8589934592\",\n ManageThreads = \"17179869184\",\n CreatePublicThreads = \"34359738368\",\n CreatePrivateThreads = \"68719476736\",\n UseExternalStickers = \"137438953472\",\n SendMessagesInThreads = \"274877906944\",\n UseEmbeddedActivities = \"549755813888\",\n ModerateMembers = \"1099511627776\",\n ViewCreatorMonetizationAnalytics = \"2199023255552\",\n UseSoundboard = \"4398046511104\",\n CreateGuildExpressions = \"8796093022208\",\n CreateEvents = \"17592186044416\",\n UseExternalSounds = \"35184372088832\",\n SendVoiceMessages = \"70368744177664\",\n SendPolls = \"562949953421312\",\n UseExternalApps = \"1125899906842624\",\n}\n\nexport type PermissionName =\n | keyof typeof Permission\n | keyof typeof Permissions\n | keyof typeof PermissionFlagsBits;\n\nexport type PermissionResolvable =\n | bigint\n | number\n | string\n | PermissionName\n | PermissionFlagsBits\n | PermissionSet\n | PermissionResolvable[];\n\n/** Immutable permission bitfield with direct boolean getters. */\nexport class PermissionSet {\n /** Permission bitfield. */\n public readonly bitfield: bigint;\n\n /** Creates a permission set. @param value Initial permission bitfield or array of permissions. @throws {RangeError} If the value is negative. @throws {TypeError} If the value is not a valid integer. */\n public constructor(value: PermissionResolvable = 0n) {\n try {\n if (Array.isArray(value)) {\n let bit = 0n;\n for (const item of value) {\n bit |= this.#resolve(item);\n }\n this.bitfield = bit;\n } else if (value instanceof PermissionSet) {\n this.bitfield = value.bitfield;\n } else {\n const bitfield = this.#resolve(value);\n if (bitfield < 0n)\n throw new RangeError(\"Permission bitfield cannot be negative.\");\n this.bitfield = bitfield;\n }\n } catch (error) {\n if (error instanceof RangeError) throw error;\n throw new TypeError(\n \"Permission bitfield must be a valid non-negative integer.\",\n { cause: error },\n );\n }\n }\n\n // Direct camelCase boolean getters for instant checks (e.g. member.permissions.kickMembers)\n public get createInstantInvite(): boolean {\n return (\n (this.bitfield & Permission.createInstantInvite) ===\n Permission.createInstantInvite\n );\n }\n public get kickMembers(): boolean {\n return (this.bitfield & Permission.kickMembers) === Permission.kickMembers;\n }\n public get banMembers(): boolean {\n return (this.bitfield & Permission.banMembers) === Permission.banMembers;\n }\n public get administrator(): boolean {\n return (\n (this.bitfield & Permission.administrator) === Permission.administrator\n );\n }\n public get manageChannels(): boolean {\n return (\n (this.bitfield & Permission.manageChannels) === Permission.manageChannels\n );\n }\n public get manageGuild(): boolean {\n return (this.bitfield & Permission.manageGuild) === Permission.manageGuild;\n }\n public get addReactions(): boolean {\n return (\n (this.bitfield & Permission.addReactions) === Permission.addReactions\n );\n }\n public get viewAuditLog(): boolean {\n return (\n (this.bitfield & Permission.viewAuditLog) === Permission.viewAuditLog\n );\n }\n public get prioritySpeaker(): boolean {\n return (\n (this.bitfield & Permission.prioritySpeaker) ===\n Permission.prioritySpeaker\n );\n }\n public get stream(): boolean {\n return (this.bitfield & Permission.stream) === Permission.stream;\n }\n public get viewChannel(): boolean {\n return (this.bitfield & Permission.viewChannel) === Permission.viewChannel;\n }\n public get sendMessages(): boolean {\n return (\n (this.bitfield & Permission.sendMessages) === Permission.sendMessages\n );\n }\n public get sendTTSMessages(): boolean {\n return (\n (this.bitfield & Permission.sendTTSMessages) ===\n Permission.sendTTSMessages\n );\n }\n public get manageMessages(): boolean {\n return (\n (this.bitfield & Permission.manageMessages) === Permission.manageMessages\n );\n }\n public get embedLinks(): boolean {\n return (this.bitfield & Permission.embedLinks) === Permission.embedLinks;\n }\n public get attachFiles(): boolean {\n return (this.bitfield & Permission.attachFiles) === Permission.attachFiles;\n }\n public get readMessageHistory(): boolean {\n return (\n (this.bitfield & Permission.readMessageHistory) ===\n Permission.readMessageHistory\n );\n }\n public get mentionEveryone(): boolean {\n return (\n (this.bitfield & Permission.mentionEveryone) ===\n Permission.mentionEveryone\n );\n }\n public get useExternalEmojis(): boolean {\n return (\n (this.bitfield & Permission.useExternalEmojis) ===\n Permission.useExternalEmojis\n );\n }\n public get viewGuildInsights(): boolean {\n return (\n (this.bitfield & Permission.viewGuildInsights) ===\n Permission.viewGuildInsights\n );\n }\n public get connect(): boolean {\n return (this.bitfield & Permission.connect) === Permission.connect;\n }\n public get speak(): boolean {\n return (this.bitfield & Permission.speak) === Permission.speak;\n }\n public get muteMembers(): boolean {\n return (this.bitfield & Permission.muteMembers) === Permission.muteMembers;\n }\n public get deafenMembers(): boolean {\n return (\n (this.bitfield & Permission.deafenMembers) === Permission.deafenMembers\n );\n }\n public get moveMembers(): boolean {\n return (this.bitfield & Permission.moveMembers) === Permission.moveMembers;\n }\n public get useVAD(): boolean {\n return (this.bitfield & Permission.useVAD) === Permission.useVAD;\n }\n public get changeNickname(): boolean {\n return (\n (this.bitfield & Permission.changeNickname) === Permission.changeNickname\n );\n }\n public get manageNicknames(): boolean {\n return (\n (this.bitfield & Permission.manageNicknames) ===\n Permission.manageNicknames\n );\n }\n public get manageRoles(): boolean {\n return (this.bitfield & Permission.manageRoles) === Permission.manageRoles;\n }\n public get manageWebhooks(): boolean {\n return (\n (this.bitfield & Permission.manageWebhooks) === Permission.manageWebhooks\n );\n }\n public get manageGuildExpressions(): boolean {\n return (\n (this.bitfield & Permission.manageGuildExpressions) ===\n Permission.manageGuildExpressions\n );\n }\n public get useApplicationCommands(): boolean {\n return (\n (this.bitfield & Permission.useApplicationCommands) ===\n Permission.useApplicationCommands\n );\n }\n public get requestToSpeak(): boolean {\n return (\n (this.bitfield & Permission.requestToSpeak) === Permission.requestToSpeak\n );\n }\n public get manageEvents(): boolean {\n return (\n (this.bitfield & Permission.manageEvents) === Permission.manageEvents\n );\n }\n public get manageThreads(): boolean {\n return (\n (this.bitfield & Permission.manageThreads) === Permission.manageThreads\n );\n }\n public get createPublicThreads(): boolean {\n return (\n (this.bitfield & Permission.createPublicThreads) ===\n Permission.createPublicThreads\n );\n }\n public get createPrivateThreads(): boolean {\n return (\n (this.bitfield & Permission.createPrivateThreads) ===\n Permission.createPrivateThreads\n );\n }\n public get useExternalStickers(): boolean {\n return (\n (this.bitfield & Permission.useExternalStickers) ===\n Permission.useExternalStickers\n );\n }\n public get sendMessagesInThreads(): boolean {\n return (\n (this.bitfield & Permission.sendMessagesInThreads) ===\n Permission.sendMessagesInThreads\n );\n }\n public get useEmbeddedActivities(): boolean {\n return (\n (this.bitfield & Permission.useEmbeddedActivities) ===\n Permission.useEmbeddedActivities\n );\n }\n public get moderateMembers(): boolean {\n return (\n (this.bitfield & Permission.moderateMembers) ===\n Permission.moderateMembers\n );\n }\n public get viewCreatorMonetizationAnalytics(): boolean {\n return (\n (this.bitfield & Permission.viewCreatorMonetizationAnalytics) ===\n Permission.viewCreatorMonetizationAnalytics\n );\n }\n public get useSoundboard(): boolean {\n return (\n (this.bitfield & Permission.useSoundboard) === Permission.useSoundboard\n );\n }\n public get createGuildExpressions(): boolean {\n return (\n (this.bitfield & Permission.createGuildExpressions) ===\n Permission.createGuildExpressions\n );\n }\n public get createEvents(): boolean {\n return (\n (this.bitfield & Permission.createEvents) === Permission.createEvents\n );\n }\n public get useExternalSounds(): boolean {\n return (\n (this.bitfield & Permission.useExternalSounds) ===\n Permission.useExternalSounds\n );\n }\n public get sendVoiceMessages(): boolean {\n return (\n (this.bitfield & Permission.sendVoiceMessages) ===\n Permission.sendVoiceMessages\n );\n }\n public get sendPolls(): boolean {\n return (this.bitfield & Permission.sendPolls) === Permission.sendPolls;\n }\n public get useExternalApps(): boolean {\n return (\n (this.bitfield & Permission.useExternalApps) ===\n Permission.useExternalApps\n );\n }\n\n /** Checks whether all supplied permissions are present (AND). @param permissions Permission names or raw bits. @returns True when every requested permission is present. */\n public has(...permissions: PermissionResolvable[]): boolean {\n if (permissions.length === 1) {\n const p = permissions[0]!;\n const bit = typeof p === \"bigint\" ? p : this.#resolve(p);\n return (this.bitfield & bit) === bit;\n }\n for (let i = 0; i < permissions.length; i++) {\n const p = permissions[i]!;\n const bit = typeof p === \"bigint\" ? p : this.#resolve(p);\n if ((this.bitfield & bit) !== bit) return false;\n }\n return true;\n }\n\n /** Checks whether any supplied permission is present (OR). @param permissions Permission names or raw bits. @returns True when at least one requested permission is present. */\n public any(...permissions: PermissionResolvable[]): boolean {\n if (permissions.length === 1) {\n const p = permissions[0]!;\n const bit = typeof p === \"bigint\" ? p : this.#resolve(p);\n return (this.bitfield & bit) !== 0n;\n }\n for (let i = 0; i < permissions.length; i++) {\n const p = permissions[i]!;\n const bit = typeof p === \"bigint\" ? p : this.#resolve(p);\n if ((this.bitfield & bit) !== 0n) return true;\n }\n return false;\n }\n\n /** Returns a new set with permissions added. @param permissions Permission names or raw bits. @returns A new permission set. */\n public add(...permissions: PermissionResolvable[]): PermissionSet {\n let bitfield = this.bitfield;\n for (let i = 0; i < permissions.length; i++) {\n const p = permissions[i]!;\n bitfield |= typeof p === \"bigint\" ? p : this.#resolve(p);\n }\n return new PermissionSet(bitfield);\n }\n\n /** Returns a new set with permissions removed. @param permissions Permission names or raw bits. @returns A new permission set. */\n public remove(...permissions: PermissionResolvable[]): PermissionSet {\n let bitfield = this.bitfield;\n for (let i = 0; i < permissions.length; i++) {\n const p = permissions[i]!;\n bitfield &= ~(typeof p === \"bigint\" ? p : this.#resolve(p));\n }\n return new PermissionSet(bitfield);\n }\n\n /** Checks equality with another permission set or raw bitfield. @param other Permission set or raw bitfield. @returns True when both values are equal. */\n public equals(other: PermissionSet | bigint | number | string): boolean {\n return (\n this.bitfield ===\n (other instanceof PermissionSet\n ? other.bitfield\n : new PermissionSet(other).bitfield)\n );\n }\n\n /** Returns the decimal permission representation. @returns Decimal permission bitfield. */\n public toString(): string {\n return this.bitfield.toString();\n }\n\n /** Returns known permission names contained in this set. @returns Names of all enabled known permissions. */\n public toArray(): PermissionName[] {\n return (Object.keys(Permission) as PermissionName[]).filter((permission) =>\n this.has(permission),\n );\n }\n\n /** Resolves a named permission, enum value, or raw bit. @param permission Permission name, enum value, or raw bit. @returns Numeric permission bit. */\n #resolve(permission: PermissionResolvable): bigint {\n if (typeof permission === \"bigint\") return permission;\n if (typeof permission === \"number\") return BigInt(permission);\n if (permission instanceof PermissionSet) return permission.bitfield;\n if (Array.isArray(permission)) {\n let bit = 0n;\n for (let i = 0; i < permission.length; i++)\n bit |= this.#resolve(permission[i]!);\n return bit;\n }\n if (typeof permission === \"string\") {\n if (permission in Permission)\n return (Permission as Record<string, bigint>)[permission]!;\n if (permission in Permissions)\n return (Permissions as Record<string, bigint>)[permission]!;\n if (permission in PermissionFlagsBits)\n return BigInt(\n (PermissionFlagsBits as Record<string, string>)[permission]!,\n );\n const lower = permission.charAt(0).toLowerCase() + permission.slice(1);\n if (lower in Permission)\n return (Permission as Record<string, bigint>)[lower]!;\n return BigInt(permission);\n }\n return 0n;\n }\n}\n\n/** Permissions bitfield alias. */\nexport class PermissionsBitField extends PermissionSet {\n /** Permission flags bits enum. */\n public static readonly Flags = PermissionFlagsBits;\n /** Permission flags constants. */\n public static readonly All = Permission;\n\n /** Creates a permissions bitfield. @param value Initial permission bitfield or array of permissions. */\n public constructor(value: PermissionResolvable = 0n) {\n super(value);\n }\n}\n",
|
|
6
|
+
"// Note: ClientEvents is defined in index.ts to avoid a circular import.\r\n// ClientEventName and ClientListener are re-exported from there.\r\n\r\n/** Names of events emitted by a Lunibee client. */\r\nexport enum ClientEvent {\r\n // ── Lifecycle ──────────────────────────────────────────────────────────────\r\n Ready = \"ready\",\r\n Raw = \"raw\",\r\n Error = \"error\",\r\n Open = \"open\",\r\n Close = \"close\",\r\n // ── Messages ───────────────────────────────────────────────────────────────\r\n MessageCreate = \"messageCreate\",\r\n MessageUpdate = \"messageUpdate\",\r\n MessageDelete = \"messageDelete\",\r\n MessageDeleteBulk = \"messageDeleteBulk\",\r\n // ── Reactions ─────────────────────────────────────────────────────────────\r\n MessageReactionAdd = \"messageReactionAdd\",\r\n MessageReactionRemove = \"messageReactionRemove\",\r\n MessageReactionRemoveAll = \"messageReactionRemoveAll\",\r\n MessageReactionRemoveEmoji = \"messageReactionRemoveEmoji\",\r\n // ── Polls ─────────────────────────────────────────────────────────────────\r\n MessagePollVoteAdd = \"messagePollVoteAdd\",\r\n MessagePollVoteRemove = \"messagePollVoteRemove\",\r\n // ── Guilds ────────────────────────────────────────────────────────────────\r\n GuildCreate = \"guildCreate\",\r\n GuildUpdate = \"guildUpdate\",\r\n GuildDelete = \"guildDelete\",\r\n GuildAvailable = \"guildAvailable\",\r\n GuildUnavailable = \"guildUnavailable\",\r\n // ── Guild Members ──────────────────────────────────────────────────────────\r\n GuildMemberAdd = \"guildMemberAdd\",\r\n GuildMemberUpdate = \"guildMemberUpdate\",\r\n GuildMemberRemove = \"guildMemberRemove\",\r\n GuildMembersChunk = \"guildMembersChunk\",\r\n // ── Guild Bans ────────────────────────────────────────────────────────────\r\n GuildBanAdd = \"guildBanAdd\",\r\n GuildBanRemove = \"guildBanRemove\",\r\n // ── Guild Roles ───────────────────────────────────────────────────────────\r\n GuildRoleCreate = \"guildRoleCreate\",\r\n GuildRoleUpdate = \"guildRoleUpdate\",\r\n GuildRoleDelete = \"guildRoleDelete\",\r\n // ── Guild Emojis & Stickers ───────────────────────────────────────────────\r\n GuildEmojisUpdate = \"guildEmojisUpdate\",\r\n GuildStickersUpdate = \"guildStickersUpdate\",\r\n // ── Guild Integrations ────────────────────────────────────────────────────\r\n GuildIntegrationsUpdate = \"guildIntegrationsUpdate\",\r\n // ── Guild Scheduled Events ────────────────────────────────────────────────\r\n GuildScheduledEventCreate = \"guildScheduledEventCreate\",\r\n GuildScheduledEventUpdate = \"guildScheduledEventUpdate\",\r\n GuildScheduledEventDelete = \"guildScheduledEventDelete\",\r\n GuildScheduledEventUserAdd = \"guildScheduledEventUserAdd\",\r\n GuildScheduledEventUserRemove = \"guildScheduledEventUserRemove\",\r\n // ── AutoMod ───────────────────────────────────────────────────────────────\r\n AutoModerationRuleCreate = \"autoModerationRuleCreate\",\r\n AutoModerationRuleUpdate = \"autoModerationRuleUpdate\",\r\n AutoModerationRuleDelete = \"autoModerationRuleDelete\",\r\n AutoModerationActionExecution = \"autoModerationActionExecution\",\r\n // ── Channels ──────────────────────────────────────────────────────────────\r\n ChannelCreate = \"channelCreate\",\r\n ChannelUpdate = \"channelUpdate\",\r\n ChannelDelete = \"channelDelete\",\r\n ChannelPinsUpdate = \"channelPinsUpdate\",\r\n // ── Threads ───────────────────────────────────────────────────────────────\r\n ThreadCreate = \"threadCreate\",\r\n ThreadUpdate = \"threadUpdate\",\r\n ThreadDelete = \"threadDelete\",\r\n ThreadListSync = \"threadListSync\",\r\n ThreadMembersUpdate = \"threadMembersUpdate\",\r\n ThreadMemberUpdate = \"threadMemberUpdate\",\r\n // ── Stage Instances ───────────────────────────────────────────────────────\r\n StageInstanceCreate = \"stageInstanceCreate\",\r\n StageInstanceUpdate = \"stageInstanceUpdate\",\r\n StageInstanceDelete = \"stageInstanceDelete\",\r\n // ── Invites ───────────────────────────────────────────────────────────────\r\n InviteCreate = \"inviteCreate\",\r\n InviteDelete = \"inviteDelete\",\r\n // ── Webhooks ──────────────────────────────────────────────────────────────\r\n WebhooksUpdate = \"webhooksUpdate\",\r\n // ── Voice ─────────────────────────────────────────────────────────────────\r\n VoiceStateUpdate = \"voiceStateUpdate\",\r\n VoiceServerUpdate = \"voiceServerUpdate\",\r\n // ── Presence & Typing ─────────────────────────────────────────────────────\r\n PresenceUpdate = \"presenceUpdate\",\r\n TypingStart = \"typingStart\",\r\n // ── Interactions ──────────────────────────────────────────────────────────\r\n InteractionCreate = \"interactionCreate\",\r\n}\r\n\r\n/** Names of events emitted by a Lunibee client. */\r\nexport type ClientEventName = keyof import(\"./index.js\").ClientEvents;\r\n\r\n/** Listener signature for a Lunibee client event. */\r\nexport type ClientListener<K extends ClientEventName> = (\r\n ...args: import(\"./index.js\").ClientEvents[K]\r\n) => unknown;\r\n",
|
|
7
|
+
"/** Discord API snowflake identifier. */\r\nexport type Snowflake = string;\r\n\r\n// ─── Gateway Intents ─────────────────────────────────────────────────────────\r\n\r\n/** Gateway intent bit flags supported by Discord (PascalCase). */\r\nexport const GatewayIntentBits = {\r\n Guilds: 1 << 0,\r\n GuildMembers: 1 << 1,\r\n GuildModeration: 1 << 2,\r\n GuildExpressions: 1 << 3,\r\n GuildIntegrations: 1 << 4,\r\n GuildWebhooks: 1 << 5,\r\n GuildInvites: 1 << 6,\r\n GuildVoiceStates: 1 << 7,\r\n GuildPresences: 1 << 8,\r\n GuildMessages: 1 << 9,\r\n GuildMessageReactions: 1 << 10,\r\n GuildMessageTyping: 1 << 11,\r\n DirectMessages: 1 << 12,\r\n DirectMessageReactions: 1 << 13,\r\n DirectMessageTyping: 1 << 14,\r\n MessageContent: 1 << 15,\r\n GuildScheduledEvents: 1 << 16,\r\n AutoModerationConfiguration: 1 << 20,\r\n AutoModerationExecution: 1 << 21,\r\n GuildMessagePolls: 1 << 24,\r\n DirectMessagePolls: 1 << 25,\r\n} as const;\r\n\r\n/** Idiomatic camelCase Gateway intent bit flags supported by Discord. */\r\nexport const IntentBits = {\r\n guild: 1 << 0,\r\n guilds: 1 << 0,\r\n guildMembers: 1 << 1,\r\n guildModeration: 1 << 2,\r\n guildBans: 1 << 2,\r\n guildExpressions: 1 << 3,\r\n guildEmojis: 1 << 3,\r\n guildEmojisAndStickers: 1 << 3,\r\n guildIntegrations: 1 << 4,\r\n guildWebhooks: 1 << 5,\r\n guildInvites: 1 << 6,\r\n guildVoiceStates: 1 << 7,\r\n guildPresences: 1 << 8,\r\n guildMessages: 1 << 9,\r\n guildMessage: 1 << 9,\r\n guildMessageReactions: 1 << 10,\r\n guildMessageTyping: 1 << 11,\r\n directMessages: 1 << 12,\r\n directMessageReactions: 1 << 13,\r\n directMessageTyping: 1 << 14,\r\n messageContent: 1 << 15,\r\n guildScheduledEvents: 1 << 16,\r\n autoModerationConfiguration: 1 << 20,\r\n autoModerationExecution: 1 << 21,\r\n guildMessagePolls: 1 << 24,\r\n directMessagePolls: 1 << 25,\r\n} as const;\r\n\r\n/** Alias for IntentBits. */\r\nexport const Intents = IntentBits;\r\n\r\n/** Gateway intent resolvable value (single bitfield, enum key, or array of bitfields/strings). */\r\nexport type GatewayIntentResolvable =\r\n | number\r\n | keyof typeof GatewayIntentBits\r\n | keyof typeof IntentBits\r\n | (\r\n number | keyof typeof GatewayIntentBits | keyof typeof IntentBits | string\r\n )[];\r\n\r\n/** Resolves any GatewayIntentResolvable into a raw bitfield integer. */\r\nexport function resolveGatewayIntents(\r\n intents: GatewayIntentResolvable,\r\n): number {\r\n if (typeof intents === \"number\") return intents;\r\n if (Array.isArray(intents)) {\r\n return intents.reduce<number>((acc, intent) => {\r\n return acc | resolveGatewayIntents(intent as any);\r\n }, 0);\r\n }\r\n if (typeof intents === \"string\") {\r\n if (intents in GatewayIntentBits)\r\n return (GatewayIntentBits as Record<string, number>)[intents]!;\r\n if (intents in IntentBits)\r\n return (IntentBits as Record<string, number>)[intents]!;\r\n const lower = intents.charAt(0).toLowerCase() + intents.slice(1);\r\n if (lower in IntentBits)\r\n return (IntentBits as Record<string, number>)[lower]!;\r\n const num = Number(intents);\r\n if (!Number.isNaN(num)) return num;\r\n }\r\n return 0;\r\n}\r\n\r\n// ─── Gateway Config ───────────────────────────────────────────────────────────\r\n\r\n/** Gateway connection properties (OS, browser, device). */\r\nexport interface GatewayProperties {\r\n os?: string;\r\n browser?: string;\r\n device?: string;\r\n [key: string]: unknown;\r\n}\r\n/** Gateway presence activity. */\r\nexport interface GatewayPresenceActivity {\r\n name: string;\r\n type?: number;\r\n url?: string;\r\n state?: string;\r\n}\r\n/** Gateway presence data. */\r\nexport interface GatewayPresence {\r\n status?: \"online\" | \"dnd\" | \"idle\" | \"invisible\" | \"offline\";\r\n activities?: GatewayPresenceActivity[];\r\n afk?: boolean;\r\n since?: number | null;\r\n}\r\n/** Client configuration. */\r\nexport interface ClientOptions {\r\n token: string;\r\n intents: GatewayIntentResolvable;\r\n gateway?: GatewayOptions;\r\n rest?: RESTOptions;\r\n}\r\n/** Gateway connection configuration. */\r\nexport interface GatewayOptions {\r\n intents?: GatewayIntentResolvable;\r\n reconnect?: boolean;\r\n maxReconnectAttempts?: number;\r\n reconnectBaseDelay?: number;\r\n reconnectMaxDelay?: number;\r\n shardId?: number;\r\n shardCount?: number;\r\n properties?: GatewayProperties;\r\n presence?: GatewayPresence;\r\n}\r\n\r\n/** REST request configuration. */\r\nexport interface RESTOptions {\r\n timeout?: number;\r\n retries?: number;\r\n baseURL?: string;\r\n}\r\n\r\n// ─── Core Discord Objects ─────────────────────────────────────────────────────\r\n\r\n/** Discord user object. */\r\nexport interface UserData {\r\n id: Snowflake;\r\n username: string;\r\n discriminator?: string;\r\n global_name?: string | null;\r\n avatar?: string | null;\r\n bot?: boolean;\r\n system?: boolean;\r\n public_flags?: number;\r\n}\r\n/** Current authenticated bot user. */\r\nexport type ClientUser = UserData;\r\n/** Discord Gateway payload envelope. */\r\nexport interface GatewayPayload<T = unknown> {\r\n op: number;\r\n d: T | null;\r\n s: number | null;\r\n t: string | null;\r\n}\r\n/** Generic Discord API error payload. */\r\nexport interface APIError {\r\n code?: number;\r\n message?: string;\r\n errors?: Record<string, unknown>;\r\n}\r\n\r\n// ─── Discord Flags & Enums ────────────────────────────────────────────────────\r\n\r\n/** Discord message flags. */\r\nexport const MessageFlags = {\r\n Crossposted: 1,\r\n IsCrosspost: 2,\r\n SuppressEmbeds: 4,\r\n SourceMessageDeleted: 8,\r\n Urgent: 16,\r\n HasThread: 32,\r\n Ephemeral: 64,\r\n Loading: 128,\r\n IsComponentsV2: 32768,\r\n} as const;\r\n\r\n/** Discord channel types. */\r\nexport const ChannelType = {\r\n GuildText: 0,\r\n DM: 1,\r\n GuildVoice: 2,\r\n GroupDM: 3,\r\n GuildCategory: 4,\r\n GuildAnnouncement: 5,\r\n AnnouncementThread: 10,\r\n PublicThread: 11,\r\n PrivateThread: 12,\r\n GuildStageVoice: 13,\r\n GuildDirectory: 14,\r\n GuildForum: 15,\r\n GuildMedia: 16,\r\n} as const;\r\n\r\n/** Discord component types. */\r\nexport const ComponentType = {\r\n ActionRow: 1,\r\n Button: 2,\r\n StringSelect: 3,\r\n TextInput: 4,\r\n UserSelect: 5,\r\n RoleSelect: 6,\r\n MentionableSelect: 7,\r\n ChannelSelect: 8,\r\n Section: 9,\r\n TextDisplay: 10,\r\n Thumbnail: 11,\r\n MediaGallery: 12,\r\n File: 13,\r\n Separator: 14,\r\n ContentInventoryEntry: 16,\r\n Container: 17,\r\n} as const;\r\n\r\n/** Discord button style types. */\r\nexport const ButtonStyle = {\r\n Primary: 1,\r\n Secondary: 2,\r\n Success: 3,\r\n Danger: 4,\r\n Link: 5,\r\n Premium: 6,\r\n} as const;\r\n\r\n/** Discord text input style types. */\r\nexport const TextInputStyle = {\r\n Short: 1,\r\n Paragraph: 2,\r\n} as const;\r\n\r\n/** Discord interaction response types. */\r\nexport const InteractionResponseType = {\r\n Pong: 1,\r\n ChannelMessage: 4,\r\n DeferredChannelMessage: 5,\r\n DeferredMessageUpdate: 6,\r\n MessageUpdate: 7,\r\n Autocomplete: 8,\r\n Modal: 9,\r\n} as const;\r\n\r\n/** Discord sticker format types. */\r\nexport const StickerFormatType = {\r\n PNG: 1,\r\n APNG: 2,\r\n Lottie: 3,\r\n GIF: 4,\r\n} as const;\r\n\r\n/** Discord sticker types. */\r\nexport const StickerType = {\r\n Standard: 1,\r\n Guild: 2,\r\n} as const;\r\n\r\n/** Discord verification levels. */\r\nexport const VerificationLevel = {\r\n None: 0,\r\n Low: 1,\r\n Medium: 2,\r\n High: 3,\r\n VeryHigh: 4,\r\n} as const;\r\n\r\n/** Discord premium tiers. */\r\nexport const PremiumTier = {\r\n None: 0,\r\n Tier1: 1,\r\n Tier2: 2,\r\n Tier3: 3,\r\n} as const;\r\n\r\n// ─── Embeds ───────────────────────────────────────────────────────────────────\r\n\r\n/** Raw Discord embed footer object. */\r\nexport interface APIEmbedFooter {\r\n text: string;\r\n icon_url?: string;\r\n proxy_icon_url?: string;\r\n}\r\n/** Raw Discord embed image/thumbnail/video object. */\r\nexport interface APIEmbedMedia {\r\n url: string;\r\n proxy_url?: string;\r\n height?: number;\r\n width?: number;\r\n}\r\n/** Raw Discord embed provider object. */\r\nexport interface APIEmbedProvider {\r\n name?: string;\r\n url?: string;\r\n}\r\n/** Raw Discord embed author object. */\r\nexport interface APIEmbedAuthor {\r\n name: string;\r\n url?: string;\r\n icon_url?: string;\r\n proxy_icon_url?: string;\r\n}\r\n/** Raw Discord embed field object. */\r\nexport interface APIEmbedField {\r\n name: string;\r\n value: string;\r\n inline?: boolean;\r\n}\r\n/** Raw Discord embed object. */\r\nexport interface APIEmbed {\r\n title?: string;\r\n type?: string;\r\n description?: string;\r\n url?: string;\r\n timestamp?: string;\r\n color?: number;\r\n footer?: APIEmbedFooter;\r\n image?: APIEmbedMedia;\r\n thumbnail?: APIEmbedMedia;\r\n video?: APIEmbedMedia;\r\n provider?: APIEmbedProvider;\r\n author?: APIEmbedAuthor;\r\n fields?: APIEmbedField[];\r\n}\r\n\r\n// ─── Message Components ───────────────────────────────────────────────────────\r\n\r\n/** Raw Discord select menu option. */\r\nexport interface APISelectMenuOption {\r\n label: string;\r\n value: string;\r\n description?: string;\r\n emoji?: APIPartialEmoji;\r\n default?: boolean;\r\n}\r\n/** Raw Discord emoji (partial, as used in components). */\r\nexport interface APIPartialEmoji {\r\n id?: Snowflake | null;\r\n name?: string | null;\r\n animated?: boolean;\r\n}\r\n/** Raw Discord button component. */\r\nexport interface APIButtonComponent {\r\n type: 2;\r\n style: number;\r\n label?: string;\r\n emoji?: APIPartialEmoji;\r\n custom_id?: string;\r\n url?: string;\r\n sku_id?: string;\r\n disabled?: boolean;\r\n}\r\n/** Raw Discord select menu component. */\r\nexport interface APISelectMenuComponent {\r\n type: 3 | 5 | 6 | 7 | 8;\r\n custom_id: string;\r\n options?: APISelectMenuOption[];\r\n channel_types?: number[];\r\n placeholder?: string;\r\n min_values?: number;\r\n max_values?: number;\r\n disabled?: boolean;\r\n}\r\n/** Raw Discord text input component. */\r\nexport interface APITextInputComponent {\r\n type: 4;\r\n custom_id: string;\r\n style: number;\r\n label: string;\r\n min_length?: number;\r\n max_length?: number;\r\n required?: boolean;\r\n value?: string;\r\n placeholder?: string;\r\n}\r\n/** Union of all raw message component types. */\r\nexport type APIMessageActionRowComponent =\r\n APIButtonComponent | APISelectMenuComponent | APITextInputComponent;\r\n/** Raw Discord action row component. */\r\nexport interface APIActionRowComponent {\r\n type: 1;\r\n id?: number;\r\n components: APIMessageActionRowComponent[];\r\n}\r\n/** Union including action rows and V2 components. */\r\nexport type APIMessageComponent = APIActionRowComponent | { type: Exclude<number, 1>; [key: string]: any };\r\n\r\n// ─── Attachments ─────────────────────────────────────────────────────────────\r\n\r\n/** Raw Discord attachment object. */\r\nexport interface APIAttachment {\r\n id: Snowflake;\r\n filename: string;\r\n description?: string | null;\r\n content_type?: string;\r\n size: number;\r\n url: string;\r\n proxy_url: string;\r\n height?: number | null;\r\n width?: number | null;\r\n ephemeral?: boolean;\r\n duration_secs?: number;\r\n waveform?: string;\r\n flags?: number;\r\n}\r\n\r\n// ─── Stickers ────────────────────────────────────────────────────────────────\r\n\r\n/** Compact sticker item as included in messages. */\r\nexport interface APIStickerItem {\r\n id: Snowflake;\r\n name: string;\r\n format_type: number;\r\n}\r\n/** Full Discord sticker object. */\r\nexport interface APISticker {\r\n id: Snowflake;\r\n pack_id?: Snowflake;\r\n name: string;\r\n description?: string | null;\r\n tags?: string;\r\n type: number;\r\n format_type: number;\r\n available?: boolean;\r\n guild_id?: Snowflake;\r\n user?: UserData;\r\n sort_value?: number;\r\n}\r\n\r\n// ─── Messages ────────────────────────────────────────────────────────────────\r\n\r\n/** Raw Discord message reference. */\r\nexport interface APIMessageReference {\r\n type?: number;\r\n message_id?: Snowflake;\r\n channel_id?: Snowflake;\r\n guild_id?: Snowflake;\r\n fail_if_not_exists?: boolean;\r\n}\r\n/** Raw Discord message reaction. */\r\nexport interface APIMessageReaction {\r\n count: number;\r\n count_details?: Record<string, number>;\r\n me?: boolean;\r\n me_burst?: boolean;\r\n emoji: APIPartialEmoji;\r\n burst_colors?: string[];\r\n}\r\n/** Raw Discord message object. */\r\nexport interface APIMessage {\r\n id: Snowflake;\r\n channel_id: Snowflake;\r\n author: UserData;\r\n content: string;\r\n timestamp?: string;\r\n edited_timestamp?: string | null;\r\n tts?: boolean;\r\n mention_everyone?: boolean;\r\n mentions?: UserData[];\r\n mention_roles?: Snowflake[];\r\n mention_channels?: Array<Record<string, unknown>>;\r\n attachments?: APIAttachment[];\r\n embeds?: APIEmbed[];\r\n reactions?: APIMessageReaction[];\r\n nonce?: string | number | null;\r\n pinned?: boolean;\r\n webhook_id?: Snowflake;\r\n type?: number;\r\n activity?: Record<string, unknown>;\r\n application?: Record<string, unknown>;\r\n application_id?: Snowflake;\r\n message_reference?: APIMessageReference;\r\n flags?: number;\r\n referenced_message?: APIMessage | null;\r\n interaction_metadata?: Record<string, unknown>;\r\n thread?: Record<string, unknown>;\r\n components?: APIMessageComponent[];\r\n sticker_items?: APIStickerItem[];\r\n stickers?: APISticker[];\r\n position?: number;\r\n role_subscription_data?: Record<string, unknown>;\r\n purchase_notification?: Record<string, unknown>;\r\n poll?: Record<string, unknown>;\r\n guild_id?: Snowflake;\r\n}\r\n\r\n// ─── Channels ────────────────────────────────────────────────────────────────\r\n\r\n/** Raw Discord channel object. */\r\nexport interface APIChannel {\r\n id: Snowflake;\r\n type: number;\r\n guild_id?: Snowflake;\r\n position?: number;\r\n permission_overwrites?: Array<Record<string, unknown>>;\r\n name?: string | null;\r\n topic?: string | null;\r\n nsfw?: boolean;\r\n last_message_id?: Snowflake | null;\r\n bitrate?: number;\r\n user_limit?: number;\r\n rate_limit_per_user?: number;\r\n recipients?: UserData[];\r\n icon?: string | null;\r\n owner_id?: Snowflake;\r\n application_id?: Snowflake;\r\n parent_id?: Snowflake | null;\r\n last_pin_timestamp?: string | null;\r\n rtc_region?: string | null;\r\n video_quality_mode?: number;\r\n message_count?: number;\r\n member_count?: number;\r\n thread_metadata?: APIThreadMetadata;\r\n default_auto_archive_duration?: number;\r\n flags?: number;\r\n total_message_sent?: number;\r\n available_tags?: APIForumTag[];\r\n default_reaction_emoji?: APIPartialEmoji | null;\r\n default_thread_rate_limit_per_user?: number;\r\n default_sort_order?: number | null;\r\n default_forum_layout?: number;\r\n}\r\n\r\n/** Raw Discord thread metadata. */\r\nexport interface APIThreadMetadata {\r\n archived: boolean;\r\n auto_archive_duration: number;\r\n archive_timestamp: string;\r\n locked: boolean;\r\n invitable?: boolean;\r\n create_timestamp?: string | null;\r\n}\r\n\r\n/** Raw Discord forum tag. */\r\nexport interface APIForumTag {\r\n id: Snowflake;\r\n name: string;\r\n moderated: boolean;\r\n emoji_id?: Snowflake | null;\r\n emoji_name?: string | null;\r\n}\r\n\r\n/** Raw Discord thread member. */\r\nexport interface APIThreadMember {\r\n id?: Snowflake;\r\n user_id?: Snowflake;\r\n join_timestamp: string;\r\n flags: number;\r\n member?: APIGuildMember;\r\n}\r\n\r\n// ─── Roles ────────────────────────────────────────────────────────────────────\r\n\r\n/** Raw Discord role object. */\r\nexport interface APIRole {\r\n id: Snowflake;\r\n name: string;\r\n color: number;\r\n hoist: boolean;\r\n icon?: string | null;\r\n unicode_emoji?: string | null;\r\n position: number;\r\n permissions: string;\r\n managed: boolean;\r\n mentionable: boolean;\r\n tags?: Record<string, unknown>;\r\n flags?: number;\r\n}\r\n\r\n// ─── Emoji ────────────────────────────────────────────────────────────────────\r\n\r\n/** Raw Discord emoji object. */\r\nexport interface APIEmoji {\r\n id: Snowflake | null;\r\n name: string | null;\r\n roles?: Snowflake[];\r\n user?: UserData;\r\n require_colons?: boolean;\r\n managed?: boolean;\r\n animated?: boolean;\r\n available?: boolean;\r\n}\r\n\r\n// ─── Guilds ───────────────────────────────────────────────────────────────────\r\n\r\n/** Raw Discord guild object. */\r\nexport interface APIGuild {\r\n id: Snowflake;\r\n name: string;\r\n icon?: string | null;\r\n icon_hash?: string | null;\r\n splash?: string | null;\r\n discovery_splash?: string | null;\r\n owner?: boolean;\r\n owner_id?: Snowflake;\r\n permissions?: string;\r\n afk_channel_id?: Snowflake | null;\r\n afk_timeout?: number;\r\n widget_enabled?: boolean;\r\n widget_channel_id?: Snowflake | null;\r\n verification_level?: number;\r\n default_message_notifications?: number;\r\n explicit_content_filter?: number;\r\n roles?: APIRole[];\r\n emojis?: APIEmoji[];\r\n stickers?: APISticker[];\r\n features?: string[];\r\n mfa_level?: number;\r\n application_id?: Snowflake | null;\r\n system_channel_id?: Snowflake | null;\r\n system_channel_flags?: number;\r\n rules_channel_id?: Snowflake | null;\r\n max_presences?: number | null;\r\n max_members?: number;\r\n vanity_url_code?: string | null;\r\n description?: string | null;\r\n banner?: string | null;\r\n premium_tier?: number;\r\n premium_subscription_count?: number;\r\n preferred_locale?: string;\r\n public_updates_channel_id?: Snowflake | null;\r\n max_video_channel_users?: number;\r\n approximate_member_count?: number;\r\n approximate_presence_count?: number;\r\n nsfw_level?: number;\r\n safety_alerts_channel_id?: Snowflake | null;\r\n member_count?: number;\r\n}\r\n\r\n/** Raw Discord guild member object. */\r\nexport interface APIGuildMember {\r\n user: UserData;\r\n nick?: string | null;\r\n avatar?: string | null;\r\n roles: Snowflake[];\r\n joined_at: string;\r\n premium_since?: string | null;\r\n deaf?: boolean;\r\n mute?: boolean;\r\n flags?: number;\r\n pending?: boolean;\r\n permissions?: string;\r\n communication_disabled_until?: string | null;\r\n guild_id?: Snowflake;\r\n}\r\n\r\n// ─── Voice ────────────────────────────────────────────────────────────────────\r\n\r\n/** Raw Discord voice state object. */\r\nexport interface APIVoiceState {\r\n guild_id?: Snowflake;\r\n channel_id?: Snowflake | null;\r\n user_id: Snowflake;\r\n member?: APIGuildMember;\r\n session_id: string;\r\n deaf: boolean;\r\n mute: boolean;\r\n self_deaf: boolean;\r\n self_mute: boolean;\r\n self_stream?: boolean;\r\n self_video: boolean;\r\n suppress: boolean;\r\n request_to_speak_timestamp?: string | null;\r\n}\r\n\r\n/** Raw Discord voice server update event. */\r\nexport interface APIVoiceServerUpdate {\r\n token: string;\r\n guild_id: Snowflake;\r\n endpoint?: string | null;\r\n}\r\n\r\n// ─── Presence ────────────────────────────────────────────────────────────────\r\n\r\n/** Raw Discord activity object. */\r\nexport interface APIActivity {\r\n name: string;\r\n type: number;\r\n url?: string | null;\r\n created_at: number;\r\n state?: string | null;\r\n details?: string | null;\r\n emoji?: APIPartialEmoji | null;\r\n}\r\n\r\n/** Raw Discord presence update event. */\r\nexport interface APIPresenceUpdate {\r\n user: { id: Snowflake } & Partial<UserData>;\r\n guild_id: Snowflake;\r\n status: string;\r\n activities: APIActivity[];\r\n client_status: { desktop?: string; mobile?: string; web?: string };\r\n}\r\n\r\n// ─── Typing ───────────────────────────────────────────────────────────────────\r\n\r\n/** Raw Discord typing start event. */\r\nexport interface APITypingStart {\r\n channel_id: Snowflake;\r\n guild_id?: Snowflake;\r\n user_id: Snowflake;\r\n timestamp: number;\r\n member?: APIGuildMember;\r\n}\r\n\r\n// ─── Guilds ──────────────────────────────────────────────────────────────────\r\n\r\n/** Raw Discord guild preview. */\r\nexport interface APIGuildPreview {\r\n id: Snowflake;\r\n name: string;\r\n icon: string | null;\r\n splash: string | null;\r\n discovery_splash: string | null;\r\n emojis: unknown[];\r\n features: string[];\r\n approximate_member_count: number;\r\n approximate_presence_count: number;\r\n description: string | null;\r\n stickers: unknown[];\r\n}\r\n\r\n// ─── Invites ─────────────────────────────────────────────────────────────────\r\n\r\n/** Raw Discord invite. */\r\nexport interface APIInvite {\r\n code: string;\r\n guild?: Partial<APIGuild>;\r\n channel: Partial<APIChannel>;\r\n inviter?: UserData;\r\n target_type?: number;\r\n target_user?: UserData;\r\n approximate_presence_count?: number;\r\n approximate_member_count?: number;\r\n}\r\n\r\n/** Raw Discord invite create event. */\r\nexport interface APIInviteCreate {\r\n channel_id: Snowflake;\r\n code: string;\r\n created_at: string;\r\n guild_id?: Snowflake;\r\n inviter?: UserData;\r\n max_age: number;\r\n max_uses: number;\r\n target_type?: number;\r\n target_user?: UserData;\r\n temporary: boolean;\r\n uses: number;\r\n}\r\n\r\n/** Raw Discord invite delete event. */\r\nexport interface APIInviteDelete {\r\n channel_id: Snowflake;\r\n guild_id?: Snowflake;\r\n code: string;\r\n}\r\n\r\n// ─── Webhooks ────────────────────────────────────────────────────────────────\r\n\r\n/** Raw Discord webhooks update event. */\r\nexport interface APIWebhooksUpdate {\r\n guild_id: Snowflake;\r\n channel_id: Snowflake;\r\n}\r\n\r\n/** Raw Discord webhook object. */\r\nexport interface APIWebhook {\r\n id: Snowflake;\r\n type: number;\r\n guild_id?: Snowflake | null;\r\n channel_id?: Snowflake | null;\r\n user?: UserData;\r\n name?: string | null;\r\n avatar?: string | null;\r\n token?: string;\r\n application_id?: Snowflake | null;\r\n url?: string;\r\n}\r\n\r\n// ─── AutoMod ─────────────────────────────────────────────────────────────────\r\n\r\n/** Raw Discord AutoMod action. */\r\nexport interface APIAutoModerationAction {\r\n type: number;\r\n metadata?: {\r\n channel_id?: Snowflake;\r\n duration_seconds?: number;\r\n custom_message?: string;\r\n };\r\n}\r\n\r\n/** Raw Discord AutoMod rule object. */\r\nexport interface APIAutoModerationRule {\r\n id: Snowflake;\r\n guild_id: Snowflake;\r\n name: string;\r\n creator_id: Snowflake;\r\n event_type: number;\r\n trigger_type: number;\r\n trigger_metadata: Record<string, unknown>;\r\n actions: APIAutoModerationAction[];\r\n enabled: boolean;\r\n exempt_roles: Snowflake[];\r\n exempt_channels: Snowflake[];\r\n}\r\n\r\n/** Raw Discord AutoMod action execution event. */\r\nexport interface APIAutoModerationActionExecution {\r\n guild_id: Snowflake;\r\n action: APIAutoModerationAction;\r\n rule_id: Snowflake;\r\n rule_trigger_type: number;\r\n user_id: Snowflake;\r\n channel_id?: Snowflake;\r\n message_id?: Snowflake;\r\n alert_system_message_id?: Snowflake;\r\n content: string;\r\n matched_keyword?: string | null;\r\n matched_content?: string | null;\r\n}\r\n\r\n// ─── Scheduled Events ─────────────────────────────────────────────────────────\r\n\r\n/** Raw Discord guild scheduled event entity metadata. */\r\nexport interface APIGuildScheduledEventEntityMetadata {\r\n location?: string;\r\n}\r\n\r\n/** Raw Discord guild scheduled event object. */\r\nexport interface APIGuildScheduledEvent {\r\n id: Snowflake;\r\n guild_id: Snowflake;\r\n channel_id?: Snowflake | null;\r\n creator_id?: Snowflake | null;\r\n name: string;\r\n description?: string | null;\r\n scheduled_start_time: string;\r\n scheduled_end_time?: string | null;\r\n privacy_level: number;\r\n status: number;\r\n entity_type: number;\r\n entity_id?: Snowflake | null;\r\n entity_metadata?: APIGuildScheduledEventEntityMetadata | null;\r\n creator?: UserData;\r\n user_count?: number;\r\n image?: string | null;\r\n}\r\n\r\n// ─── Stage Instances ─────────────────────────────────────────────────────────\r\n\r\n/** Raw Discord stage instance object. */\r\nexport interface APIStageInstance {\r\n id: Snowflake;\r\n guild_id: Snowflake;\r\n channel_id: Snowflake;\r\n topic: string;\r\n privacy_level: number;\r\n discoverable_disabled?: boolean;\r\n guild_scheduled_event_id?: Snowflake | null;\r\n}\r\n\r\n// ─── Application Commands ─────────────────────────────────────────────────────\r\n\r\n/** Discord application command option types. */\r\nexport const ApplicationCommandOptionType = {\r\n SubCommand: 1,\r\n SubCommandGroup: 2,\r\n String: 3,\r\n Integer: 4,\r\n Boolean: 5,\r\n User: 6,\r\n Channel: 7,\r\n Role: 8,\r\n Mentionable: 9,\r\n Number: 10,\r\n Attachment: 11,\r\n} as const;\r\n\r\n/** Discord application command types. */\r\nexport const ApplicationCommandType = {\r\n ChatInput: 1,\r\n User: 2,\r\n Message: 3,\r\n} as const;\r\n\r\n/** Raw Discord application command option. */\r\nexport interface APIApplicationCommandOption {\r\n type: number;\r\n name: string;\r\n description: string;\r\n required?: boolean;\r\n choices?: Array<{ name: string; value: string | number }>;\r\n options?: APIApplicationCommandOption[];\r\n min_value?: number;\r\n max_value?: number;\r\n min_length?: number;\r\n max_length?: number;\r\n autocomplete?: boolean;\r\n channel_types?: number[];\r\n}\r\n\r\n/** Raw Discord application command object (from API). */\r\nexport interface APIApplicationCommand {\r\n id: Snowflake;\r\n type?: number;\r\n application_id: Snowflake;\r\n guild_id?: Snowflake;\r\n name: string;\r\n description: string;\r\n options?: APIApplicationCommandOption[];\r\n default_member_permissions?: string | null;\r\n dm_permission?: boolean;\r\n nsfw?: boolean;\r\n version: Snowflake;\r\n}\r\n\r\n/** Data for creating/overwriting an application command. */\r\nexport interface ApplicationCommandData {\r\n name: string;\r\n description: string;\r\n type?: number;\r\n options?: APIApplicationCommandOption[];\r\n default_member_permissions?: string | null;\r\n dm_permission?: boolean;\r\n nsfw?: boolean;\r\n}\r\n\r\n// ─── Gateway Events ───────────────────────────────────────────────────────────\r\n\r\n/** Raw Discord READY event payload. */\r\nexport interface APIReadyEvent {\r\n v: number;\r\n user: UserData;\r\n guilds: Array<{ id: Snowflake; unavailable?: boolean }>;\r\n session_id: string;\r\n resume_gateway_url: string;\r\n shard?: [number, number];\r\n application?: { id: Snowflake; flags: number; [key: string]: unknown };\r\n}\r\n\r\n/** Raw Discord reaction event payload. */\r\nexport interface APIMessageReactionEvent {\r\n user_id: Snowflake;\r\n channel_id: Snowflake;\r\n message_id: Snowflake;\r\n guild_id?: Snowflake;\r\n member?: APIGuildMember;\r\n emoji: APIPartialEmoji;\r\n message_author_id?: Snowflake;\r\n burst?: boolean;\r\n type?: number;\r\n}\r\n\r\n/** Raw Discord reaction remove emoji event payload. */\r\nexport interface APIMessageReactionRemoveEmojiEvent {\r\n channel_id: Snowflake;\r\n guild_id?: Snowflake;\r\n message_id: Snowflake;\r\n emoji: APIPartialEmoji;\r\n}\r\n\r\n/** Raw Discord message deletion event payload. */\r\nexport interface APIMessageDeleteEvent {\r\n id: Snowflake;\r\n channel_id: Snowflake;\r\n guild_id?: Snowflake;\r\n}\r\n\r\n/** Raw Discord bulk message deletion event payload. */\r\nexport interface APIMessageDeleteBulkEvent {\r\n ids: Snowflake[];\r\n channel_id: Snowflake;\r\n guild_id?: Snowflake;\r\n}\r\n\r\n/** Raw Discord channel deletion event payload. */\r\nexport interface APIChannelDeleteEvent extends APIChannel {}\r\n\r\n/** Raw Discord guild deletion event payload. */\r\nexport interface APIGuildDeleteEvent {\r\n id: Snowflake;\r\n unavailable?: boolean;\r\n}\r\n\r\n/** Raw Discord thread lifecycle payload. */\r\nexport interface APIThreadEvent extends APIChannel {\r\n guild_id: Snowflake;\r\n member?: APIThreadMember;\r\n}\r\n\r\n/** Raw Discord thread list sync event. */\r\nexport interface APIThreadListSync {\r\n guild_id: Snowflake;\r\n channel_ids?: Snowflake[];\r\n threads: APIChannel[];\r\n members: APIThreadMember[];\r\n}\r\n\r\n/** Raw Discord thread members update event. */\r\nexport interface APIThreadMembersUpdate {\r\n id: Snowflake;\r\n guild_id: Snowflake;\r\n member_count: number;\r\n added_members?: APIThreadMember[];\r\n removed_member_ids?: Snowflake[];\r\n}\r\n\r\n/** Raw Discord guild role event payload. */\r\nexport interface APIGuildRoleEvent {\r\n guild_id: Snowflake;\r\n role: APIRole;\r\n}\r\n\r\n/** Raw Discord guild role delete event payload. */\r\nexport interface APIGuildRoleDeleteEvent {\r\n guild_id: Snowflake;\r\n role_id: Snowflake;\r\n}\r\n\r\n/** Raw Discord guild ban event payload. */\r\nexport interface APIGuildBanEvent {\r\n guild_id: Snowflake;\r\n user: UserData;\r\n}\r\n\r\n/** Raw Discord guild emojis update event payload. */\r\nexport interface APIGuildEmojisUpdateEvent {\r\n guild_id: Snowflake;\r\n emojis: APIEmoji[];\r\n}\r\n\r\n/** Raw Discord guild stickers update event payload. */\r\nexport interface APIGuildStickersUpdateEvent {\r\n guild_id: Snowflake;\r\n stickers: APISticker[];\r\n}\r\n\r\n/** Raw Discord channel pins update event. */\r\nexport interface APIChannelPinsUpdate {\r\n guild_id?: Snowflake;\r\n channel_id: Snowflake;\r\n last_pin_timestamp?: string | null;\r\n}\r\n\r\n/** Raw Discord guild members chunk event. */\r\nexport interface APIGuildMembersChunk {\r\n guild_id: Snowflake;\r\n members: APIGuildMember[];\r\n chunk_index: number;\r\n chunk_count: number;\r\n not_found?: Snowflake[];\r\n presences?: APIPresenceUpdate[];\r\n nonce?: string;\r\n}\r\n\r\n/** Raw Discord guild scheduled event user add/remove event. */\r\nexport interface APIGuildScheduledEventUserEvent {\r\n guild_scheduled_event_id: Snowflake;\r\n user_id: Snowflake;\r\n guild_id: Snowflake;\r\n}\r\n\r\n/** Raw Discord message poll vote add/remove event. */\r\nexport interface APIMessagePollVoteEvent {\r\n user_id: Snowflake;\r\n channel_id: Snowflake;\r\n message_id: Snowflake;\r\n guild_id?: Snowflake;\r\n answer_id: number;\r\n}\r\n",
|
|
8
|
+
"/** A lightweight keyed collection for Lunibee resource and application state. */\r\nexport class Collection<K, V> extends Map<K, V> {\r\n /** Returns the first stored value. */\r\n public first(): V | undefined {\r\n for (const value of this.values()) return value;\r\n return undefined;\r\n }\r\n /** Returns the first stored key. */\r\n public firstKey(): K | undefined {\r\n for (const key of this.keys()) return key;\r\n return undefined;\r\n }\r\n /** Returns the last stored value. */\r\n public last(): V | undefined {\r\n let value: V | undefined;\r\n for (const item of this.values()) value = item;\r\n return value;\r\n }\r\n /** Returns the last stored key. */\r\n public lastKey(): K | undefined {\r\n let key: K | undefined;\r\n for (const item of this.keys()) key = item;\r\n return key;\r\n }\r\n /** Finds the first value matching a predicate. */\r\n public find(\r\n predicate: (value: V, key: K, collection: this) => boolean,\r\n ): V | undefined {\r\n for (const [key, value] of this) {\r\n if (predicate(value, key, this)) return value;\r\n }\r\n return undefined;\r\n }\r\n /** Returns all values matching a predicate. */\r\n public filter(\r\n predicate: (value: V, key: K, collection: this) => boolean,\r\n ): Collection<K, V> {\r\n const result = new Collection<K, V>();\r\n for (const [key, value] of this) {\r\n if (predicate(value, key, this)) result.set(key, value);\r\n }\r\n return result;\r\n }\r\n /** Transforms every stored value into an array. */\r\n public map<T>(transform: (value: V, key: K, collection: this) => T): T[] {\r\n const result: T[] = [];\r\n for (const [key, value] of this) {\r\n result.push(transform(value, key, this));\r\n }\r\n return result;\r\n }\r\n /** Returns whether at least one stored value satisfies a predicate. */\r\n public some(\r\n predicate: (value: V, key: K, collection: this) => boolean,\r\n ): boolean {\r\n for (const [key, value] of this) {\r\n if (predicate(value, key, this)) return true;\r\n }\r\n return false;\r\n }\r\n /** Returns whether every stored value satisfies a predicate. */\r\n public every(\r\n predicate: (value: V, key: K, collection: this) => boolean,\r\n ): boolean {\r\n for (const [key, value] of this) {\r\n if (!predicate(value, key, this)) return false;\r\n }\r\n return true;\r\n }\r\n /** Runs a callback for each stored value. */\r\n public each(callback: (value: V, key: K, collection: this) => unknown): this {\r\n for (const [key, value] of this) {\r\n callback(value, key, this);\r\n }\r\n return this;\r\n }\r\n /** Returns an array containing all stored values. */\r\n public array(): V[] {\r\n return [...this.values()];\r\n }\r\n /** Returns an array containing all stored keys. */\r\n public keyArray(): K[] {\r\n return [...this.keys()];\r\n }\r\n /** Returns a plain array of entries. */\r\n public entriesArray(): [K, V][] {\r\n return [...this.entries()];\r\n }\r\n /** Returns a new collection with the same entries. */\r\n public clone(): Collection<K, V> {\r\n const copy = new Collection<K, V>();\r\n for (const [key, value] of this) copy.set(key, value);\r\n return copy;\r\n }\r\n /** Returns whether all supplied keys are present. */\r\n public hasAll(...keys: K[]): boolean {\r\n for (let i = 0; i < keys.length; i++) {\r\n if (!this.has(keys[i]!)) return false;\r\n }\r\n return true;\r\n }\r\n /** Returns whether at least one supplied key is present. */\r\n public hasAny(...keys: K[]): boolean {\r\n for (let i = 0; i < keys.length; i++) {\r\n if (this.has(keys[i]!)) return true;\r\n }\r\n return false;\r\n }\r\n /** Returns the first key whose value matches a predicate. */\r\n public findKey(\r\n predicate: (value: V, key: K, collection: this) => boolean,\r\n ): K | undefined {\r\n for (const [key, value] of this) {\r\n if (predicate(value, key, this)) return key;\r\n }\r\n return undefined;\r\n }\r\n /** Returns whether a predicate matches at least one entry. */\r\n public someEntry(\r\n predicate: (value: V, key: K, collection: this) => boolean,\r\n ): boolean {\r\n return this.some(predicate);\r\n }\r\n /** Removes every entry matching a predicate and returns the number removed. */\r\n public sweep(\r\n predicate: (value: V, key: K, collection: this) => boolean,\r\n ): number {\r\n let removed = 0;\r\n for (const [key, value] of this) {\r\n if (predicate(value, key, this) && this.delete(key)) removed++;\r\n }\r\n return removed;\r\n }\r\n /** Returns the collection's first matching entry as a tuple. */\r\n public firstEntry(): [K, V] | undefined {\r\n for (const [key, value] of this) return [key, value];\r\n return undefined;\r\n }\r\n /** Returns the collection's last matching entry as a tuple. */\r\n public lastEntry(): [K, V] | undefined {\r\n let entry: [K, V] | undefined;\r\n for (const item of this) entry = [item[0], item[1]];\r\n return entry;\r\n }\r\n /** Returns a new Collection containing elements from both collections. */\r\n public union(other: Collection<K, V>): Collection<K, V> {\r\n const result = this.clone();\r\n for (const [key, value] of other) result.set(key, value);\r\n return result;\r\n }\r\n /** Returns a new Collection containing only elements present in both collections. */\r\n public intersection(other: Collection<K, V>): Collection<K, V> {\r\n const result = new Collection<K, V>();\r\n for (const [key, value] of this) {\r\n if (other.has(key)) result.set(key, value);\r\n }\r\n return result;\r\n }\r\n /** Returns a new Collection containing elements present in this collection but not the other. */\r\n public difference(other: Collection<K, V>): Collection<K, V> {\r\n const result = new Collection<K, V>();\r\n for (const [key, value] of this) {\r\n if (!other.has(key)) result.set(key, value);\r\n }\r\n return result;\r\n }\r\n}\r\n\r\nexport { Cache } from \"./cache.js\";\r\nexport type { CacheOptions } from \"./cache.js\";\r\n",
|
|
7
9
|
"import { Collection } from \"@lunibee/collection\";\n\n/** Generic cache manager. @typeParam K Cache key type. @typeParam V Cached value type. */\nexport class Manager<K, V> {\n /** Cached resources. */ public readonly cache = new Collection<K, V>();\n /** Gets a cached value. @param id Cache key. @returns Cached value. */ public get(\n id: K,\n ): V | undefined {\n return this.cache.get(id);\n }\n /** Checks whether a value is cached. @param id Cache key. @returns True when cached. */ public has(\n id: K,\n ): boolean {\n return this.cache.has(id);\n }\n /** Stores a value. @param id Cache key. @param value Value. @returns This manager. */ public set(\n id: K,\n value: V,\n ): this {\n this.cache.set(id, value);\n return this;\n }\n /** Deletes a cached value. @param id Cache key. @returns True when deleted. */ public delete(\n id: K,\n ): boolean {\n return this.cache.delete(id);\n }\n /** Clears the cache. @returns Nothing. */ public clear(): void {\n this.cache.clear();\n }\n /** Gets cache size. @returns Number of cached values. */ public get size(): number {\n return this.cache.size;\n }\n /** Gets the first cached value. @returns First value. */ public first():\n V | undefined {\n return this.cache.first();\n }\n /** Returns cached values. @returns Array of values. */ public values(): V[] {\n return this.cache.array();\n }\n /** Finds a cached value. @param predicate Predicate. @returns Matching value. */ public find(\n predicate: (value: V, key: K) => boolean,\n ): V | undefined {\n return this.cache.find(predicate);\n }\n /** Iterates cached entries. @returns Cache iterator. */ public [Symbol.iterator](): IterableIterator<\n [K, V]\n > {\n return this.cache[Symbol.iterator]();\n }\n}\n\n/** Generic REST-backed resource manager. @typeParam K Resource key type. @typeParam V Resource type. */\nexport class ResourceManager<K, V> extends Manager<K, V> {\n readonly #fetcher: (id: K) => Promise<V>;\n readonly #key: (value: V) => K;\n\n public constructor(fetcher: (id: K) => Promise<V>, key: (value: V) => K) {\n super();\n if (typeof fetcher !== \"function\" || typeof key !== \"function\")\n throw new TypeError(\n \"ResourceManager requires fetcher and key functions.\",\n );\n this.#fetcher = fetcher;\n this.#key = key;\n }\n\n public async resolve(id: K): Promise<V> {\n return this.get(id) ?? this.fetch(id);\n }\n\n public async fetch(id: K): Promise<V> {\n const resource = await this.#fetcher(id);\n this.set(id, resource);\n return resource;\n }\n\n public async fetchMany(ids: Iterable<K>): Promise<V[]> {\n return Promise.all([...ids].map((id) => this.resolve(id)));\n }\n\n public upsert(resource: V): V {\n const key = this.#key(resource);\n this.set(key, resource);\n return resource;\n }\n\n public update(resource: V): V {\n return this.upsert(resource);\n }\n}\n",
|
|
8
|
-
"/** Discord REST API route definitions. */\r\nexport const Routes = {\r\n /** Returns the current bot user. @returns User route. */ user: () =>\r\n \"/users/@me\",\r\n /** Returns one user. @param userId User identifier. @returns User route. */ userById:\r\n (userId: string) => `/users/${snowflake(userId, \"User ID\")}`,\r\n /** Returns a guild. @param guildId Guild identifier. @returns Guild route. */ guild:\r\n (guildId: string) => `/guilds/${snowflake(guildId, \"Guild ID\")}`,\r\n /** Returns channels in a guild. @param guildId Guild identifier. @returns Channel collection route. */ guildChannels:\r\n (guildId: string) => `/guilds/${snowflake(guildId, \"Guild ID\")}/channels`,\r\n /** Returns a guild member. @param guildId Guild identifier. @param userId User identifier. @returns Guild-member route. */ guildMember:\r\n (guildId: string, userId: string) =>\r\n `/guilds/${snowflake(guildId, \"Guild ID\")}/members/${snowflake(userId, \"User ID\")}`,\r\n /** Returns all guild roles. @param guildId Guild identifier. @returns Guild-role route. */ guildRoles:\r\n (guildId: string) => `/guilds/${snowflake(guildId, \"Guild ID\")}/roles`,\r\n /** Returns an individual guild role. */ guildRole: (\r\n guildId: string,\r\n roleId: string,\r\n ) =>\r\n `/guilds/${snowflake(guildId, \"Guild ID\")}/roles/${snowflake(roleId, \"Role ID\")}`,\r\n /** Returns a member role route. */ guildMemberRole: (\r\n guildId: string,\r\n userId: string,\r\n roleId: string,\r\n ) =>\r\n `/guilds/${snowflake(guildId, \"Guild ID\")}/members/${snowflake(userId, \"User ID\")}/roles/${snowflake(roleId, \"Role ID\")}`,\r\n /** Returns guild bans collection. */ guildBans: (guildId: string) =>\r\n `/guilds/${snowflake(guildId, \"Guild ID\")}/bans`,\r\n /** Returns an individual guild ban. */ guildBan: (\r\n guildId: string,\r\n userId: string,\r\n ) =>\r\n `/guilds/${snowflake(guildId, \"Guild ID\")}/bans/${snowflake(userId, \"User ID\")}`,\r\n /** Returns a channel. @param channelId Channel identifier. @returns Channel route. */ channel:\r\n (channelId: string) => `/channels/${snowflake(channelId, \"Channel ID\")}`,\r\n /** Returns messages in a channel. @param channelId Channel identifier. @returns Message collection route. */ channelMessages:\r\n (channelId: string) =>\r\n `/channels/${snowflake(channelId, \"Channel ID\")}/messages`,\r\n /** Returns a message. @param channelId Channel identifier. @param messageId Message identifier. @returns Message route. */ message:\r\n (channelId: string, messageId: string) =>\r\n `/channels/${snowflake(channelId, \"Channel ID\")}/messages/${snowflake(messageId, \"Message ID\")}`,\r\n /** Crossposts a message. @param channelId Channel identifier. @param messageId Message identifier. @returns Crosspost route. */ crosspostMessage:\r\n (channelId: string, messageId: string) =>\r\n `${Routes.message(channelId, messageId)}/crosspost`,\r\n /** Returns reactions for a message and emoji. @param channelId Channel identifier. @param messageId Message identifier. @param emoji Emoji name or ID. @returns Reaction route. */ messageReactions:\r\n (channelId: string, messageId: string, emoji: string) =>\r\n `${Routes.message(channelId, messageId)}/reactions/${encodeURIComponent(emoji)}`,\r\n /** Removes all reactions from a message. @param channelId Channel identifier. @param messageId Message identifier. @returns Reaction collection route. */ messageReactionsAll:\r\n (channelId: string, messageId: string) =>\r\n `${Routes.message(channelId, messageId)}/reactions`,\r\n /** Returns pinned messages. @param channelId Channel identifier. @returns Pins route. */ channelPins:\r\n (channelId: string) =>\r\n `/channels/${snowflake(channelId, \"Channel ID\")}/pins`,\r\n /** Pins a message. @param channelId Channel identifier. @param messageId Message identifier. @returns Pin route. */ channelPin:\r\n (channelId: string, messageId: string) =>\r\n `/channels/${snowflake(channelId, \"Channel ID\")}/pins/${snowflake(messageId, \"Message ID\")}`,\r\n /** Creates a thread from a message. @param channelId Channel identifier. @param messageId Message identifier. @returns Message-thread route. */ messageThread:\r\n (channelId: string, messageId: string) =>\r\n `${Routes.message(channelId, messageId)}/threads`,\r\n /** Bulk deletes messages. @param channelId Channel identifier. @returns Bulk-delete route. */ channelBulkDelete:\r\n (channelId: string) =>\r\n `/channels/${snowflake(channelId, \"Channel ID\")}/messages/bulk-delete`,\r\n /** Returns channel webhooks. @param channelId Channel identifier. @returns Webhook collection route. */ channelWebhooks:\r\n (channelId: string) =>\r\n `/channels/${snowflake(channelId, \"Channel ID\")}/webhooks`,\r\n /** Returns channel invites. @param channelId Channel identifier. @returns Invite collection route. */ channelInvites:\r\n (channelId: string) =>\r\n `/channels/${snowflake(channelId, \"Channel ID\")}/invites`,\r\n /** Returns a webhook. @param webhookId Webhook identifier. @param token Optional webhook token. @returns Webhook route. */ webhook:\r\n (webhookId: string, token?: string) =>\r\n `/webhooks/${snowflake(webhookId, \"Webhook ID\")}${token ? `/${encodeURIComponent(token)}` : \"\"}`,\r\n /** Returns a webhook message. */ webhookMessage: (\r\n webhookId: string,\r\n token: string,\r\n messageId: string,\r\n ) =>\r\n `/webhooks/${snowflake(webhookId, \"Webhook ID\")}/${encodeURIComponent(token)}/messages/${snowflake(messageId, \"Message ID\")}`,\r\n /** Returns application commands for an application. @param applicationId Application identifier. @returns Global command route. */ applicationCommands:\r\n (applicationId: string) =>\r\n `/applications/${snowflake(applicationId, \"Application ID\")}/commands`,\r\n /** Returns one application command. @param applicationId Application identifier. @param commandId Command identifier. @returns Command route. */ applicationCommand:\r\n (applicationId: string, commandId: string) =>\r\n `/applications/${snowflake(applicationId, \"Application ID\")}/commands/${snowflake(commandId, \"Command ID\")}`,\r\n /** Returns guild application commands. @param applicationId Application identifier. @param guildId Guild identifier. @returns Guild command route. */ guildApplicationCommands:\r\n (applicationId: string, guildId: string) =>\r\n `/applications/${snowflake(applicationId, \"Application ID\")}/guilds/${snowflake(guildId, \"Guild ID\")}/commands`,\r\n /** Returns a single guild application command. @param applicationId Application identifier. @param guildId Guild identifier. @param commandId Command identifier. @returns Guild command route. */ guildApplicationCommand:\r\n (applicationId: string, guildId: string, commandId: string) =>\r\n `/applications/${snowflake(applicationId, \"Application ID\")}/guilds/${snowflake(guildId, \"Guild ID\")}/commands/${snowflake(commandId, \"Command ID\")}`,\r\n /** Returns an interaction callback endpoint. @param interactionId Interaction identifier. @param token Interaction token. @returns Interaction callback route. */ interactionCallback:\r\n (interactionId: string, token: string) =>\r\n `/interactions/${snowflake(interactionId, \"Interaction ID\")}/${encodeURIComponent(token)}/callback`,\r\n /** Returns the original interaction response endpoint. @param applicationId Application identifier. @param token Interaction token. @returns Original-response route. */ interactionOriginalResponse:\r\n (applicationId: string, token: string) =>\r\n `/webhooks/${snowflake(applicationId, \"Application ID\")}/${encodeURIComponent(token)}/messages/@original`,\r\n /** Returns guild threads that are active. @param guildId Guild identifier. @returns Active-thread route. */ guildActiveThreads:\r\n (guildId: string) =>\r\n `/guilds/${snowflake(guildId, \"Guild ID\")}/threads/active`,\r\n /** Returns public archived threads for a channel. @param channelId Channel identifier. @returns Public-archive route. */ channelPublicArchivedThreads:\r\n (channelId: string) =>\r\n `/channels/${snowflake(channelId, \"Channel ID\")}/threads/archived/public`,\r\n /** Returns private archived threads for a channel. @param channelId Channel identifier. @returns Private-archive route. */ channelPrivateArchivedThreads:\r\n (channelId: string) =>\r\n `/channels/${snowflake(channelId, \"Channel ID\")}/threads/archived/private`,\r\n /** Returns a thread's members. @param threadId Thread identifier. @returns Thread-member route. */ threadMembers:\r\n (threadId: string) =>\r\n `/channels/${snowflake(threadId, \"Thread ID\")}/thread-members`,\r\n /** Returns guild scheduled events. @param guildId Guild identifier. @returns Scheduled-event collection route. */ guildScheduledEvents:\r\n (guildId: string) =>\r\n `/guilds/${snowflake(guildId, \"Guild ID\")}/scheduled-events`,\r\n /** Returns one guild scheduled event. @param guildId Guild identifier. @param eventId Event identifier. @returns Scheduled-event route. */ guildScheduledEvent:\r\n (guildId: string, eventId: string) =>\r\n `/guilds/${snowflake(guildId, \"Guild ID\")}/scheduled-events/${snowflake(eventId, \"Event ID\")}`,\r\n /** Returns guild automod rules. @param guildId Guild identifier. @returns Automod-rule collection route. */ guildAutoModerationRules:\r\n (guildId: string) =>\r\n `/guilds/${snowflake(guildId, \"Guild ID\")}/auto-moderation/rules`,\r\n /** Returns one automod rule. @param guildId Guild identifier. @param ruleId Rule identifier. @returns Automod-rule route. */ guildAutoModerationRule:\r\n (guildId: string, ruleId: string) =>\r\n `/guilds/${snowflake(guildId, \"Guild ID\")}/auto-moderation/rules/${snowflake(ruleId, \"Rule ID\")}`,\r\n /** Returns current voice regions. @returns Voice-region route. */ voiceRegions:\r\n () => \"/voice/regions\",\r\n /** Returns the generic Gateway endpoint. @returns Gateway route. */ gateway:\r\n () => \"/gateway\",\r\n /** Returns the Gateway endpoint and recommended shard count for bots. @returns Gateway bot route. */ gatewayBot:\r\n () => \"/gateway/bot\",\r\n} as const;\r\n\r\n/** Validates a Discord snowflake route parameter. @param value Candidate identifier. @param field Human-readable field name. @returns The validated identifier. @throws {TypeError} If the identifier is not a Discord snowflake. */\r\nfunction snowflake(value: string, field: string): string {\r\n if (!/^\\d{1,20}$/.test(value))\r\n throw new TypeError(`${field} must be a valid Discord snowflake.`);\r\n return value;\r\n}\r\n",
|
|
9
|
-
"/** Error thrown when Discord rejects a REST request. */\nexport class RESTError extends Error {\n /** HTTP status returned by Discord. */ public readonly status: number;\n /** Discord API error code, when provided. */ public readonly code?: number;\n /** Raw Discord validation/error payload. */ public readonly errors?: unknown;\n /** HTTP method used for the failed request. */ public readonly method?: string;\n /** API path used for the failed request. */ public readonly path?: string;\n /** Creates a REST error with request context. @param message Error message. @param status HTTP status. @param code Discord error code. @param errors Raw error payload. @param options Request context and cause. */\n public constructor(\n message: string,\n status: number,\n code?: number,\n errors?: unknown,\n options: { method?: string; path?: string; cause?: unknown } = {},\n ) {\n super(\n message,\n options.cause === undefined ? undefined : { cause: options.cause },\n );\n this.name = \"RESTError\";\n this.status = status;\n this.code = code;\n this.errors = errors;\n this.method = options.method;\n this.path = options.path;\n }\n}\n\n/** Internal state shared by requests mapped to one Discord rate-limit bucket. */\ntype Bucket = { remaining: number; resetAt: number; queue: Promise<void> };\n/** Options controlling an individual REST request. */\nexport interface RESTRequestOptions {\n /** Abort signal used to cancel the request and any queued wait. */ signal?: AbortSignal;\n}\n\n/** Configures which REST failures may be retried. */\nexport interface RetryPolicy {\n /** Maximum retry attempts. */ maxRetries: number;\n /** Determines whether a request may be retried. @param method HTTP method. @param status HTTP status, or zero for transport errors. @returns True when retrying is safe under the policy. */ shouldRetry(\n method: string,\n status: number,\n ): boolean;\n /** Calculates delay before the next attempt. @param attempt Zero-based retry number. @param retryAfter Server-provided delay, when available. @returns Delay in milliseconds. */ getDelay(\n attempt: number,\n retryAfter?: number,\n ): number;\n}\n/** Creates the default conservative REST retry policy. @param maxRetries Maximum retries. @returns Retry policy that retries rate limits and idempotent transient failures. @throws {TypeError} If maxRetries is negative or not finite. */\nexport function createRetryPolicy(maxRetries = 2): RetryPolicy {\n if (!Number.isFinite(maxRetries) || maxRetries < 0)\n throw new TypeError(\"maxRetries must be a non-negative finite number.\");\n return {\n maxRetries: Math.floor(maxRetries),\n shouldRetry(method, status) {\n const normalized = method.toUpperCase();\n return (\n status === 429 ||\n (status >= 500 &&\n status <= 599 &&\n [\"GET\", \"HEAD\", \"PUT\", \"DELETE\"].includes(normalized))\n );\n },\n getDelay(attempt, retryAfter) {\n if (retryAfter !== undefined) return Math.max(0, retryAfter * 1000);\n return Math.min(10_000, 500 * 2 ** attempt) + Math.random() * 250;\n },\n };\n}\n\n/** Bun-native REST transport with Discord bucket-aware rate limiting, retries, and cancellation. */\nexport class REST {\n readonly #baseURL: string;\n readonly #timeout: number;\n readonly #retryPolicy: RetryPolicy;\n #token?: string;\n #globalResetAt = 0;\n readonly #buckets = new Map<string, Bucket>();\n readonly #routeBuckets = new Map<string, string>();\n /** Creates a REST transport. @param options Transport configuration. @throws {TypeError} If retry configuration is invalid. */\n public constructor(\n options: {\n token?: string;\n timeout?: number;\n retries?: number;\n retryPolicy?: RetryPolicy;\n baseURL?: string;\n } = {},\n ) {\n this.#token = options.token;\n this.#timeout = Math.max(1, options.timeout ?? 15_000);\n this.#retryPolicy =\n options.retryPolicy ?? createRetryPolicy(options.retries ?? 2);\n this.#baseURL = (options.baseURL ?? \"https://discord.com/api/v10\").replace(\n /\\/$/,\n \"\",\n );\n }\n /** Sets the authentication token. @param token Discord bot token. @returns Nothing. @throws {TypeError} If token is empty. */\n public setToken(token: string): void {\n if (!token.trim()) throw new TypeError(\"A Discord bot token is required.\");\n this.#token = token;\n }\n /** Executes an HTTP request with Discord bucket/global rate limits, retry handling, and AbortSignal support. @param method HTTP method. @param path API path. @param body Optional JSON body. @param options Cancellation options. @returns Decoded response body. @throws {RESTError} If Discord or transport rejects the request. */\n public async request<T>(\n method: string,\n path: string,\n body?: unknown,\n options: RESTRequestOptions = {},\n ): Promise<T> {\n const normalizedMethod = method.toUpperCase();\n if (!normalizedMethod) throw new TypeError(\"REST method is required.\");\n if (!path.startsWith(\"/\"))\n throw new TypeError(\"REST paths must start with '/'.\");\n const route = `${normalizedMethod}:${this.#normalizeRoute(path)}`;\n let bucketKey = this.#routeBuckets.get(route) ?? route;\n let bucket = this.#buckets.get(bucketKey) ?? {\n remaining: 1,\n resetAt: 0,\n queue: Promise.resolve(),\n };\n this.#buckets.set(bucketKey, bucket);\n const previous = bucket.queue;\n let release!: () => void;\n bucket.queue = new Promise((resolve) => {\n release = resolve;\n });\n await this.#abortable(previous, options.signal, path);\n try {\n for (\n let attempt = 0;\n attempt <= this.#retryPolicy.maxRetries;\n attempt++\n ) {\n await this.#wait(bucket, options.signal, path);\n await this.#waitGlobal(options.signal, path);\n const controller = new AbortController();\n const onAbort = () => controller.abort(options.signal?.reason);\n if (options.signal?.aborted)\n throw this.#abortError(path, options.signal.reason);\n options.signal?.addEventListener(\"abort\", onAbort, { once: true });\n const timer = setTimeout(\n () =>\n controller.abort(\n new DOMException(\"REST request timeout\", \"TimeoutError\"),\n ),\n this.#timeout,\n );\n try {\n const response = await fetch(`${this.#baseURL}${path}`, {\n method: normalizedMethod,\n headers: {\n ...(this.#token ? { Authorization: `Bot ${this.#token}` } : {}),\n \"Content-Type\": \"application/json\",\n \"User-Agent\": \"Lunibee/0.1.0\",\n },\n body: body === undefined ? undefined : JSON.stringify(body),\n signal: controller.signal,\n });\n bucket = this.#update(response, bucket, route, bucketKey);\n bucketKey = this.#routeBuckets.get(route) ?? bucketKey;\n const payload = await this.#readPayload(response);\n if (response.ok)\n return (response.status === 204 ? undefined : payload) as T;\n const data = this.#errorData(payload);\n const retryAfter =\n response.status === 429\n ? this.#retryAfter(response, data)\n : undefined;\n if (data.global && retryAfter !== undefined)\n this.#globalResetAt = Date.now() + retryAfter * 1000;\n if (\n attempt < this.#retryPolicy.maxRetries &&\n this.#retryPolicy.shouldRetry(normalizedMethod, response.status)\n ) {\n await this.#sleep(\n this.#retryPolicy.getDelay(attempt, retryAfter),\n options.signal,\n path,\n );\n continue;\n }\n throw new RESTError(\n data.message ??\n response.statusText ??\n `Discord REST request failed with status ${response.status}`,\n response.status,\n data.code,\n payload,\n { method: normalizedMethod, path },\n );\n } catch (error) {\n if (error instanceof RESTError) throw error;\n if (options.signal?.aborted)\n throw this.#abortError(path, options.signal.reason);\n const isTimeout =\n error instanceof DOMException &&\n (error.name === \"TimeoutError\" || error.name === \"AbortError\");\n if (\n !isTimeout &&\n attempt < this.#retryPolicy.maxRetries &&\n this.#retryPolicy.shouldRetry(normalizedMethod, 0)\n ) {\n await this.#sleep(\n this.#retryPolicy.getDelay(attempt),\n options.signal,\n path,\n );\n continue;\n }\n throw new RESTError(\n isTimeout\n ? `Discord REST request timed out after ${this.#timeout}ms`\n : \"Discord REST request failed\",\n 0,\n undefined,\n undefined,\n { method: normalizedMethod, path, cause: error },\n );\n } finally {\n clearTimeout(timer);\n options.signal?.removeEventListener(\"abort\", onAbort);\n }\n }\n throw new RESTError(\n \"Discord REST request exhausted its retry attempts\",\n 0,\n undefined,\n undefined,\n { method: normalizedMethod, path },\n );\n } finally {\n release();\n }\n }\n /** Sends a GET request. @param path API path. @param options Cancellation options. @returns Decoded response. @throws {RESTError} When the request fails. */ public get<\n T,\n >(path: string, options?: RESTRequestOptions): Promise<T> {\n return this.request<T>(\"GET\", path, undefined, options);\n }\n /** Sends a POST request. @param path API path. @param body Optional JSON body. @param options Cancellation options. @returns Decoded response. @throws {RESTError} When the request fails. */ public post<\n T,\n >(path: string, body?: unknown, options?: RESTRequestOptions): Promise<T> {\n return this.request<T>(\"POST\", path, body, options);\n }\n /** Sends a PATCH request. @param path API path. @param body Optional JSON body. @param options Cancellation options. @returns Decoded response. @throws {RESTError} When the request fails. */ public patch<\n T,\n >(path: string, body?: unknown, options?: RESTRequestOptions): Promise<T> {\n return this.request<T>(\"PATCH\", path, body, options);\n }\n /** Sends a PUT request. @param path API path. @param body Optional JSON body. @param options Cancellation options. @returns Decoded response. @throws {RESTError} When the request fails. */ public put<\n T,\n >(path: string, body?: unknown, options?: RESTRequestOptions): Promise<T> {\n return this.request<T>(\"PUT\", path, body, options);\n }\n /** Sends a DELETE request. @param path API path. @param options Cancellation options. @returns Decoded response. @throws {RESTError} When the request fails. */ public delete<\n T,\n >(path: string, options?: RESTRequestOptions): Promise<T> {\n return this.request<T>(\"DELETE\", path, undefined, options);\n }\n /** Waits for a route bucket while respecting cancellation. @param bucket Bucket state. @param signal Optional cancellation signal. @param path Request path for error context. @returns Promise fulfilled when sending is permitted. @throws {RESTError} If the request is aborted. */\n async #wait(\n bucket: Bucket,\n signal: AbortSignal | undefined,\n path: string,\n ): Promise<void> {\n const delay = bucket.resetAt - Date.now();\n if (bucket.remaining <= 0 && delay > 0)\n await this.#sleep(delay, signal, path);\n }\n /** Waits for the global Discord rate limit while respecting cancellation. @param signal Optional cancellation signal. @param path Request path for error context. @returns Promise fulfilled when the global limit expires. @throws {RESTError} If the request is aborted. */\n async #waitGlobal(\n signal: AbortSignal | undefined,\n path: string,\n ): Promise<void> {\n const delay = this.#globalResetAt - Date.now();\n if (delay > 0) await this.#sleep(delay, signal, path);\n }\n /** Waits for a delay or aborts immediately. @param delay Delay in milliseconds. @param signal Optional cancellation signal. @param path Request path. @returns Promise fulfilled after delay. @throws {RESTError} If aborted. */\n async #sleep(\n delay: number,\n signal: AbortSignal | undefined,\n path: string,\n ): Promise<void> {\n if (delay <= 0) return;\n await new Promise<void>((resolve, reject) => {\n const timer = setTimeout(resolve, delay);\n const abort = () => {\n clearTimeout(timer);\n reject(this.#abortError(path, signal?.reason));\n };\n if (signal?.aborted) return abort();\n signal?.addEventListener(\"abort\", abort, { once: true });\n });\n }\n /** Waits for a queued request or aborts. @param promise Queue predecessor. @param signal Optional cancellation signal. @param path Request path. @returns Promise fulfilled when predecessor releases. @throws {RESTError} If aborted. */\n async #abortable(\n promise: Promise<void>,\n signal: AbortSignal | undefined,\n path: string,\n ): Promise<void> {\n if (!signal) return promise;\n if (signal.aborted) throw this.#abortError(path, signal.reason);\n return Promise.race([\n promise,\n new Promise<void>((_, reject) =>\n signal.addEventListener(\n \"abort\",\n () => reject(this.#abortError(path, signal.reason)),\n { once: true },\n ),\n ),\n ]);\n }\n /** Creates a consistent cancellation error. @param path Request path. @param reason Abort reason. @returns REST cancellation error. */\n #abortError(path: string, reason: unknown): RESTError {\n return new RESTError(\n reason instanceof Error\n ? reason.message\n : \"Discord REST request was aborted\",\n 0,\n undefined,\n undefined,\n { path, cause: reason },\n );\n }\n /** Reads a Discord response payload. @param response HTTP response. @returns JSON or text payload. */\n async #readPayload(response: Response): Promise<unknown> {\n if (response.status === 204) return undefined;\n const contentType = response.headers.get(\"content-type\") ?? \"\";\n if (contentType.includes(\"application/json\"))\n return response.json().catch(() => undefined);\n return response.text().catch(() => undefined);\n }\n /** Extracts retry metadata from a Discord payload. @param payload Response payload. @returns Normalized error metadata. */\n #errorData(payload: unknown): {\n message?: string;\n code?: number;\n retry_after?: number;\n global?: boolean;\n } {\n if (!payload || typeof payload !== \"object\") return {};\n const data = payload as Record<string, unknown>;\n return {\n message: typeof data.message === \"string\" ? data.message : undefined,\n code: typeof data.code === \"number\" ? data.code : undefined,\n retry_after:\n typeof data.retry_after === \"number\" ? data.retry_after : undefined,\n global: data.global === true,\n };\n }\n /** Resolves Retry-After from headers or JSON. @param response HTTP response. @param data Parsed response metadata. @returns Retry delay in seconds. */\n #retryAfter(response: Response, data: { retry_after?: number }): number {\n const header = Number(response.headers.get(\"Retry-After\"));\n const retryAfter =\n data.retry_after ?? (Number.isFinite(header) ? header : 1);\n return Math.max(0, retryAfter);\n }\n /** Normalizes Discord routes for stable bucket discovery. @param path API path. @returns Normalized route. */\n #normalizeRoute(path: string): string {\n const queryIndex = path.indexOf(\"?\");\n const routePath = queryIndex === -1 ? path : path.slice(0, queryIndex);\n return routePath.replace(/\\/\\d+(?=\\/|$)/g, \"/:id\");\n }\n /** Updates bucket state from Discord's rate-limit headers and records the server bucket hash. @param response HTTP response. @param bucket Current bucket. @param route Normalized local route key. @param bucketKey Current bucket identifier. @returns Bucket state used for subsequent attempts. */\n #update(\n response: Response,\n bucket: Bucket,\n route: string,\n bucketKey: string,\n ): Bucket {\n const serverBucket = response.headers.get(\"X-RateLimit-Bucket\");\n if (serverBucket) {\n this.#routeBuckets.set(route, serverBucket);\n if (serverBucket !== bucketKey) {\n const shared = this.#buckets.get(serverBucket) ?? bucket;\n this.#buckets.set(serverBucket, shared);\n bucket = shared;\n }\n }\n const remaining = Number(response.headers.get(\"X-RateLimit-Remaining\"));\n const resetAfter = Number(response.headers.get(\"X-RateLimit-Reset-After\"));\n const reset = Number(response.headers.get(\"X-RateLimit-Reset\"));\n if (Number.isFinite(remaining)) bucket.remaining = Math.max(0, remaining);\n if (Number.isFinite(resetAfter))\n bucket.resetAt = Date.now() + Math.max(0, resetAfter) * 1000;\n else if (Number.isFinite(reset)) bucket.resetAt = reset * 1000;\n if (response.status === 429) {\n const retryAfter = Number(response.headers.get(\"Retry-After\"));\n if (Number.isFinite(retryAfter))\n bucket.resetAt = Math.max(\n bucket.resetAt,\n Date.now() + retryAfter * 1000,\n );\n }\n if (response.headers.get(\"X-RateLimit-Global\") === \"true\") {\n const retryAfter = Number(response.headers.get(\"Retry-After\"));\n if (Number.isFinite(retryAfter))\n this.#globalResetAt = Math.max(\n this.#globalResetAt,\n Date.now() + retryAfter * 1000,\n );\n }\n return bucket;\n }\n}\n\nexport { Routes } from \"./routes.js\";\n\nexport {\n WebhookClient,\n type WebhookClientOptions,\n type WebhookMessageOptions,\n} from \"./webhook.js\";\n",
|
|
10
|
-
"/** Common Discord snowflake-backed structure. */\nexport class BaseStructure {\n /** Discord resource ID. */\n public readonly id: string;\n /** Creates a structure from an ID. @param id Discord snowflake identifier. @throws {TypeError} If the ID is invalid. */\n public constructor(id: string) {\n if (!/^\\d{1,20}$/.test(id))\n throw new TypeError(\"A Discord structure requires a valid snowflake ID.\");\n this.id = id;\n }\n /** Returns the resource ID. @returns Discord snowflake identifier. */\n public toString(): string {\n return this.id;\n }\n}\n\n/** Context used by structures to delegate resource operations to the owning client. */\nexport interface ResourceContext {\n /** Sends a message through the owning channel manager. @param channelId Channel identifier. @param options Message payload. @returns The created message. */\n sendMessage(\n channelId: string,\n options: { content?: string },\n ): Promise<import(\"./index.js\").Message>;\n /** Edits a message through the owning channel manager. @param channelId Channel identifier. @param messageId Message identifier. @param options Edit payload. @returns The updated message. */\n editMessage(\n channelId: string,\n messageId: string,\n options: { content?: string },\n ): Promise<import(\"./index.js\").Message>;\n /** Deletes a message through the owning channel manager. @param channelId Channel identifier. @param messageId Message identifier. @returns A promise fulfilled after deletion. */\n deleteMessage(channelId: string, messageId: string): Promise<void>;\n /** Crossposts a message through the owning channel manager. @param channelId Channel identifier. @param messageId Message identifier. @returns The crossposted message. */\n crosspostMessage(\n channelId: string,\n messageId: string,\n ): Promise<import(\"./index.js\").Message>;\n}\n\n/** Represents a Discord user. */\nexport class User extends BaseStructure {\n /** User name. */ public username: string;\n /** Global display name. */ public globalName: string | null;\n /** Avatar hash. */ public avatar: string | null;\n /** Whether the user is a bot. */ public bot: boolean;\n /** Whether the account is a Discord system user. */ public system: boolean;\n /** Public user flags. */ public flags: number;\n /** Creates a user from Discord API data. @param data User payload. @throws {TypeError} If required data is invalid. */\n public constructor(data: import(\"@lunibee/types\").UserData) {\n super(data.id);\n if (!data.username)\n throw new TypeError(\"A Discord user requires a username.\");\n this.username = data.username;\n this.globalName = data.global_name ?? null;\n this.avatar = data.avatar ?? null;\n this.bot = data.bot ?? false;\n this.system = data.system ?? false;\n this.flags = data.public_flags ?? 0;\n }\n /** Gets the effective display name. @returns Global display name or username. */\n public get displayName(): string {\n return this.globalName ?? this.username;\n }\n /** Creates an avatar CDN URL. @param options URL format options. @returns Avatar URL, or null when no custom avatar exists. */\n public avatarURL(\n options: { extension?: \"png\" | \"jpg\" | \"webp\" | \"gif\"; size?: number } = {},\n ): string | null {\n if (!this.avatar) return null;\n const extension =\n options.extension ?? (this.avatar.startsWith(\"a_\") ? \"gif\" : \"png\");\n return `https://cdn.discordapp.com/avatars/${this.id}/${this.avatar}.${extension}${options.size ? `?size=${options.size}` : \"\"}`;\n }\n /** Creates the default avatar URL. @returns Discord default avatar URL. */\n public defaultAvatarURL(): string {\n return `https://cdn.discordapp.com/embed/avatars/${Number(BigInt(this.id) % 5n)}.png`;\n }\n /** Creates an avatar URL with default fallback. @param options URL format options. @returns Avatar or default avatar URL. */\n public displayAvatarURL(\n options: { extension?: \"png\" | \"jpg\" | \"webp\" | \"gif\"; size?: number } = {},\n ): string {\n return this.avatarURL(options) ?? this.defaultAvatarURL();\n }\n}\n\n/** Represents a Discord channel. */\nexport class Channel extends BaseStructure {\n /** Discord channel type. */ public type: number;\n /** Channel name. */ public name?: string | null;\n /** Guild containing the channel. */ public guildId?: string;\n readonly #context?: ResourceContext;\n /** Creates a channel from Discord API data. @param data Channel payload. @param context Optional owning resource context. @throws {TypeError|RangeError} If required channel data is invalid. */\n public constructor(\n data: import(\"@lunibee/types\").APIChannel,\n context?: ResourceContext,\n ) {\n super(data.id);\n if (!Number.isInteger(data.type) || data.type < 0)\n throw new RangeError(\"A Discord channel requires a valid channel type.\");\n this.type = data.type;\n this.name = data.name;\n this.guildId = data.guild_id;\n this.#context = context;\n }\n /** Sends a message through the owning manager. @param options Message payload. @returns The created message. @throws {Error} If this channel is detached from a client. */\n public sendMessage(options: {\n content?: string;\n }): Promise<import(\"./index.js\").Message> {\n if (!this.#context)\n throw new Error(\"This channel is not attached to a client.\");\n return this.#context.sendMessage(this.id, options);\n }\n}\n\n/** Represents a Discord guild. */\nexport class Guild extends BaseStructure {\n /** Guild name. */ public name: string;\n /** Preferred guild locale. */ public preferredLocale?: string;\n /** Guild owner ID. */ public ownerId?: string;\n /** Creates a guild from Discord API data. @param data Guild payload. @throws {TypeError} If required data is invalid. */\n public constructor(data: {\n id: string;\n name: string;\n preferred_locale?: string;\n owner_id?: string;\n }) {\n super(data.id);\n if (!data.name) throw new TypeError(\"A Discord guild requires a name.\");\n this.name = data.name;\n this.preferredLocale = data.preferred_locale;\n this.ownerId = data.owner_id;\n }\n}\n",
|
|
11
|
-
"/** Permission bit values exposed by Discord. */\
|
|
12
|
-
"/** Discord interaction type constants. */\r\nexport const InteractionType = {\r\n Ping: 1,\r\n ApplicationCommand: 2,\r\n MessageComponent: 3,\r\n ApplicationCommandAutocomplete: 4,\r\n ModalSubmit: 5,\r\n} as const;\r\n/** Discord interaction response type constants. */\r\nexport const InteractionResponseType = {\r\n Pong: 1,\r\n ChannelMessage: 4,\r\n DeferredChannelMessage: 5,\r\n DeferredMessageUpdate: 6,\r\n MessageUpdate: 7,\r\n Autocomplete: 8,\r\n Modal: 9,\r\n} as const;\r\n/** Data shared by Discord interactions. */\r\nexport interface InteractionData {\r\n /** Interaction identifier. */ id: string;\r\n /** Application identifier. */ application_id: string;\r\n /** Interaction type. */ type: number;\r\n /** Interaction token. */ token: string;\r\n /** Gateway/API version. */ version?: number;\r\n /** Guild identifier. */ guild_id?: string;\r\n /** Channel identifier. */ channel_id?: string;\r\n /** Interaction-specific data. */ data?: Record<string, unknown>;\r\n [key: string]: unknown;\r\n}\r\n/** Options for an interaction response message. */\r\nexport interface InteractionReplyOptions {\r\n /** Message content. */ content?: string;\r\n /** Whether the response is ephemeral. */ ephemeral?: boolean;\r\n /** Message components. */ components?: unknown[];\r\n /** Message embeds. */ embeds?: unknown[];\r\n /** Discord message flags. */ flags?: number;\r\n [key: string]: unknown;\r\n}\r\n/** Transport required by an interaction structure. */\r\nexport interface InteractionClient {\r\n /** Sends the initial interaction callback. @param id Interaction identifier. @param token Interaction token. @param response Callback payload. @returns Discord response. @throws {Error} When REST fails. */ postInteractionResponse(\r\n id: string,\r\n token: string,\r\n response: InteractionResponse,\r\n ): Promise<unknown>;\r\n /** Edits the original interaction response. @param token Interaction token. @param data Message payload. @returns Discord response. @throws {Error} When REST fails. */ editInteractionReply(\r\n token: string,\r\n data: InteractionReplyOptions,\r\n ): Promise<unknown>;\r\n /** Deletes the original interaction response. @param token Interaction token. @returns Promise fulfilled after deletion. @throws {Error} When REST fails. */ deleteInteractionReply(\r\n token: string,\r\n ): Promise<void>;\r\n /** Sends a follow-up interaction webhook message. @param token Interaction token. @param data Message payload. @returns Discord response. @throws {Error} When REST fails. */ followUpInteraction(\r\n token: string,\r\n data: InteractionReplyOptions,\r\n ): Promise<unknown>;\r\n}\r\n/** A Discord interaction callback payload. */\r\nexport class InteractionResponse {\r\n readonly type: number;\r\n readonly data?: InteractionReplyOptions;\r\n /** Creates a response payload. @param type Discord callback type. @param data Optional callback data. @throws {TypeError} If type is not finite. */\r\n public constructor(type: number, data?: InteractionReplyOptions) {\r\n if (!Number.isFinite(type))\r\n throw new TypeError(\"Interaction response type must be finite.\");\r\n this.type = type;\r\n this.data = data;\r\n }\r\n /** Serializes the response for Discord. @returns Discord callback payload. */ public toJSON(): {\r\n type: number;\r\n data?: InteractionReplyOptions;\r\n } {\r\n return this.data === undefined\r\n ? { type: this.type }\r\n : { type: this.type, data: this.data };\r\n }\r\n /** Creates an immediate message response. @param options Response message options. @returns Callback payload. */ public static message(\r\n options: InteractionReplyOptions,\r\n ): InteractionResponse {\r\n const data: InteractionReplyOptions = { ...options };\r\n if (options.ephemeral) {\r\n data.flags = (typeof options.flags === \"number\" ? options.flags : 0) | 64;\r\n }\r\n return new InteractionResponse(\r\n InteractionResponseType.ChannelMessage,\r\n data,\r\n );\r\n }\r\n /** Creates a deferred channel response. @param ephemeral Whether the eventual response is ephemeral. @returns Callback payload. */ public static defer(\r\n ephemeral = false,\r\n ): InteractionResponse {\r\n return new InteractionResponse(\r\n InteractionResponseType.DeferredChannelMessage,\r\n ephemeral ? { flags: 64 } : undefined,\r\n );\r\n }\r\n /** Creates a Pong response. @returns Callback payload. */ public static pong(): InteractionResponse {\r\n return new InteractionResponse(InteractionResponseType.Pong);\r\n }\r\n}\r\n/** Base interaction structure. */\r\nexport class Interaction<TData extends InteractionData = InteractionData> {\r\n /** Interaction identifier. */ public readonly id: string;\r\n /** Application identifier. */ public readonly applicationId: string;\r\n /** Interaction token. */ public readonly token: string;\r\n /** Guild identifier. */ public readonly guildId?: string;\r\n /** Channel identifier. */ public readonly channelId?: string;\r\n /** Interaction type. */ public readonly type: number;\r\n /** Raw interaction data. */ public readonly data: TData;\r\n /** Whether the initial response was sent. */ public replied = false;\r\n /** Whether the initial response was deferred. */ public deferred = false;\r\n readonly #client: InteractionClient;\r\n /** Creates an interaction from a Gateway payload. @param client Interaction transport. @param data Gateway interaction payload. @throws {TypeError} If required identifiers are missing. */ public constructor(\r\n client: InteractionClient,\r\n data: TData,\r\n ) {\r\n if (!data.id || !data.token)\r\n throw new TypeError(\"Interaction ID and token are required.\");\r\n this.#client = client;\r\n this.id = data.id;\r\n this.applicationId = data.application_id;\r\n this.token = data.token;\r\n this.guildId = data.guild_id;\r\n this.channelId = data.channel_id;\r\n this.type = data.type;\r\n this.data = data;\r\n }\r\n /** Whether this interaction is an application command. @returns True for application command interactions. */ public isChatInputCommand(): this is CommandInteraction {\r\n return this.type === InteractionType.ApplicationCommand;\r\n }\r\n /** Whether this interaction is a message component. @returns True for component interactions. */ public isMessageComponent(): this is ComponentInteraction {\r\n return this.type === InteractionType.MessageComponent;\r\n }\r\n /** Whether this interaction is a modal submission. @returns True for modal submissions. */ public isModalSubmit(): this is ComponentInteraction {\r\n return this.type === InteractionType.ModalSubmit;\r\n }\r\n /** Whether this interaction is autocomplete. @returns True for autocomplete interactions. */ public isAutocomplete(): this is CommandInteraction {\r\n return this.type === InteractionType.ApplicationCommandAutocomplete;\r\n }\r\n /** Ensures the interaction has not already been acknowledged. @returns Nothing. @throws {Error} When already acknowledged. */ protected assertUnacknowledged(): void {\r\n if (this.replied || this.deferred)\r\n throw new Error(\"Interaction has already been acknowledged.\");\r\n }\r\n /** Ensures the interaction has been acknowledged. @returns Nothing. @throws {Error} When not acknowledged. */ protected assertAcknowledged(): void {\r\n if (!this.replied && !this.deferred)\r\n throw new Error(\"Interaction has not been acknowledged.\");\r\n }\r\n /** Posts a raw interaction response callback. */\r\n protected postResponse(response: InteractionResponse): Promise<unknown> {\r\n return this.#client.postInteractionResponse(this.id, this.token, response);\r\n }\r\n /** Sends the initial interaction response. @param options Response message options. @returns Discord response. @throws {Error} When already acknowledged or REST fails. */ public async reply(\r\n options: InteractionReplyOptions | string,\r\n ): Promise<unknown> {\r\n this.assertUnacknowledged();\r\n const payload =\r\n typeof options === \"string\" ? { content: options } : options;\r\n const result = await this.#client.postInteractionResponse(\r\n this.id,\r\n this.token,\r\n InteractionResponse.message(payload),\r\n );\r\n this.replied = true;\r\n return result;\r\n }\r\n /** Defers the initial interaction response. @param ephemeral Whether the eventual response is ephemeral. @returns Promise fulfilled after acknowledgement. @throws {Error} When already acknowledged or REST fails. */ public async deferReply(\r\n ephemeral = false,\r\n ): Promise<void> {\r\n this.assertUnacknowledged();\r\n await this.#client.postInteractionResponse(\r\n this.id,\r\n this.token,\r\n InteractionResponse.defer(ephemeral),\r\n );\r\n this.deferred = true;\r\n }\r\n /** Edits the original response. @param options Replacement message options. @returns Discord response. @throws {Error} When not acknowledged or REST fails. */ public editReply(\r\n options: InteractionReplyOptions,\r\n ): Promise<unknown> {\r\n this.assertAcknowledged();\r\n return this.#client.editInteractionReply(this.token, options);\r\n }\r\n /** Deletes the original response. @returns Promise fulfilled after deletion. @throws {Error} When not acknowledged or REST fails. */ public deleteReply(): Promise<void> {\r\n this.assertAcknowledged();\r\n return this.#client.deleteInteractionReply(this.token);\r\n }\r\n /** Sends a follow-up message using the interaction webhook. @param options Follow-up message options. @returns Discord response. @throws {Error} When REST fails. */ public followUp(\r\n options: InteractionReplyOptions | string,\r\n ): Promise<unknown> {\r\n const payload =\r\n typeof options === \"string\" ? { content: options } : options;\r\n return this.#client.followUpInteraction(this.token, payload);\r\n }\r\n /** Updates the message for a component interaction. */ public async update(\r\n options: InteractionReplyOptions | string,\r\n ): Promise<unknown> {\r\n this.assertUnacknowledged();\r\n const payload =\r\n typeof options === \"string\" ? { content: options } : options;\r\n const result = await this.#client.postInteractionResponse(\r\n this.id,\r\n this.token,\r\n new InteractionResponse(InteractionResponseType.MessageUpdate, payload),\r\n );\r\n this.replied = true;\r\n return result;\r\n }\r\n /** Opens a modal dialog in the user's client. @param modal Modal builder output or raw modal callback data. @returns Discord response. @throws {Error} When already acknowledged or REST fails. */\r\n public async showModal(modal: {\r\n custom_id: string;\r\n title: string;\r\n components: unknown[];\r\n [key: string]: unknown;\r\n }): Promise<unknown> {\r\n this.assertUnacknowledged();\r\n const result = await this.#client.postInteractionResponse(\r\n this.id,\r\n this.token,\r\n new InteractionResponse(\r\n InteractionResponseType.Modal,\r\n modal as InteractionReplyOptions,\r\n ),\r\n );\r\n this.replied = true;\r\n return result;\r\n }\r\n}\r\n/** Application command interaction. */\r\nexport class CommandInteraction extends Interaction {\r\n /** Invoked command name. @returns Command name or an empty string. */ public get commandName(): string {\r\n return typeof this.data.data?.name === \"string\" ? this.data.data.name : \"\";\r\n }\r\n}\r\n/** Message component interaction. */\r\nexport class ComponentInteraction extends Interaction {\r\n /** Gets component custom ID. */\r\n public get customId(): string {\r\n return (this.data as any)?.data?.custom_id ?? \"\";\r\n }\r\n /** Gets component type. */\r\n public get componentType(): number {\r\n return (this.data as any)?.data?.component_type ?? 0;\r\n }\r\n /** Gets selected values for select menu component interactions. */\r\n public get values(): string[] {\r\n return (this.data as any)?.data?.values ?? [];\r\n }\r\n /** Defers updating the message to which the component was attached. */\r\n public async deferUpdate(): Promise<void> {\r\n this.assertUnacknowledged();\r\n await this.postResponse(\r\n new InteractionResponse(InteractionResponseType.DeferredMessageUpdate),\r\n );\r\n this.deferred = true;\r\n }\r\n /** Updates the message to which the component was attached. */\r\n public async update(\r\n options: InteractionReplyOptions | string,\r\n ): Promise<unknown> {\r\n this.assertUnacknowledged();\r\n const payload =\r\n typeof options === \"string\" ? { content: options } : options;\r\n const result = await this.postResponse(\r\n new InteractionResponse(InteractionResponseType.MessageUpdate, payload),\r\n );\r\n this.replied = true;\r\n return result;\r\n }\r\n}\r\n\r\n/** Creates a specialized interaction structure for a Gateway payload. @param client Interaction transport. @param data Gateway interaction payload. @returns Specialized interaction structure. @throws {TypeError} If required identifiers are missing. */\r\nexport function createInteraction(\r\n client: InteractionClient,\r\n data: InteractionData,\r\n): Interaction {\r\n switch (data.type) {\r\n case InteractionType.ApplicationCommand:\r\n case InteractionType.ApplicationCommandAutocomplete:\r\n return new CommandInteraction(client, data);\r\n case InteractionType.MessageComponent:\r\n case InteractionType.ModalSubmit:\r\n return new ComponentInteraction(client, data);\r\n default:\r\n return new Interaction(client, data);\r\n }\r\n}\r\n\r\n/** Represents a Discord modal submission interaction. */\r\nexport class ModalSubmitInteraction extends Interaction {\r\n /** Gets the submitted modal custom ID. */\r\n public get customId(): string {\r\n return (this.data as any)?.data?.custom_id ?? \"\";\r\n }\r\n\r\n /** Retrieves the text value for a specific text input custom ID. */\r\n public getInputValue(customId: string): string | undefined {\r\n const rows = (this.data as any)?.data?.components ?? [];\r\n for (const row of rows) {\r\n for (const comp of row.components ?? []) {\r\n if (comp.custom_id === customId) return comp.value;\r\n }\r\n }\r\n return undefined;\r\n }\r\n}\r\n\r\n/** Represents a Discord slash command autocomplete interaction. */\r\nexport class AutocompleteInteraction extends Interaction {\r\n /** Gets the target command name. */\r\n public get commandName(): string {\r\n return (this.data as any)?.data?.name ?? \"\";\r\n }\r\n\r\n /** Gets the currently focused autocomplete option. */\r\n public get focusedOption(): { name: string; value: unknown } | undefined {\r\n const options = (this.data as any)?.data?.options ?? [];\r\n return options.find((opt: any) => opt.focused);\r\n }\r\n\r\n /** Responds to Discord with autocomplete choices. */\r\n public async respond(\r\n choices: { name: string; value: string | number }[],\r\n ): Promise<void> {\r\n const response = new InteractionResponse(\r\n InteractionResponseType.Autocomplete,\r\n { choices },\r\n );\r\n await this.postResponse(response);\r\n }\r\n}\r\n",
|
|
13
|
-
"
|
|
14
|
-
"import { Collection } from \"@lunibee/collection\";\nimport { REST, Routes } from \"@lunibee/rest\";\nimport { Message, type ResourceContext } from \"@lunibee/structures\";\n\
|
|
10
|
+
"/** Discord REST API route definitions. */\r\nexport const Routes = {\r\n /** Returns the current bot user. @returns User route. */ user: () =>\r\n \"/users/@me\",\r\n /** Returns one user. @param userId User identifier. @returns User route. */ userById:\r\n (userId: string) => `/users/${snowflake(userId, \"User ID\")}`,\r\n /** Returns a guild. @param guildId Guild identifier. @returns Guild route. */ guild:\r\n (guildId: string) => `/guilds/${snowflake(guildId, \"Guild ID\")}`,\r\n /** Returns a guild preview. @param guildId Guild identifier. */ guildPreview:\r\n (guildId: string) => `/guilds/${snowflake(guildId, \"Guild ID\")}/preview`,\r\n /** Returns active threads for a guild. @param guildId Guild identifier. */ guildActiveThreads:\r\n (guildId: string) => `/guilds/${snowflake(guildId, \"Guild ID\")}/threads/active`,\r\n /** Returns webhooks for a guild. @param guildId Guild identifier. */ guildWebhooks:\r\n (guildId: string) => `/guilds/${snowflake(guildId, \"Guild ID\")}/webhooks`,\r\n /** Returns invites for a guild. @param guildId Guild identifier. */ guildInvites:\r\n (guildId: string) => `/guilds/${snowflake(guildId, \"Guild ID\")}/invites`,\r\n /** Returns channels in a guild. @param guildId Guild identifier. @returns Channel collection route. */ guildChannels:\r\n (guildId: string) => `/guilds/${snowflake(guildId, \"Guild ID\")}/channels`,\r\n /** Returns a guild member. @param guildId Guild identifier. @param userId User identifier. @returns Guild-member route. */ guildMember:\r\n (guildId: string, userId: string) =>\r\n `/guilds/${snowflake(guildId, \"Guild ID\")}/members/${snowflake(userId, \"User ID\")}`,\r\n /** Returns all guild roles. @param guildId Guild identifier. @returns Guild-role route. */ guildRoles:\r\n (guildId: string) => `/guilds/${snowflake(guildId, \"Guild ID\")}/roles`,\r\n /** Returns an individual guild role. */ guildRole: (\r\n guildId: string,\r\n roleId: string,\r\n ) =>\r\n `/guilds/${snowflake(guildId, \"Guild ID\")}/roles/${snowflake(roleId, \"Role ID\")}`,\r\n /** Returns a member role route. */ guildMemberRole: (\r\n guildId: string,\r\n userId: string,\r\n roleId: string,\r\n ) =>\r\n `/guilds/${snowflake(guildId, \"Guild ID\")}/members/${snowflake(userId, \"User ID\")}/roles/${snowflake(roleId, \"Role ID\")}`,\r\n /** Returns guild bans collection. */ guildBans: (guildId: string) =>\r\n `/guilds/${snowflake(guildId, \"Guild ID\")}/bans`,\r\n /** Returns an individual guild ban. */ guildBan: (\r\n guildId: string,\r\n userId: string,\r\n ) =>\r\n `/guilds/${snowflake(guildId, \"Guild ID\")}/bans/${snowflake(userId, \"User ID\")}`,\r\n /** Returns a channel. @param channelId Channel identifier. @returns Channel route. */ channel:\r\n (channelId: string) => `/channels/${snowflake(channelId, \"Channel ID\")}`,\r\n /** Returns messages in a channel. @param channelId Channel identifier. @returns Message collection route. */ channelMessages:\r\n (channelId: string) =>\r\n `/channels/${snowflake(channelId, \"Channel ID\")}/messages`,\r\n /** Returns a message. @param channelId Channel identifier. @param messageId Message identifier. @returns Message route. */ message:\r\n (channelId: string, messageId: string) =>\r\n `/channels/${snowflake(channelId, \"Channel ID\")}/messages/${snowflake(messageId, \"Message ID\")}`,\r\n /** Crossposts a message. @param channelId Channel identifier. @param messageId Message identifier. @returns Crosspost route. */ crosspostMessage:\r\n (channelId: string, messageId: string) =>\r\n `${Routes.message(channelId, messageId)}/crosspost`,\r\n /** Returns reactions for a message and emoji. @param channelId Channel identifier. @param messageId Message identifier. @param emoji Emoji name or ID. @returns Reaction route. */ messageReactions:\r\n (channelId: string, messageId: string, emoji: string) =>\r\n `${Routes.message(channelId, messageId)}/reactions/${encodeURIComponent(emoji)}`,\r\n /** Removes all reactions from a message. @param channelId Channel identifier. @param messageId Message identifier. @returns Reaction collection route. */ messageReactionsAll:\r\n (channelId: string, messageId: string) =>\r\n `${Routes.message(channelId, messageId)}/reactions`,\r\n /** Returns pinned messages. @param channelId Channel identifier. @returns Pins route. */ channelPins:\r\n (channelId: string) =>\r\n `/channels/${snowflake(channelId, \"Channel ID\")}/pins`,\r\n /** Pins a message. @param channelId Channel identifier. @param messageId Message identifier. @returns Pin route. */ channelPin:\r\n (channelId: string, messageId: string) =>\r\n `/channels/${snowflake(channelId, \"Channel ID\")}/pins/${snowflake(messageId, \"Message ID\")}`,\r\n /** Creates a thread from a message. @param channelId Channel identifier. @param messageId Message identifier. @returns Message-thread route. */ messageThread:\r\n (channelId: string, messageId: string) =>\r\n `${Routes.message(channelId, messageId)}/threads`,\r\n /** Bulk deletes messages. @param channelId Channel identifier. @returns Bulk-delete route. */ channelBulkDelete:\r\n (channelId: string) =>\r\n `/channels/${snowflake(channelId, \"Channel ID\")}/messages/bulk-delete`,\r\n /** Returns channel webhooks. @param channelId Channel identifier. @returns Webhook collection route. */ channelWebhooks:\r\n (channelId: string) =>\r\n `/channels/${snowflake(channelId, \"Channel ID\")}/webhooks`,\r\n /** Returns channel invites. @param channelId Channel identifier. @returns Invite collection route. */ channelInvites:\r\n (channelId: string) =>\r\n `/channels/${snowflake(channelId, \"Channel ID\")}/invites`,\r\n /** Returns a webhook. @param webhookId Webhook identifier. @param token Optional webhook token. @returns Webhook route. */ webhook:\r\n (webhookId: string, token?: string) =>\r\n `/webhooks/${snowflake(webhookId, \"Webhook ID\")}${token ? `/${encodeURIComponent(token)}` : \"\"}`,\r\n /** Returns a webhook message. */ webhookMessage: (\r\n webhookId: string,\r\n token: string,\r\n messageId: string,\r\n ) =>\r\n `/webhooks/${snowflake(webhookId, \"Webhook ID\")}/${encodeURIComponent(token)}/messages/${snowflake(messageId, \"Message ID\")}`,\r\n /** Returns application commands for an application. @param applicationId Application identifier. @returns Global command route. */ applicationCommands:\r\n (applicationId: string) =>\r\n `/applications/${snowflake(applicationId, \"Application ID\")}/commands`,\r\n /** Returns one application command. @param applicationId Application identifier. @param commandId Command identifier. @returns Command route. */ applicationCommand:\r\n (applicationId: string, commandId: string) =>\r\n `/applications/${snowflake(applicationId, \"Application ID\")}/commands/${snowflake(commandId, \"Command ID\")}`,\r\n /** Returns guild application commands. @param applicationId Application identifier. @param guildId Guild identifier. @returns Guild command route. */ guildApplicationCommands:\r\n (applicationId: string, guildId: string) =>\r\n `/applications/${snowflake(applicationId, \"Application ID\")}/guilds/${snowflake(guildId, \"Guild ID\")}/commands`,\r\n /** Returns a single guild application command. @param applicationId Application identifier. @param guildId Guild identifier. @param commandId Command identifier. @returns Guild command route. */ guildApplicationCommand:\r\n (applicationId: string, guildId: string, commandId: string) =>\r\n `/applications/${snowflake(applicationId, \"Application ID\")}/guilds/${snowflake(guildId, \"Guild ID\")}/commands/${snowflake(commandId, \"Command ID\")}`,\r\n /** Returns an interaction callback endpoint. @param interactionId Interaction identifier. @param token Interaction token. @returns Interaction callback route. */ interactionCallback:\r\n (interactionId: string, token: string) =>\r\n `/interactions/${snowflake(interactionId, \"Interaction ID\")}/${encodeURIComponent(token)}/callback`,\r\n /** Returns the original interaction response endpoint. @param applicationId Application identifier. @param token Interaction token. @returns Original-response route. */ interactionOriginalResponse:\r\n (applicationId: string, token: string) =>\r\n `/webhooks/${snowflake(applicationId, \"Application ID\")}/${encodeURIComponent(token)}/messages/@original`,\r\n\r\n /** Returns public archived threads for a channel. @param channelId Channel identifier. @returns Public-archive route. */ channelPublicArchivedThreads:\r\n (channelId: string) =>\r\n `/channels/${snowflake(channelId, \"Channel ID\")}/threads/archived/public`,\r\n /** Returns private archived threads for a channel. @param channelId Channel identifier. @returns Private-archive route. */ channelPrivateArchivedThreads:\r\n (channelId: string) =>\r\n `/channels/${snowflake(channelId, \"Channel ID\")}/threads/archived/private`,\r\n /** Returns a thread's members. @param threadId Thread identifier. @returns Thread-member route. */ threadMembers:\r\n (threadId: string) =>\r\n `/channels/${snowflake(threadId, \"Thread ID\")}/thread-members`,\r\n /** Returns guild scheduled events. @param guildId Guild identifier. @returns Scheduled-event collection route. */ guildScheduledEvents:\r\n (guildId: string) =>\r\n `/guilds/${snowflake(guildId, \"Guild ID\")}/scheduled-events`,\r\n /** Returns one guild scheduled event. @param guildId Guild identifier. @param eventId Event identifier. @returns Scheduled-event route. */ guildScheduledEvent:\r\n (guildId: string, eventId: string) =>\r\n `/guilds/${snowflake(guildId, \"Guild ID\")}/scheduled-events/${snowflake(eventId, \"Event ID\")}`,\r\n /** Returns guild automod rules. @param guildId Guild identifier. @returns Automod-rule collection route. */ guildAutoModerationRules:\r\n (guildId: string) =>\r\n `/guilds/${snowflake(guildId, \"Guild ID\")}/auto-moderation/rules`,\r\n /** Returns one automod rule. @param guildId Guild identifier. @param ruleId Rule identifier. @returns Automod-rule route. */ guildAutoModerationRule:\r\n (guildId: string, ruleId: string) =>\r\n `/guilds/${snowflake(guildId, \"Guild ID\")}/auto-moderation/rules/${snowflake(ruleId, \"Rule ID\")}`,\r\n /** Returns current voice regions. @returns Voice-region route. */ voiceRegions:\r\n () => \"/voice/regions\",\r\n /** Returns the generic Gateway endpoint. @returns Gateway route. */ gateway:\r\n () => \"/gateway\",\r\n /** Returns the Gateway endpoint and recommended shard count for bots. @returns Gateway bot route. */ gatewayBot:\r\n () => \"/gateway/bot\",\r\n} as const;\r\n\r\n/** Validates a Discord snowflake route parameter. @param value Candidate identifier. @param field Human-readable field name. @returns The validated identifier. @throws {TypeError} If the identifier is not a Discord snowflake. */\r\nfunction snowflake(value: string, field: string): string {\r\n if (!/^\\d{1,20}$/.test(value))\r\n throw new TypeError(`${field} must be a valid Discord snowflake.`);\r\n return value;\r\n}\r\n",
|
|
11
|
+
"/** Error thrown when Discord rejects a REST request. */\r\nexport class RESTError extends Error {\r\n /** HTTP status returned by Discord. */ public readonly status: number;\r\n /** Discord API error code, when provided. */ public readonly code?: number;\r\n /** Raw Discord validation/error payload. */ public readonly errors?: unknown;\r\n /** HTTP method used for the failed request. */ public readonly method?: string;\r\n /** API path used for the failed request. */ public readonly path?: string;\r\n /** Creates a REST error with request context. @param message Error message. @param status HTTP status. @param code Discord error code. @param errors Raw error payload. @param options Request context and cause. */\r\n public constructor(\r\n message: string,\r\n status: number,\r\n code?: number,\r\n errors?: unknown,\r\n options: { method?: string; path?: string; cause?: unknown } = {},\r\n ) {\r\n super(\r\n message,\r\n options.cause === undefined ? undefined : { cause: options.cause },\r\n );\r\n this.name = \"RESTError\";\r\n this.status = status;\r\n this.code = code;\r\n this.errors = errors;\r\n this.method = options.method;\r\n this.path = options.path;\r\n }\r\n}\r\n\r\n/** Library version and source URL used for the Discord-compliant User-Agent. */\r\nimport packageJson from \"../package.json\" with { type: \"json\" };\r\nconst LIBRARY_VERSION = packageJson.version;\r\nconst LIBRARY_URL = \"https://github.com/Ekretos/lunibee\";\r\nconst USER_AGENT = `DiscordBot (${LIBRARY_URL}, ${packageJson.version})`;\r\n\r\n/** Internal state shared by requests mapped to one Discord rate-limit bucket. */\r\ntype Bucket = { remaining: number; resetAt: number; queue: Promise<void> };\r\n/** Options controlling an individual REST request. */\r\nexport interface RESTRequestOptions {\r\n /** Abort signal used to cancel the request and any queued wait. */ signal?: AbortSignal;\r\n}\r\n\r\nexport interface RESTFileAttachment {\r\n name: string;\r\n data: Blob | Uint8Array | ArrayBuffer;\r\n contentType?: string;\r\n}\r\n\r\n/** Configures which REST failures may be retried. */\r\nexport interface RetryPolicy {\r\n /** Maximum retry attempts. */ maxRetries: number;\r\n /** Determines whether a request may be retried. @param method HTTP method. @param status HTTP status, or zero for transport errors. @returns True when retrying is safe under the policy. */ shouldRetry(\r\n method: string,\r\n status: number,\r\n ): boolean;\r\n /** Calculates delay before the next attempt. @param attempt Zero-based retry number. @param retryAfter Server-provided delay, when available. @returns Delay in milliseconds. */ getDelay(\r\n attempt: number,\r\n retryAfter?: number,\r\n ): number;\r\n}\r\n/** Creates the default conservative REST retry policy. @param maxRetries Maximum retries. @returns Retry policy that retries rate limits and idempotent transient failures. @throws {TypeError} If maxRetries is negative or not finite. */\r\nexport function createRetryPolicy(maxRetries = 2): RetryPolicy {\r\n if (!Number.isFinite(maxRetries) || maxRetries < 0)\r\n throw new TypeError(\"maxRetries must be a non-negative finite number.\");\r\n return {\r\n maxRetries: Math.floor(maxRetries),\r\n shouldRetry(method, status) {\r\n const normalized = method.toUpperCase();\r\n return (\r\n status === 429 ||\r\n (status >= 500 &&\r\n status <= 599 &&\r\n [\"GET\", \"HEAD\", \"PUT\", \"DELETE\"].includes(normalized))\r\n );\r\n },\r\n getDelay(attempt, retryAfter) {\r\n if (retryAfter !== undefined) return Math.max(0, retryAfter * 1000);\r\n return Math.min(10_000, 500 * 2 ** attempt) + Math.random() * 250;\r\n },\r\n };\r\n}\r\n\r\n/** Bun-native REST transport with Discord bucket-aware rate limiting, retries, and cancellation. */\r\nexport class REST {\r\n readonly #baseURL: string;\r\n readonly #timeout: number;\r\n readonly #retryPolicy: RetryPolicy;\r\n #token?: string;\r\n #globalResetAt = 0;\r\n readonly #buckets = new Map<string, Bucket>();\r\n readonly #routeBuckets = new Map<string, string>();\r\n /** Creates a REST transport. @param options Transport configuration. @throws {TypeError} If retry configuration is invalid. */\r\n public constructor(\r\n options: {\r\n token?: string;\r\n timeout?: number;\r\n retries?: number;\r\n retryPolicy?: RetryPolicy;\r\n baseURL?: string;\r\n } = {},\r\n ) {\r\n this.#token = options.token;\r\n this.#timeout = Math.max(1, options.timeout ?? 15_000);\r\n this.#retryPolicy =\r\n options.retryPolicy ?? createRetryPolicy(options.retries ?? 2);\r\n this.#baseURL = (options.baseURL ?? \"https://discord.com/api/v10\").replace(\r\n /\\/$/,\r\n \"\",\r\n );\r\n }\r\n /** Sets the authentication token. @param token Discord bot token. @returns Nothing. @throws {TypeError} If token is empty. */\r\n public setToken(token: string): void {\r\n if (!token.trim()) throw new TypeError(\"A Discord bot token is required.\");\r\n this.#token = token;\r\n }\r\n /** Executes an HTTP request with Discord bucket/global rate limits, retry handling, and AbortSignal support.\r\n * Accepts a JSON body, a FormData body (for file uploads), or undefined.\r\n * @param method HTTP method.\r\n * @param path API path.\r\n * @param body Optional JSON body, FormData for file uploads, or undefined.\r\n * @param options Cancellation options.\r\n * @returns Decoded response body.\r\n * @throws {RESTError} If Discord or transport rejects the request.\r\n */\r\n public async request<T>(\r\n method: string,\r\n path: string,\r\n body?: unknown,\r\n options: RESTRequestOptions = {},\r\n ): Promise<T> {\r\n const normalizedMethod = method.toUpperCase();\r\n if (!normalizedMethod) throw new TypeError(\"REST method is required.\");\r\n if (!path.startsWith(\"/\"))\r\n throw new TypeError(\"REST paths must start with '/'.\");\r\n const route = `${normalizedMethod}:${this.#normalizeRoute(path)}`;\r\n let bucketKey = this.#routeBuckets.get(route) ?? route;\r\n let bucket = this.#buckets.get(bucketKey) ?? {\r\n remaining: 1,\r\n resetAt: 0,\r\n queue: Promise.resolve(),\r\n };\r\n this.#buckets.set(bucketKey, bucket);\r\n const previous = bucket.queue;\r\n let release!: () => void;\r\n bucket.queue = new Promise((resolve) => {\r\n release = resolve;\r\n });\r\n await this.#abortable(previous, options.signal, path);\r\n try {\r\n for (\r\n let attempt = 0;\r\n attempt <= this.#retryPolicy.maxRetries;\r\n attempt++\r\n ) {\r\n await this.#wait(bucket, options.signal, path);\r\n await this.#waitGlobal(options.signal, path);\r\n const controller = new AbortController();\r\n const onAbort = () => controller.abort(options.signal?.reason);\r\n if (options.signal?.aborted)\r\n throw this.#abortError(path, options.signal.reason);\r\n options.signal?.addEventListener(\"abort\", onAbort, { once: true });\r\n const timer = setTimeout(\r\n () =>\r\n controller.abort(\r\n new DOMException(\"REST request timeout\", \"TimeoutError\"),\r\n ),\r\n this.#timeout,\r\n );\r\n // Build headers and body based on whether this is a multipart request\r\n const isFormData =\r\n typeof FormData !== \"undefined\" && body instanceof FormData;\r\n const headers: Record<string, string> = {\r\n ...(this.#token ? { Authorization: `Bot ${this.#token}` } : {}),\r\n \"User-Agent\": USER_AGENT,\r\n };\r\n if (!isFormData) headers[\"Content-Type\"] = \"application/json\";\r\n const fetchBody = isFormData\r\n ? (body as FormData)\r\n : body === undefined\r\n ? undefined\r\n : JSON.stringify(body);\r\n try {\r\n const response = await fetch(`${this.#baseURL}${path}`, {\r\n method: normalizedMethod,\r\n headers,\r\n body: fetchBody,\r\n signal: controller.signal,\r\n });\r\n bucket = this.#update(response, bucket, route, bucketKey);\r\n bucketKey = this.#routeBuckets.get(route) ?? bucketKey;\r\n const payload = await this.#readPayload(response);\r\n if (response.ok)\r\n return (response.status === 204 ? undefined : payload) as T;\r\n const data = this.#errorData(payload);\r\n const retryAfter =\r\n response.status === 429\r\n ? this.#retryAfter(response, data)\r\n : undefined;\r\n if (data.global && retryAfter !== undefined)\r\n this.#globalResetAt = Date.now() + retryAfter * 1000;\r\n if (\r\n attempt < this.#retryPolicy.maxRetries &&\r\n this.#retryPolicy.shouldRetry(normalizedMethod, response.status)\r\n ) {\r\n await this.#sleep(\r\n this.#retryPolicy.getDelay(attempt, retryAfter),\r\n options.signal,\r\n path,\r\n );\r\n continue;\r\n }\r\n throw new RESTError(\r\n data.message ??\r\n response.statusText ??\r\n `Discord REST request failed with status ${response.status}`,\r\n response.status,\r\n data.code,\r\n payload,\r\n { method: normalizedMethod, path },\r\n );\r\n } catch (error) {\r\n if (error instanceof RESTError) throw error;\r\n if (options.signal?.aborted)\r\n throw this.#abortError(path, options.signal.reason);\r\n const isTimeout =\r\n error instanceof DOMException &&\r\n (error.name === \"TimeoutError\" || error.name === \"AbortError\");\r\n if (\r\n !isTimeout &&\r\n attempt < this.#retryPolicy.maxRetries &&\r\n this.#retryPolicy.shouldRetry(normalizedMethod, 0)\r\n ) {\r\n await this.#sleep(\r\n this.#retryPolicy.getDelay(attempt),\r\n options.signal,\r\n path,\r\n );\r\n continue;\r\n }\r\n throw new RESTError(\r\n isTimeout\r\n ? `Discord REST request timed out after ${this.#timeout}ms`\r\n : \"Discord REST request failed\",\r\n 0,\r\n undefined,\r\n undefined,\r\n { method: normalizedMethod, path, cause: error },\r\n );\r\n } finally {\r\n clearTimeout(timer);\r\n options.signal?.removeEventListener(\"abort\", onAbort);\r\n }\r\n }\r\n throw new RESTError(\r\n \"Discord REST request exhausted its retry attempts\",\r\n 0,\r\n undefined,\r\n undefined,\r\n { method: normalizedMethod, path },\r\n );\r\n } finally {\r\n release();\r\n }\r\n }\r\n /** Sends a GET request. @param path API path. @param options Cancellation options. @returns Decoded response. @throws {RESTError} When the request fails. */ public get<\r\n T,\r\n >(path: string, options?: RESTRequestOptions): Promise<T> {\r\n return this.request<T>(\"GET\", path, undefined, options);\r\n }\r\n /** Sends a POST request. @param path API path. @param body Optional JSON body. @param options Cancellation options. @returns Decoded response. @throws {RESTError} When the request fails. */ public post<\r\n T,\r\n >(path: string, body?: unknown, options?: RESTRequestOptions): Promise<T> {\r\n return this.request<T>(\"POST\", path, body, options);\r\n }\r\n /** Sends a PATCH request. @param path API path. @param body Optional JSON body. @param options Cancellation options. @returns Decoded response. @throws {RESTError} When the request fails. */ public patch<\r\n T,\r\n >(path: string, body?: unknown, options?: RESTRequestOptions): Promise<T> {\r\n return this.request<T>(\"PATCH\", path, body, options);\r\n }\r\n /** Sends a PUT request. @param path API path. @param body Optional JSON body. @param options Cancellation options. @returns Decoded response. @throws {RESTError} When the request fails. */ public put<\r\n T,\r\n >(path: string, body?: unknown, options?: RESTRequestOptions): Promise<T> {\r\n return this.request<T>(\"PUT\", path, body, options);\r\n }\r\n /** Sends a DELETE request. @param path API path. @param options Cancellation options. @returns Decoded response. @throws {RESTError} When the request fails. */ public delete<\r\n T,\r\n >(path: string, options?: RESTRequestOptions): Promise<T> {\r\n return this.request<T>(\"DELETE\", path, undefined, options);\r\n }\r\n /**\r\n * Builds a multipart form with a JSON payload and file attachments.\r\n */\r\n #fileForm(payload: unknown, files: RESTFileAttachment[]): FormData {\r\n const form = new FormData();\r\n form.append(\"payload_json\", JSON.stringify(payload));\r\n for (let i = 0; i < files.length; i++) {\r\n const file = files[i]!;\r\n const blob =\r\n file.data instanceof Blob\r\n ? file.data\r\n : new Blob([file.data as ArrayBuffer], {\r\n type: file.contentType ?? \"application/octet-stream\",\r\n });\r\n form.append(`files[${i}]`, blob, file.name);\r\n }\r\n return form;\r\n }\r\n\r\n /**\r\n * Sends a multipart/form-data POST request for file uploads.\r\n * Attaches a JSON payload as `payload_json` and files as additional fields.\r\n * @param path API path.\r\n * @param payload JSON payload (e.g. message content, embeds).\r\n * @param files Array of file attachments.\r\n * @param options Cancellation options.\r\n * @returns Decoded response.\r\n * @throws {RESTError} When the request fails.\r\n */\r\n public postWithFiles<T>(\r\n path: string,\r\n payload: unknown,\r\n files: RESTFileAttachment[],\r\n options?: RESTRequestOptions,\r\n ): Promise<T> {\r\n return this.request<T>(\"POST\", path, this.#fileForm(payload, files), options);\r\n }\r\n\r\n /**\r\n * Sends a multipart/form-data PATCH request for editing messages with files.\r\n * @param path API path.\r\n * @param payload JSON payload.\r\n * @param files Array of file attachments.\r\n * @param options Cancellation options.\r\n * @returns Decoded response.\r\n * @throws {RESTError} When the request fails.\r\n */\r\n public patchWithFiles<T>(\r\n path: string,\r\n payload: unknown,\r\n files: RESTFileAttachment[],\r\n options?: RESTRequestOptions,\r\n ): Promise<T> {\r\n return this.request<T>(\"PATCH\", path, this.#fileForm(payload, files), options);\r\n }\r\n /** Waits for a route bucket while respecting cancellation. @param bucket Bucket state. @param signal Optional cancellation signal. @param path Request path for error context. @returns Promise fulfilled when sending is permitted. @throws {RESTError} If the request is aborted. */\r\n async #wait(\r\n bucket: Bucket,\r\n signal: AbortSignal | undefined,\r\n path: string,\r\n ): Promise<void> {\r\n const delay = bucket.resetAt - Date.now();\r\n if (bucket.remaining <= 0 && delay > 0)\r\n await this.#sleep(delay, signal, path);\r\n }\r\n /** Waits for the global Discord rate limit while respecting cancellation. @param signal Optional cancellation signal. @param path Request path for error context. @returns Promise fulfilled when the global limit expires. @throws {RESTError} If the request is aborted. */\r\n async #waitGlobal(\r\n signal: AbortSignal | undefined,\r\n path: string,\r\n ): Promise<void> {\r\n const delay = this.#globalResetAt - Date.now();\r\n if (delay > 0) await this.#sleep(delay, signal, path);\r\n }\r\n /** Waits for a delay or aborts immediately. @param delay Delay in milliseconds. @param signal Optional cancellation signal. @param path Request path. @returns Promise fulfilled after delay. @throws {RESTError} If aborted. */\r\n async #sleep(\r\n delay: number,\r\n signal: AbortSignal | undefined,\r\n path: string,\r\n ): Promise<void> {\r\n if (delay <= 0) return;\r\n await new Promise<void>((resolve, reject) => {\r\n const timer = setTimeout(resolve, delay);\r\n const abort = () => {\r\n clearTimeout(timer);\r\n reject(this.#abortError(path, signal?.reason));\r\n };\r\n if (signal?.aborted) return abort();\r\n signal?.addEventListener(\"abort\", abort, { once: true });\r\n });\r\n }\r\n /** Waits for a queued request or aborts. @param promise Queue predecessor. @param signal Optional cancellation signal. @param path Request path. @returns Promise fulfilled when predecessor releases. @throws {RESTError} If aborted. */\r\n async #abortable(\r\n promise: Promise<void>,\r\n signal: AbortSignal | undefined,\r\n path: string,\r\n ): Promise<void> {\r\n if (!signal) return promise;\r\n if (signal.aborted) throw this.#abortError(path, signal.reason);\r\n return Promise.race([\r\n promise,\r\n new Promise<void>((_, reject) =>\r\n signal.addEventListener(\r\n \"abort\",\r\n () => reject(this.#abortError(path, signal.reason)),\r\n { once: true },\r\n ),\r\n ),\r\n ]);\r\n }\r\n /** Creates a consistent cancellation error. @param path Request path. @param reason Abort reason. @returns REST cancellation error. */\r\n #abortError(path: string, reason: unknown): RESTError {\r\n return new RESTError(\r\n reason instanceof Error\r\n ? reason.message\r\n : \"Discord REST request was aborted\",\r\n 0,\r\n undefined,\r\n undefined,\r\n { path, cause: reason },\r\n );\r\n }\r\n /** Reads a Discord response payload. @param response HTTP response. @returns JSON or text payload. */\r\n async #readPayload(response: Response): Promise<unknown> {\r\n if (response.status === 204) return undefined;\r\n const contentType = response.headers.get(\"content-type\") ?? \"\";\r\n if (contentType.includes(\"application/json\"))\r\n return response.json().catch(() => undefined);\r\n return response.text().catch(() => undefined);\r\n }\r\n /** Extracts retry metadata from a Discord payload. @param payload Response payload. @returns Normalized error metadata. */\r\n #errorData(payload: unknown): {\r\n message?: string;\r\n code?: number;\r\n retry_after?: number;\r\n global?: boolean;\r\n } {\r\n if (!payload || typeof payload !== \"object\") return {};\r\n const data = payload as Record<string, unknown>;\r\n return {\r\n message: typeof data.message === \"string\" ? data.message : undefined,\r\n code: typeof data.code === \"number\" ? data.code : undefined,\r\n retry_after:\r\n typeof data.retry_after === \"number\" ? data.retry_after : undefined,\r\n global: data.global === true,\r\n };\r\n }\r\n /** Resolves Retry-After from headers or JSON. @param response HTTP response. @param data Parsed response metadata. @returns Retry delay in seconds. */\r\n #retryAfter(response: Response, data: { retry_after?: number }): number {\r\n const header = Number(response.headers.get(\"Retry-After\"));\r\n const retryAfter =\r\n data.retry_after ?? (Number.isFinite(header) ? header : 1);\r\n return Math.max(0, retryAfter);\r\n }\r\n /** Normalizes Discord routes for stable bucket discovery. @param path API path. @returns Normalized route. */\r\n #normalizeRoute(path: string): string {\r\n const queryIndex = path.indexOf(\"?\");\r\n const routePath = queryIndex === -1 ? path : path.slice(0, queryIndex);\r\n return routePath.replace(/\\/\\d+(?=\\/|$)/g, \"/:id\");\r\n }\r\n /** Updates bucket state from Discord's rate-limit headers and records the server bucket hash. @param response HTTP response. @param bucket Current bucket. @param route Normalized local route key. @param bucketKey Current bucket identifier. @returns Bucket state used for subsequent attempts. */\r\n #update(\r\n response: Response,\r\n bucket: Bucket,\r\n route: string,\r\n bucketKey: string,\r\n ): Bucket {\r\n const serverBucket = response.headers.get(\"X-RateLimit-Bucket\");\r\n if (serverBucket) {\r\n this.#routeBuckets.set(route, serverBucket);\r\n if (serverBucket !== bucketKey) {\r\n const shared = this.#buckets.get(serverBucket) ?? bucket;\r\n this.#buckets.set(serverBucket, shared);\r\n bucket = shared;\r\n }\r\n }\r\n const remaining = Number(response.headers.get(\"X-RateLimit-Remaining\"));\r\n const resetAfter = Number(response.headers.get(\"X-RateLimit-Reset-After\"));\r\n const reset = Number(response.headers.get(\"X-RateLimit-Reset\"));\r\n if (Number.isFinite(remaining)) bucket.remaining = Math.max(0, remaining);\r\n if (Number.isFinite(resetAfter))\r\n bucket.resetAt = Date.now() + Math.max(0, resetAfter) * 1000;\r\n else if (Number.isFinite(reset)) bucket.resetAt = reset * 1000;\r\n if (response.status === 429) {\r\n const retryAfter = Number(response.headers.get(\"Retry-After\"));\r\n if (Number.isFinite(retryAfter))\r\n bucket.resetAt = Math.max(\r\n bucket.resetAt,\r\n Date.now() + retryAfter * 1000,\r\n );\r\n }\r\n if (response.headers.get(\"X-RateLimit-Global\") === \"true\") {\r\n const retryAfter = Number(response.headers.get(\"Retry-After\"));\r\n if (Number.isFinite(retryAfter))\r\n this.#globalResetAt = Math.max(\r\n this.#globalResetAt,\r\n Date.now() + retryAfter * 1000,\r\n );\r\n }\r\n return bucket;\r\n }\r\n}\r\n\r\nexport { Routes } from \"./routes.js\";\r\n\r\nexport {\r\n WebhookClient,\r\n type WebhookClientOptions,\r\n type WebhookMessageOptions,\r\n} from \"./webhook.js\";\r\n",
|
|
12
|
+
"/** Common Discord snowflake-backed structure. */\r\nexport class BaseStructure {\r\n public readonly id: string;\r\n public constructor(id: string) {\r\n if (!/^\\d{1,20}$/.test(id))\r\n throw new TypeError(\"A Discord structure requires a valid snowflake ID.\");\r\n this.id = id;\r\n }\r\n /** Returns the snowflake ID as a string. */\r\n public toString(): string {\r\n return this.id;\r\n }\r\n /** Returns the timestamp this snowflake was created at. */\r\n public get createdAt(): Date {\r\n return new Date(Number((BigInt(this.id) >> 22n) + 1420070400000n));\r\n }\r\n}\r\n\r\nexport interface ResourceContext {\r\n sendMessage(\r\n channelId: string,\r\n options: Record<string, unknown> & { content?: string },\r\n ): Promise<import(\"./index.js\").Message>;\r\n editMessage(\r\n channelId: string,\r\n messageId: string,\r\n options: Record<string, unknown> & { content?: string },\r\n ): Promise<import(\"./index.js\").Message>;\r\n deleteMessage(channelId: string, messageId: string): Promise<void>;\r\n crosspostMessage(\r\n channelId: string,\r\n messageId: string,\r\n ): Promise<import(\"./index.js\").Message>;\r\n editChannel?(\r\n channelId: string,\r\n options: Record<string, unknown>,\r\n ): Promise<import(\"./base.js\").Channel>;\r\n deleteChannel?(channelId: string): Promise<void>;\r\n addReaction?(\r\n channelId: string,\r\n messageId: string,\r\n emoji: string,\r\n ): Promise<void>;\r\n removeOwnReaction?(\r\n channelId: string,\r\n messageId: string,\r\n emoji: string,\r\n ): Promise<void>;\r\n removeReaction?(\r\n channelId: string,\r\n messageId: string,\r\n emoji: string,\r\n userId: string,\r\n ): Promise<void>;\r\n removeAllReactions?(channelId: string, messageId: string): Promise<void>;\r\n pinMessage?(channelId: string, messageId: string): Promise<void>;\r\n unpinMessage?(channelId: string, messageId: string): Promise<void>;\r\n}\r\n\r\n// ─── CDN helpers ──────────────────────────────────────────────────────────────\r\n\r\nconst CDN_BASE = \"https://cdn.discordapp.com\";\r\n\r\n/** Options for CDN image URLs. */\r\nexport interface ImageURLOptions {\r\n extension?: \"png\" | \"jpg\" | \"webp\" | \"gif\" | \"jpeg\";\r\n size?: 16 | 32 | 64 | 128 | 256 | 512 | 1024 | 2048 | 4096;\r\n forceStatic?: boolean;\r\n}\r\n\r\nfunction cdnURL(\r\n path: string,\r\n hash: string,\r\n options: ImageURLOptions = {},\r\n): string {\r\n const isAnimated = hash.startsWith(\"a_\") && !options.forceStatic;\r\n const ext = options.extension ?? (isAnimated ? \"gif\" : \"png\");\r\n const size = options.size ? `?size=${options.size}` : \"\";\r\n return `${CDN_BASE}${path}/${hash}.${ext}${size}`;\r\n}\r\n\r\n// ─── User ─────────────────────────────────────────────────────────────────────\r\n\r\nexport class User extends BaseStructure {\r\n public username: string;\r\n public globalName: string | null;\r\n public avatar: string | null;\r\n public bot: boolean;\r\n public system: boolean;\r\n public flags: number;\r\n public discriminator: string | null;\r\n public constructor(data: import(\"@lunibee/types\").UserData) {\r\n super(data.id);\r\n if (!data.username)\r\n throw new TypeError(\"A Discord user requires a username.\");\r\n this.username = data.username;\r\n this.globalName = data.global_name ?? null;\r\n this.avatar = data.avatar ?? null;\r\n this.bot = data.bot ?? false;\r\n this.system = data.system ?? false;\r\n this.flags = data.public_flags ?? 0;\r\n this.discriminator = data.discriminator && data.discriminator !== \"0\" ? data.discriminator : null;\r\n }\r\n /** Effective display name — global name, falling back to username. */\r\n public get displayName(): string {\r\n return this.globalName ?? this.username;\r\n }\r\n /** Returns the user's avatar URL, or null if they have no avatar. */\r\n public avatarURL(options: ImageURLOptions = {}): string | null {\r\n if (!this.avatar) return null;\r\n return cdnURL(`/avatars/${this.id}`, this.avatar, options);\r\n }\r\n /** Returns the default avatar URL based on the user's discriminator/snowflake. */\r\n public defaultAvatarURL(): string {\r\n const index = this.discriminator\r\n ? Number(this.discriminator) % 5\r\n : Number((BigInt(this.id) >> 22n) % 6n);\r\n return `${CDN_BASE}/embed/avatars/${index}.png`;\r\n }\r\n /** Returns the avatar URL if available, falling back to the default avatar URL. */\r\n public displayAvatarURL(options: ImageURLOptions = {}): string {\r\n return this.avatarURL(options) ?? this.defaultAvatarURL();\r\n }\r\n /** Returns the Discord mention string. Used automatically in template literals. */\r\n public override toString(): string {\r\n return `<@${this.id}>`;\r\n }\r\n}\r\n\r\n// ─── Channel ──────────────────────────────────────────────────────────────────\r\n\r\nexport class Channel extends BaseStructure {\r\n public type: number;\r\n public name?: string | null;\r\n public guildId?: string;\r\n public topic?: string | null;\r\n public parentId?: string | null;\r\n public nsfw?: boolean;\r\n public rateLimitPerUser?: number;\r\n public position?: number;\r\n readonly #context?: ResourceContext;\r\n\r\n /** Creates a channel structure from Discord channel data. */\r\n public constructor(\r\n data: import(\"@lunibee/types\").APIChannel,\r\n context?: ResourceContext,\r\n ) {\r\n super(data.id);\r\n if (!Number.isInteger(data.type) || data.type < 0)\r\n throw new RangeError(\"A Discord channel requires a valid channel type.\");\r\n this.type = data.type;\r\n this.name = data.name;\r\n this.guildId = data.guild_id;\r\n this.topic = data.topic;\r\n this.parentId = data.parent_id;\r\n this.nsfw = data.nsfw;\r\n this.rateLimitPerUser = data.rate_limit_per_user;\r\n this.position = data.position;\r\n this.#context = context;\r\n }\r\n\r\n /** Sends a message to this channel. @param options Message payload. @returns The created message. @throws {Error} If the channel is not attached to a client. */\r\n public sendMessage(\r\n options: Record<string, unknown> & { content?: string },\r\n ): Promise<import(\"./index.js\").Message> {\r\n if (!this.#context)\r\n throw new Error(\"This channel is not attached to a client.\");\r\n return this.#context.sendMessage(this.id, options);\r\n }\r\n\r\n /** Sends a message using Lunibee's concise channel API. @param options Message payload. @returns The created message. @throws {Error} If the channel is not attached to a client. */\r\n public send(\r\n options: Record<string, unknown> & { content?: string },\r\n ): Promise<import(\"./index.js\").Message> {\r\n return this.sendMessage(options);\r\n }\r\n\r\n /** Edits this channel. @param options Channel fields to change. @returns The updated channel. @throws {Error} If the channel is not attached to a client. */\r\n public edit(options: Record<string, unknown>): Promise<Channel> {\r\n if (!this.#context?.editChannel)\r\n throw new Error(\"This channel is not attached to a client.\");\r\n return this.#context.editChannel(this.id, options);\r\n }\r\n\r\n /** Changes only this channel's name. @param name New channel name. @returns The updated channel. @throws {TypeError} If the name is empty. @throws {Error} If the channel is not attached to a client. */\r\n public editName(name: string): Promise<Channel> {\r\n if (!name.trim()) throw new TypeError(\"Channel name cannot be empty.\");\r\n return this.edit({ name });\r\n }\r\n\r\n /** Changes only this channel's topic. @param topic New topic, or null to clear it. @returns The updated channel. @throws {Error} If the channel is not attached to a client. */\r\n public editTopic(topic: string | null): Promise<Channel> {\r\n return this.edit({ topic });\r\n }\r\n\r\n /** Moves this channel to another parent category. @param parentId Parent category ID, or null to remove the parent. @returns The updated channel. @throws {Error} If the channel is not attached to a client. */\r\n public editParent(parentId: string | null): Promise<Channel> {\r\n return this.edit({ parent_id: parentId });\r\n }\r\n\r\n /** Deletes this channel. @returns A promise fulfilled when Discord confirms deletion. @throws {Error} If the channel is not attached to a client. */\r\n public delete(): Promise<void> {\r\n if (!this.#context?.deleteChannel)\r\n throw new Error(\"This channel is not attached to a client.\");\r\n return this.#context.deleteChannel(this.id);\r\n }\r\n\r\n /** Updates this channel using the same resource operation as edit. @param options Channel fields to change. @returns The updated channel. @throws {Error} If the channel is not attached to a client. */\r\n public update(options: Record<string, unknown>): Promise<Channel> {\r\n return this.edit(options);\r\n }\r\n\r\n /** Returns the Discord channel mention string. Used automatically in template literals. */\r\n public override toString(): string {\r\n return `<#${this.id}>`;\r\n }\r\n}\r\n\r\n// ─── Guild ────────────────────────────────────────────────────────────────────\r\n\r\nexport class Guild extends BaseStructure {\r\n public name: string;\r\n public icon: string | null;\r\n public splash: string | null;\r\n public banner: string | null;\r\n public description: string | null;\r\n public preferredLocale: string;\r\n public ownerId?: string;\r\n public features: string[];\r\n public verificationLevel: number;\r\n public premiumTier: number;\r\n public premiumSubscriptionCount: number;\r\n public memberCount?: number;\r\n public approximateMemberCount?: number;\r\n public approximatePresenceCount?: number;\r\n public vanityUrlCode: string | null;\r\n public nsfwLevel: number;\r\n public discoverySplash: string | null;\r\n\r\n public constructor(data: import(\"@lunibee/types\").APIGuild) {\r\n super(data.id);\r\n if (!data.name) throw new TypeError(\"A Discord guild requires a name.\");\r\n this.name = data.name;\r\n this.icon = data.icon ?? null;\r\n this.splash = data.splash ?? null;\r\n this.banner = data.banner ?? null;\r\n this.description = data.description ?? null;\r\n this.preferredLocale = data.preferred_locale ?? \"en-US\";\r\n this.ownerId = data.owner_id;\r\n this.features = data.features ?? [];\r\n this.verificationLevel = data.verification_level ?? 0;\r\n this.premiumTier = data.premium_tier ?? 0;\r\n this.premiumSubscriptionCount = data.premium_subscription_count ?? 0;\r\n this.memberCount = data.member_count ?? data.approximate_member_count;\r\n this.approximateMemberCount = data.approximate_member_count;\r\n this.approximatePresenceCount = data.approximate_presence_count;\r\n this.vanityUrlCode = data.vanity_url_code ?? null;\r\n this.nsfwLevel = data.nsfw_level ?? 0;\r\n this.discoverySplash = data.discovery_splash ?? null;\r\n }\r\n\r\n /** Returns the guild icon URL, or null if no icon is set. */\r\n public iconURL(options: ImageURLOptions = {}): string | null {\r\n if (!this.icon) return null;\r\n return cdnURL(`/icons/${this.id}`, this.icon, options);\r\n }\r\n\r\n /** Returns the guild splash URL, or null if none. */\r\n public splashURL(options: ImageURLOptions = {}): string | null {\r\n if (!this.splash) return null;\r\n return cdnURL(`/splashes/${this.id}`, this.splash, options);\r\n }\r\n\r\n /** Returns the guild banner URL, or null if none. */\r\n public bannerURL(options: ImageURLOptions = {}): string | null {\r\n if (!this.banner) return null;\r\n return cdnURL(`/banners/${this.id}`, this.banner, options);\r\n }\r\n\r\n /** Returns the guild discovery splash URL, or null if none. */\r\n public discoverySplashURL(\r\n options: ImageURLOptions = {},\r\n ): string | null {\r\n if (!this.discoverySplash) return null;\r\n return cdnURL(`/discovery-splashes/${this.id}`, this.discoverySplash, options);\r\n }\r\n\r\n /** Whether the guild has a given feature flag. @param feature Feature string, e.g. \"COMMUNITY\". */\r\n public hasFeature(feature: string): boolean {\r\n return this.features.includes(feature);\r\n }\r\n\r\n /** Whether the guild is a Community server. */\r\n public get isCommunity(): boolean {\r\n return this.hasFeature(\"COMMUNITY\");\r\n }\r\n\r\n /** Whether the guild has a vanity URL. */\r\n public get hasVanityUrl(): boolean {\r\n return this.vanityUrlCode !== null;\r\n }\r\n\r\n /** Returns the guild's vanity invite URL, or null if none. */\r\n public get vanityURL(): string | null {\r\n return this.vanityUrlCode\r\n ? `https://discord.gg/${this.vanityUrlCode}`\r\n : null;\r\n }\r\n\r\n /** Returns a human-readable string representation. */\r\n public override toString(): string {\r\n return this.name;\r\n }\r\n}\r\n",
|
|
13
|
+
"/** Permission bit values exposed by Discord. */\nexport const Permissions = {\n /** Create instant invite permission. */ CreateInstantInvite: 1n << 0n,\n /** Kick members permission. */ KickMembers: 1n << 1n,\n /** Ban members permission. */ BanMembers: 1n << 2n,\n /** Administrator permission. */ Administrator: 1n << 3n,\n /** Manage channels permission. */ ManageChannels: 1n << 4n,\n /** Manage guild permission. */ ManageGuild: 1n << 5n,\n /** Add reactions permission. */ AddReactions: 1n << 6n,\n /** View audit log permission. */ ViewAuditLog: 1n << 7n,\n /** Priority speaker permission. */ PrioritySpeaker: 1n << 8n,\n /** Stream permission. */ Stream: 1n << 9n,\n /** View channel permission. */ ViewChannel: 1n << 10n,\n /** Send messages permission. */ SendMessages: 1n << 11n,\n /** Send TTS messages permission. */ SendTTSMessages: 1n << 12n,\n /** Manage messages permission. */ ManageMessages: 1n << 13n,\n /** Embed links permission. */ EmbedLinks: 1n << 14n,\n /** Attach files permission. */ AttachFiles: 1n << 15n,\n /** Read message history permission. */ ReadMessageHistory: 1n << 16n,\n /** Mention everyone permission. */ MentionEveryone: 1n << 17n,\n /** Use external emojis permission. */ UseExternalEmojis: 1n << 18n,\n /** View guild insights permission. */ ViewGuildInsights: 1n << 19n,\n /** Connect permission. */ Connect: 1n << 20n,\n /** Speak permission. */ Speak: 1n << 21n,\n /** Mute members permission. */ MuteMembers: 1n << 22n,\n /** Deafen members permission. */ DeafenMembers: 1n << 23n,\n /** Move members permission. */ MoveMembers: 1n << 24n,\n /** Use voice activity detection permission. */ UseVAD: 1n << 25n,\n /** Change nickname permission. */ ChangeNickname: 1n << 26n,\n /** Manage nicknames permission. */ ManageNicknames: 1n << 27n,\n /** Manage roles permission. */ ManageRoles: 1n << 28n,\n /** Manage webhooks permission. */ ManageWebhooks: 1n << 29n,\n /** Manage guild expressions permission. */ ManageGuildExpressions: 1n << 30n,\n /** Use application commands permission. */ UseApplicationCommands: 1n << 31n,\n /** Request to speak permission. */ RequestToSpeak: 1n << 32n,\n /** Manage events permission. */ ManageEvents: 1n << 33n,\n /** Manage threads permission. */ ManageThreads: 1n << 34n,\n /** Create public threads permission. */ CreatePublicThreads: 1n << 35n,\n /** Create private threads permission. */ CreatePrivateThreads: 1n << 36n,\n /** Use external stickers permission. */ UseExternalStickers: 1n << 37n,\n /** Send messages in threads permission. */ SendMessagesInThreads: 1n << 38n,\n /** Use embedded activities permission. */ UseEmbeddedActivities: 1n << 39n,\n /** Moderate members permission. */ ModerateMembers: 1n << 40n,\n /** View creator monetization analytics permission. */ ViewCreatorMonetizationAnalytics:\n 1n << 41n,\n /** Use soundboard permission. */ UseSoundboard: 1n << 42n,\n /** Create guild expressions permission. */ CreateGuildExpressions: 1n << 43n,\n /** Create events permission. */ CreateEvents: 1n << 44n,\n /** Use external sounds permission. */ UseExternalSounds: 1n << 45n,\n /** Send voice messages permission. */ SendVoiceMessages: 1n << 46n,\n /** Send polls permission. */ SendPolls: 1n << 49n,\n /** Use external apps permission. */ UseExternalApps: 1n << 50n,\n} as const;\n\n/** Public permission resolvable. */\nexport type PermissionResolvable =\n | bigint\n | number\n | string\n | PermissionName\n | PermissionSet\n | PermissionResolvable[];\n\n/** Immutable Discord permission bitfield. */\nexport class PermissionSet {\n /** Permission bitfield. */ public readonly bitfield: bigint;\n /** Creates a permission set. @param value Initial permission bitfield. @throws {RangeError} If the value is negative. @throws {TypeError} If the value is not a valid integer. */\n public constructor(value: PermissionResolvable = 0n) {\n try {\n if (Array.isArray(value)) {\n let bit = 0n;\n for (const item of value) bit |= this.#resolve(item);\n this.bitfield = bit;\n } else if (value instanceof PermissionSet) {\n this.bitfield = value.bitfield;\n } else {\n const bitfield = this.#resolve(value);\n if (bitfield < 0n)\n throw new RangeError(\"Permission bitfield cannot be negative.\");\n this.bitfield = bitfield;\n }\n } catch (error) {\n if (error instanceof RangeError) throw error;\n throw new TypeError(\n \"Permission bitfield must be a valid non-negative integer.\",\n { cause: error },\n );\n }\n }\n /** Checks whether all supplied permissions are present. @param permissions Permission names or raw bits. @returns True when every requested permission is present. */ public has(\n ...permissions: PermissionResolvable[]\n ): boolean {\n return permissions.every(\n (permission) =>\n (this.bitfield & this.#resolve(permission)) ===\n this.#resolve(permission),\n );\n }\n /** Checks whether any supplied permission is present. @param permissions Permission names or raw bits. @returns True when at least one requested permission is present. */ public any(\n ...permissions: PermissionResolvable[]\n ): boolean {\n return permissions.some(\n (permission) => (this.bitfield & this.#resolve(permission)) !== 0n,\n );\n }\n /** Returns a new set with permissions added. @param permissions Permission names or raw bits. @returns A new permission set. */ public add(\n ...permissions: PermissionResolvable[]\n ): PermissionSet {\n let bitfield = this.bitfield;\n for (const permission of permissions) bitfield |= this.#resolve(permission);\n return new PermissionSet(bitfield);\n }\n /** Returns a new set with permissions removed. @param permissions Permission names or raw bits. @returns A new permission set. */ public remove(\n ...permissions: PermissionResolvable[]\n ): PermissionSet {\n let bitfield = this.bitfield;\n for (const permission of permissions)\n bitfield &= ~this.#resolve(permission);\n return new PermissionSet(bitfield);\n }\n /** Checks equality with another permission set or raw bitfield. @param other Permission set or raw bitfield. @returns True when both values are equal. */ public equals(\n other: PermissionSet | bigint | number | string,\n ): boolean {\n return (\n this.bitfield ===\n (other instanceof PermissionSet\n ? other.bitfield\n : new PermissionSet(other).bitfield)\n );\n }\n /** Returns the decimal permission representation. @returns Decimal permission bitfield. */ public toString(): string {\n return this.bitfield.toString();\n }\n /** Returns known permission names contained in this set. @returns Names of all enabled known permissions. */ public toArray(): PermissionName[] {\n return (Object.keys(Permissions) as PermissionName[]).filter((permission) =>\n this.has(permission),\n );\n }\n /** Resolves a named permission or raw bit. @param permission Permission name or raw bit. @returns Numeric permission bit. */ #resolve(\n permission: PermissionResolvable,\n ): bigint {\n if (permission instanceof PermissionSet) return permission.bitfield;\n if (typeof permission === \"bigint\") return permission;\n if (typeof permission === \"number\") return BigInt(permission);\n if (Array.isArray(permission)) {\n let bit = 0n;\n for (const p of permission) bit |= this.#resolve(p);\n return bit;\n }\n if (typeof permission === \"string\") {\n if (permission in Permissions)\n return (Permissions as Record<string, bigint>)[permission]!;\n const matchedKey = Object.keys(Permissions).find(\n (k) => k.toLowerCase() === permission.toLowerCase(),\n );\n if (matchedKey)\n return (Permissions as Record<string, bigint>)[matchedKey]!;\n return BigInt(permission);\n }\n return 0n;\n }\n}\n\n/** Discord.js-compatible permission bitfield. */\nexport class PermissionsBitField extends PermissionSet {\n /** Creates a permissions bitfield. @param value Initial permission bitfield. */\n public constructor(value: PermissionResolvable = 0n) {\n super(value);\n }\n}\n",
|
|
14
|
+
"import { InteractionResponseType } from \"@lunibee/types\";\r\n\r\n/** Discord interaction type constants. */\r\nexport const InteractionType = {\r\n Ping: 1,\r\n ApplicationCommand: 2,\r\n MessageComponent: 3,\r\n ApplicationCommandAutocomplete: 4,\r\n ModalSubmit: 5,\r\n} as const;\r\n// Re-export for consumers who import from structures directly\r\nexport { InteractionResponseType } from \"@lunibee/types\";\r\n/** Data shared by Discord interactions. */\r\nexport interface InteractionData {\r\n /** Interaction identifier. */ id: string;\r\n /** Application identifier. */ application_id: string;\r\n /** Interaction type. */ type: number;\r\n /** Interaction token. */ token: string;\r\n /** Gateway/API version. */ version?: number;\r\n /** Guild identifier. */ guild_id?: string;\r\n /** Channel identifier. */ channel_id?: string;\r\n /** Interaction-specific data. */ data?: Record<string, unknown>;\r\n [key: string]: unknown;\r\n}\r\n/** Options for an interaction response message. */\r\nexport interface InteractionReplyOptions {\r\n /** Message content. */ content?: string;\r\n /** Whether the response is ephemeral. */ ephemeral?: boolean;\r\n /** Message components. */ components?: unknown[];\r\n /** Message embeds. */ embeds?: unknown[];\r\n /** Discord message flags. */ flags?: number;\r\n [key: string]: unknown;\r\n}\r\n/** Transport required by an interaction structure. */\r\nexport interface InteractionClient {\r\n /** Sends the initial interaction callback. @param id Interaction identifier. @param token Interaction token. @param response Callback payload. @returns Discord response. @throws {Error} When REST fails. */ postInteractionResponse(\r\n id: string,\r\n token: string,\r\n response: InteractionResponse,\r\n ): Promise<unknown>;\r\n /** Edits the original interaction response. @param token Interaction token. @param data Message payload. @returns Discord response. @throws {Error} When REST fails. */ editInteractionReply(\r\n token: string,\r\n data: InteractionReplyOptions,\r\n ): Promise<unknown>;\r\n /** Deletes the original interaction response. @param token Interaction token. @returns Promise fulfilled after deletion. @throws {Error} When REST fails. */ deleteInteractionReply(\r\n token: string,\r\n ): Promise<void>;\r\n /** Sends a follow-up interaction webhook message. @param token Interaction token. @param data Message payload. @returns Discord response. @throws {Error} When REST fails. */ followUpInteraction(\r\n token: string,\r\n data: InteractionReplyOptions,\r\n ): Promise<unknown>;\r\n}\r\n\r\n// ─── Raw option type from Discord ────────────────────────────────────────────\r\n\r\n/** Raw Discord application command interaction data option. */\r\nexport interface APIInteractionDataOption {\r\n name: string;\r\n type: number;\r\n value?: string | number | boolean;\r\n options?: APIInteractionDataOption[];\r\n focused?: boolean;\r\n}\r\n\r\n// ─── CommandOptions resolver ──────────────────────────────────────────────────\r\n\r\n/** Application command option types mirroring Discord's enum. */\r\nconst OptionType = {\r\n SubCommand: 1,\r\n SubCommandGroup: 2,\r\n String: 3,\r\n Integer: 4,\r\n Boolean: 5,\r\n User: 6,\r\n Channel: 7,\r\n Role: 8,\r\n Mentionable: 9,\r\n Number: 10,\r\n Attachment: 11,\r\n} as const;\r\n\r\n/**\r\n * Typed resolver for application command options.\r\n * Attached as `CommandInteraction.options`.\r\n */\r\nexport class CommandOptions {\r\n readonly #options: APIInteractionDataOption[];\r\n readonly #resolved: Record<string, unknown>;\r\n\r\n /** @internal */\r\n public constructor(\r\n options: APIInteractionDataOption[],\r\n resolved: Record<string, unknown> = {},\r\n ) {\r\n let currentOptions = options;\r\n let group: string | null = null;\r\n let sub: string | null = null;\r\n \r\n // Drill down to the deepest options level for nested subcommands\r\n while (currentOptions.length === 1) {\r\n const opt = currentOptions[0]!;\r\n if (opt.type === OptionType.SubCommandGroup) {\r\n group = opt.name;\r\n currentOptions = opt.options ?? [];\r\n } else if (opt.type === OptionType.SubCommand) {\r\n sub = opt.name;\r\n currentOptions = opt.options ?? [];\r\n } else {\r\n break;\r\n }\r\n }\r\n \r\n this.#options = currentOptions;\r\n this.#resolved = resolved;\r\n this.#subcommandGroup = group;\r\n this.#subcommand = sub;\r\n }\r\n \r\n readonly #subcommandGroup: string | null;\r\n readonly #subcommand: string | null;\r\n\r\n /** Finds a raw option by name (case-insensitive). */\r\n #get(name: string): APIInteractionDataOption | undefined {\r\n return this.#options.find(\r\n (o) => o.name.toLowerCase() === name.toLowerCase(),\r\n );\r\n }\r\n\r\n // ── Subcommand resolution ──────────────────────────────────────────────────\r\n\r\n /** Returns the invoked subcommand name, or null if none. */\r\n public getSubcommand(required?: false): string | null;\r\n public getSubcommand(required: true): string;\r\n public getSubcommand(required = false): string | null {\r\n if (!this.#subcommand && required) {\r\n throw new TypeError(\"No subcommand was provided.\");\r\n }\r\n return this.#subcommand;\r\n }\r\n\r\n /** Returns the invoked subcommand group name, or null if none. */\r\n public getSubcommandGroup(required?: false): string | null;\r\n public getSubcommandGroup(required: true): string;\r\n public getSubcommandGroup(required = false): string | null {\r\n if (!this.#subcommandGroup && required) {\r\n throw new TypeError(\"No subcommand group was provided.\");\r\n }\r\n return this.#subcommandGroup;\r\n }\r\n\r\n // ── Primitive value options ────────────────────────────────────────────────\r\n\r\n /** Gets a string option. @param name Option name. @param required If true, throws when missing. */\r\n public getString(name: string, required?: false): string | null;\r\n public getString(name: string, required: true): string;\r\n public getString(name: string, required = false): string | null {\r\n const opt = this.#get(name);\r\n if (!opt || opt.type !== OptionType.String) {\r\n if (required)\r\n throw new TypeError(`Required option \"${name}\" (string) is missing.`);\r\n return null;\r\n }\r\n return typeof opt.value === \"string\" ? opt.value : null;\r\n }\r\n\r\n /** Gets an integer option. @param name Option name. @param required If true, throws when missing. */\r\n public getInteger(name: string, required?: false): number | null;\r\n public getInteger(name: string, required: true): number;\r\n public getInteger(name: string, required = false): number | null {\r\n const opt = this.#get(name);\r\n if (!opt || opt.type !== OptionType.Integer) {\r\n if (required)\r\n throw new TypeError(`Required option \"${name}\" (integer) is missing.`);\r\n return null;\r\n }\r\n return typeof opt.value === \"number\" ? Math.trunc(opt.value) : null;\r\n }\r\n\r\n /** Gets a number (float) option. @param name Option name. @param required If true, throws when missing. */\r\n public getNumber(name: string, required?: false): number | null;\r\n public getNumber(name: string, required: true): number;\r\n public getNumber(name: string, required = false): number | null {\r\n const opt = this.#get(name);\r\n if (!opt || opt.type !== OptionType.Number) {\r\n if (required)\r\n throw new TypeError(`Required option \"${name}\" (number) is missing.`);\r\n return null;\r\n }\r\n return typeof opt.value === \"number\" ? opt.value : null;\r\n }\r\n\r\n /** Gets a boolean option. @param name Option name. @param required If true, throws when missing. */\r\n public getBoolean(name: string, required?: false): boolean | null;\r\n public getBoolean(name: string, required: true): boolean;\r\n public getBoolean(name: string, required = false): boolean | null {\r\n const opt = this.#get(name);\r\n if (!opt || opt.type !== OptionType.Boolean) {\r\n if (required)\r\n throw new TypeError(`Required option \"${name}\" (boolean) is missing.`);\r\n return null;\r\n }\r\n return typeof opt.value === \"boolean\" ? opt.value : null;\r\n }\r\n\r\n // ── Resolved entity options ────────────────────────────────────────────────\r\n\r\n /** Gets the raw resolved user data for a user option. @param name Option name. @param required If true, throws when missing. */\r\n public getUser(\r\n name: string,\r\n required?: false,\r\n ): Record<string, unknown> | null;\r\n public getUser(name: string, required: true): Record<string, unknown>;\r\n public getUser(\r\n name: string,\r\n required = false,\r\n ): Record<string, unknown> | null {\r\n const opt = this.#get(name);\r\n if (!opt || opt.type !== OptionType.User) {\r\n if (required)\r\n throw new TypeError(`Required option \"${name}\" (user) is missing.`);\r\n return null;\r\n }\r\n const userId = String(opt.value);\r\n const resolved = (this.#resolved as any)?.users?.[userId] ?? null;\r\n if (!resolved && required)\r\n throw new TypeError(`Resolved user for option \"${name}\" is missing.`);\r\n return resolved;\r\n }\r\n\r\n /** Gets the raw resolved channel data for a channel option. @param name Option name. @param required If true, throws when missing. */\r\n public getChannel(\r\n name: string,\r\n required?: false,\r\n ): Record<string, unknown> | null;\r\n public getChannel(name: string, required: true): Record<string, unknown>;\r\n public getChannel(\r\n name: string,\r\n required = false,\r\n ): Record<string, unknown> | null {\r\n const opt = this.#get(name);\r\n if (!opt || opt.type !== OptionType.Channel) {\r\n if (required)\r\n throw new TypeError(`Required option \"${name}\" (channel) is missing.`);\r\n return null;\r\n }\r\n const channelId = String(opt.value);\r\n const resolved = (this.#resolved as any)?.channels?.[channelId] ?? null;\r\n if (!resolved && required)\r\n throw new TypeError(`Resolved channel for option \"${name}\" is missing.`);\r\n return resolved;\r\n }\r\n\r\n /** Gets the raw resolved role data for a role option. @param name Option name. @param required If true, throws when missing. */\r\n public getRole(\r\n name: string,\r\n required?: false,\r\n ): Record<string, unknown> | null;\r\n public getRole(name: string, required: true): Record<string, unknown>;\r\n public getRole(\r\n name: string,\r\n required = false,\r\n ): Record<string, unknown> | null {\r\n const opt = this.#get(name);\r\n if (!opt || opt.type !== OptionType.Role) {\r\n if (required)\r\n throw new TypeError(`Required option \"${name}\" (role) is missing.`);\r\n return null;\r\n }\r\n const roleId = String(opt.value);\r\n const resolved = (this.#resolved as any)?.roles?.[roleId] ?? null;\r\n if (!resolved && required)\r\n throw new TypeError(`Resolved role for option \"${name}\" is missing.`);\r\n return resolved;\r\n }\r\n\r\n /** Gets the raw resolved user or role data for a mentionable option. @param name Option name. @param required If true, throws when missing. */\r\n public getMentionable(\r\n name: string,\r\n required?: false,\r\n ): Record<string, unknown> | null;\r\n public getMentionable(name: string, required: true): Record<string, unknown>;\r\n public getMentionable(\r\n name: string,\r\n required = false,\r\n ): Record<string, unknown> | null {\r\n const opt = this.#get(name);\r\n if (!opt || opt.type !== OptionType.Mentionable) {\r\n if (required)\r\n throw new TypeError(\r\n `Required option \"${name}\" (mentionable) is missing.`,\r\n );\r\n return null;\r\n }\r\n const id = String(opt.value);\r\n const resolved =\r\n (this.#resolved as any)?.users?.[id] ??\r\n (this.#resolved as any)?.roles?.[id] ??\r\n null;\r\n if (!resolved && required)\r\n throw new TypeError(\r\n `Resolved mentionable for option \"${name}\" is missing.`,\r\n );\r\n return resolved;\r\n }\r\n\r\n /** Gets the raw resolved attachment data for an attachment option. @param name Option name. @param required If true, throws when missing. */\r\n public getAttachment(\r\n name: string,\r\n required?: false,\r\n ): Record<string, unknown> | null;\r\n public getAttachment(name: string, required: true): Record<string, unknown>;\r\n public getAttachment(\r\n name: string,\r\n required = false,\r\n ): Record<string, unknown> | null {\r\n const opt = this.#get(name);\r\n if (!opt || opt.type !== OptionType.Attachment) {\r\n if (required)\r\n throw new TypeError(\r\n `Required option \"${name}\" (attachment) is missing.`,\r\n );\r\n return null;\r\n }\r\n const attachmentId = String(opt.value);\r\n const resolved =\r\n (this.#resolved as any)?.attachments?.[attachmentId] ?? null;\r\n if (!resolved && required)\r\n throw new TypeError(\r\n `Resolved attachment for option \"${name}\" is missing.`,\r\n );\r\n return resolved;\r\n }\r\n\r\n /** Returns the raw option list for advanced use cases. */\r\n public get raw(): readonly APIInteractionDataOption[] {\r\n return this.#options;\r\n }\r\n}\r\n\r\n// ─── Response class ───────────────────────────────────────────────────────────\r\n\r\n/** A Discord interaction callback payload. */\r\nexport class InteractionResponse {\r\n readonly type: number;\r\n readonly data?: InteractionReplyOptions;\r\n /** Creates a response payload. @param type Discord callback type. @param data Optional callback data. @throws {TypeError} If type is not finite. */\r\n public constructor(type: number, data?: InteractionReplyOptions) {\r\n if (!Number.isFinite(type))\r\n throw new TypeError(\"Interaction response type must be finite.\");\r\n this.type = type;\r\n this.data = data;\r\n }\r\n /** Serializes the response for Discord. @returns Discord callback payload. */ public toJSON(): {\r\n type: number;\r\n data?: InteractionReplyOptions;\r\n } {\r\n return this.data === undefined\r\n ? { type: this.type }\r\n : { type: this.type, data: this.data };\r\n }\r\n /** Creates an immediate message response. @param options Response message options. @returns Callback payload. */ public static message(\r\n options: InteractionReplyOptions,\r\n ): InteractionResponse {\r\n const data: InteractionReplyOptions = { ...options };\r\n if (options.ephemeral) {\r\n data.flags = (typeof options.flags === \"number\" ? options.flags : 0) | 64;\r\n }\r\n return new InteractionResponse(\r\n InteractionResponseType.ChannelMessage,\r\n data,\r\n );\r\n }\r\n /** Creates a deferred channel response. @param ephemeral Whether the eventual response is ephemeral. @returns Callback payload. */ public static defer(\r\n ephemeral = false,\r\n ): InteractionResponse {\r\n return new InteractionResponse(\r\n InteractionResponseType.DeferredChannelMessage,\r\n ephemeral ? { flags: 64 } : undefined,\r\n );\r\n }\r\n /** Creates a Pong response. @returns Callback payload. */ public static pong(): InteractionResponse {\r\n return new InteractionResponse(InteractionResponseType.Pong);\r\n }\r\n}\r\n\r\n// ─── Base Interaction ─────────────────────────────────────────────────────────\r\n\r\n/** Base interaction structure. */\r\nexport class Interaction<TData extends InteractionData = InteractionData> {\r\n /** Interaction identifier. */ public readonly id: string;\r\n /** Application identifier. */ public readonly applicationId: string;\r\n /** Interaction token. */ public readonly token: string;\r\n /** Guild identifier. */ public readonly guildId?: string;\r\n /** Channel identifier. */ public readonly channelId?: string;\r\n /** Interaction type. */ public readonly type: number;\r\n /** Raw interaction data. */ public readonly data: TData;\r\n /** Whether the initial response was sent. */ public replied = false;\r\n /** Whether the initial response was deferred. */ public deferred = false;\r\n readonly #client: InteractionClient;\r\n /** Creates an interaction from a Gateway payload. @param client Interaction transport. @param data Gateway interaction payload. @throws {TypeError} If required identifiers are missing. */ public constructor(\r\n client: InteractionClient,\r\n data: TData,\r\n ) {\r\n if (!data.id || !data.token)\r\n throw new TypeError(\"Interaction ID and token are required.\");\r\n this.#client = client;\r\n this.id = data.id;\r\n this.applicationId = data.application_id;\r\n this.token = data.token;\r\n this.guildId = data.guild_id;\r\n this.channelId = data.channel_id;\r\n this.type = data.type;\r\n this.data = data;\r\n }\r\n /** Whether this interaction is an application command. @returns True for application command interactions. */ public isChatInputCommand(): this is CommandInteraction {\r\n return this.type === InteractionType.ApplicationCommand;\r\n }\r\n /** Whether this interaction is a message component. @returns True for component interactions. */ public isMessageComponent(): this is ComponentInteraction {\r\n return this.type === InteractionType.MessageComponent;\r\n }\r\n /** Whether this interaction is a modal submission. @returns True for modal submissions. */ public isModalSubmit(): this is ModalSubmitInteraction {\r\n return this.type === InteractionType.ModalSubmit;\r\n }\r\n /** Whether this interaction is autocomplete. @returns True for autocomplete interactions. */ public isAutocomplete(): this is AutocompleteInteraction {\r\n return this.type === InteractionType.ApplicationCommandAutocomplete;\r\n }\r\n /** Ensures the interaction has not already been acknowledged. @returns Nothing. @throws {Error} When already acknowledged. */ protected assertUnacknowledged(): void {\r\n if (this.replied || this.deferred)\r\n throw new Error(\"Interaction has already been acknowledged.\");\r\n }\r\n /** Ensures the interaction has been acknowledged. @returns Nothing. @throws {Error} When not acknowledged. */ protected assertAcknowledged(): void {\r\n if (!this.replied && !this.deferred)\r\n throw new Error(\"Interaction has not been acknowledged.\");\r\n }\r\n /** Posts a raw interaction response callback. */\r\n protected postResponse(response: InteractionResponse): Promise<unknown> {\r\n return this.#client.postInteractionResponse(this.id, this.token, response);\r\n }\r\n /** Sends the initial interaction response. @param options Response message options. @returns Discord response. @throws {Error} When already acknowledged or REST fails. */ public async reply(\r\n options: InteractionReplyOptions | string,\r\n ): Promise<unknown> {\r\n this.assertUnacknowledged();\r\n const payload =\r\n typeof options === \"string\" ? { content: options } : options;\r\n const result = await this.#client.postInteractionResponse(\r\n this.id,\r\n this.token,\r\n InteractionResponse.message(payload),\r\n );\r\n this.replied = true;\r\n return result;\r\n }\r\n /** Defers the initial interaction response. @param ephemeral Whether the eventual response is ephemeral. @returns Promise fulfilled after acknowledgement. @throws {Error} When already acknowledged or REST fails. */ public async deferReply(\r\n ephemeral = false,\r\n ): Promise<void> {\r\n this.assertUnacknowledged();\r\n await this.#client.postInteractionResponse(\r\n this.id,\r\n this.token,\r\n InteractionResponse.defer(ephemeral),\r\n );\r\n this.deferred = true;\r\n }\r\n /** Edits the original response. @param options Replacement message options. @returns Discord response. @throws {Error} When not acknowledged or REST fails. */ public editReply(\r\n options: InteractionReplyOptions,\r\n ): Promise<unknown> {\r\n this.assertAcknowledged();\r\n return this.#client.editInteractionReply(this.token, options);\r\n }\r\n /** Deletes the original response. @returns Promise fulfilled after deletion. @throws {Error} When not acknowledged or REST fails. */ public deleteReply(): Promise<void> {\r\n this.assertAcknowledged();\r\n return this.#client.deleteInteractionReply(this.token);\r\n }\r\n /** Sends a follow-up message using the interaction webhook. @param options Follow-up message options. @returns Discord response. @throws {Error} When REST fails. */ public followUp(\r\n options: InteractionReplyOptions | string,\r\n ): Promise<unknown> {\r\n const payload =\r\n typeof options === \"string\" ? { content: options } : options;\r\n return this.#client.followUpInteraction(this.token, payload);\r\n }\r\n /** Updates the message for a component interaction. */ public async update(\r\n options: InteractionReplyOptions | string,\r\n ): Promise<unknown> {\r\n this.assertUnacknowledged();\r\n const payload =\r\n typeof options === \"string\" ? { content: options } : options;\r\n const result = await this.#client.postInteractionResponse(\r\n this.id,\r\n this.token,\r\n new InteractionResponse(InteractionResponseType.MessageUpdate, payload),\r\n );\r\n this.replied = true;\r\n return result;\r\n }\r\n /** Opens a modal dialog in the user's client. @param modal Modal builder output or raw modal callback data. @returns Discord response. @throws {Error} When already acknowledged or REST fails. */\r\n public async showModal(modal: {\r\n custom_id: string;\r\n title: string;\r\n components: unknown[];\r\n [key: string]: unknown;\r\n }): Promise<unknown> {\r\n this.assertUnacknowledged();\r\n const result = await this.#client.postInteractionResponse(\r\n this.id,\r\n this.token,\r\n new InteractionResponse(\r\n InteractionResponseType.Modal,\r\n modal as InteractionReplyOptions,\r\n ),\r\n );\r\n this.replied = true;\r\n return result;\r\n }\r\n}\r\n\r\n// ─── CommandInteraction ───────────────────────────────────────────────────────\r\n\r\n/** Application command interaction with fully typed option resolver. */\r\nexport class CommandInteraction extends Interaction {\r\n /** Typed option resolver. Access slash command options with full type safety. */\r\n public readonly options: CommandOptions;\r\n\r\n /** Invoked command name. @returns Command name or an empty string. */ public get commandName(): string {\r\n return typeof this.data.data?.name === \"string\" ? this.data.data.name : \"\";\r\n }\r\n\r\n public constructor(client: InteractionClient, data: InteractionData) {\r\n super(client, data);\r\n const rawOptions = (data.data?.options as APIInteractionDataOption[]) ?? [];\r\n const resolved = (data.data?.resolved as Record<string, unknown>) ?? {};\r\n // If a subcommand is present, drill into its options for the resolver\r\n const sub = rawOptions.find(\r\n (o) =>\r\n o.type === 1 /* SubCommand */ || o.type === 2 /* SubCommandGroup */,\r\n );\r\n this.options = new CommandOptions(sub?.options ?? rawOptions, resolved);\r\n }\r\n}\r\n\r\n// ─── ComponentInteraction ─────────────────────────────────────────────────────\r\n\r\n/** Message component interaction. */\r\nexport class ComponentInteraction extends Interaction {\r\n /** Gets component custom ID. */\r\n public get customId(): string {\r\n return (this.data as any)?.data?.custom_id ?? \"\";\r\n }\r\n /** Gets component type. */\r\n public get componentType(): number {\r\n return (this.data as any)?.data?.component_type ?? 0;\r\n }\r\n /** Gets selected values for select menu component interactions. */\r\n public get values(): string[] {\r\n return (this.data as any)?.data?.values ?? [];\r\n }\r\n /** Defers updating the message to which the component was attached. */\r\n public async deferUpdate(): Promise<void> {\r\n this.assertUnacknowledged();\r\n await this.postResponse(\r\n new InteractionResponse(InteractionResponseType.DeferredMessageUpdate),\r\n );\r\n this.deferred = true;\r\n }\r\n /** Updates the message to which the component was attached. */\r\n public override async update(\r\n options: InteractionReplyOptions | string,\r\n ): Promise<unknown> {\r\n this.assertUnacknowledged();\r\n const payload =\r\n typeof options === \"string\" ? { content: options } : options;\r\n const result = await this.postResponse(\r\n new InteractionResponse(InteractionResponseType.MessageUpdate, payload),\r\n );\r\n this.replied = true;\r\n return result;\r\n }\r\n}\r\n\r\n// ─── ModalSubmitInteraction ───────────────────────────────────────────────────\r\n\r\n/** Represents a Discord modal submission interaction. */\r\nexport class ModalSubmitInteraction extends Interaction {\r\n /** Gets the submitted modal custom ID. */\r\n public get customId(): string {\r\n return (this.data as any)?.data?.custom_id ?? \"\";\r\n }\r\n\r\n /** Retrieves the text value for a specific text input custom ID. @param customId The custom_id of the text input component. @returns The submitted text, or undefined if not found. */\r\n public getInputValue(customId: string): string | undefined {\r\n const rows = (this.data as any)?.data?.components ?? [];\r\n for (const row of rows) {\r\n for (const comp of row.components ?? []) {\r\n if (comp.custom_id === customId) return comp.value;\r\n }\r\n }\r\n return undefined;\r\n }\r\n\r\n /** Retrieves the text value for a text input, throwing if missing. @param customId The custom_id of the text input component. @returns The submitted text. @throws {TypeError} If the field is not found. */\r\n public getRequiredInputValue(customId: string): string {\r\n const value = this.getInputValue(customId);\r\n if (value === undefined)\r\n throw new TypeError(\r\n `Modal input \"${customId}\" was not found in the submission.`,\r\n );\r\n return value;\r\n }\r\n}\r\n\r\n// ─── AutocompleteInteraction ──────────────────────────────────────────────────\r\n\r\n/** Represents a Discord slash command autocomplete interaction. */\r\nexport class AutocompleteInteraction extends Interaction {\r\n /** Gets the target command name. */\r\n public get commandName(): string {\r\n return (this.data as any)?.data?.name ?? \"\";\r\n }\r\n\r\n /** Gets the currently focused autocomplete option. */\r\n public get focusedOption():\r\n { name: string; value: unknown; type: number } | undefined {\r\n const options = (this.data as any)?.data?.options ?? [];\r\n return findFocused(options);\r\n }\r\n\r\n /** Responds to Discord with autocomplete choices. @param choices Array of name/value pairs to show. @throws {TypeError} If choices is not an array. */\r\n public async respond(\r\n choices: { name: string; value: string | number }[],\r\n ): Promise<void> {\r\n if (!Array.isArray(choices))\r\n throw new TypeError(\"Autocomplete choices must be an array.\");\r\n const response = new InteractionResponse(\r\n InteractionResponseType.Autocomplete,\r\n { choices } as InteractionReplyOptions,\r\n );\r\n await this.postResponse(response);\r\n this.replied = true;\r\n }\r\n}\r\n\r\n/** Recursively finds the focused option in a nested options tree. */\r\nfunction findFocused(\r\n options: any[],\r\n): { name: string; value: unknown; type: number } | undefined {\r\n for (const opt of options) {\r\n if (opt.focused)\r\n return { name: opt.name, value: opt.value, type: opt.type };\r\n if (Array.isArray(opt.options)) {\r\n const found = findFocused(opt.options);\r\n if (found) return found;\r\n }\r\n }\r\n return undefined;\r\n}\r\n\r\n// ─── Factory ──────────────────────────────────────────────────────────────────\r\n\r\n/**\r\n * Creates a specialized interaction structure for a Gateway payload.\r\n * @param client Interaction transport.\r\n * @param data Gateway interaction payload.\r\n * @returns Specialized interaction structure.\r\n * @throws {TypeError} If required identifiers are missing.\r\n */\r\nexport function createInteraction(\r\n client: InteractionClient,\r\n data: InteractionData,\r\n): Interaction {\r\n switch (data.type) {\r\n case InteractionType.ApplicationCommand:\r\n return new CommandInteraction(client, data);\r\n case InteractionType.ApplicationCommandAutocomplete:\r\n return new AutocompleteInteraction(client, data);\r\n case InteractionType.MessageComponent:\r\n return new ComponentInteraction(client, data);\r\n case InteractionType.ModalSubmit:\r\n return new ModalSubmitInteraction(client, data);\r\n default:\r\n return new Interaction(client, data);\r\n }\r\n}\r\n",
|
|
15
|
+
"/** Resource structures for Discord messages and related entities. */\r\nimport { BaseStructure, Channel, User } from \"./base.js\";\r\nimport type { ResourceContext } from \"./base.js\";\r\n\r\nexport { BaseStructure, Channel, Guild, User } from \"./base.js\";\r\nexport type { ResourceContext } from \"./base.js\";\r\n\r\nexport class Message extends BaseStructure {\r\n public content: string;\r\n public author: User;\r\n public channelId: string;\r\n public readonly channel: Channel;\r\n public guildId?: string;\r\n public flags: number;\r\n /** Message creation timestamp (from timestamp field or snowflake). */\r\n public readonly timestamp: Date;\r\n public readonly attachments: import(\"@lunibee/types\").APIAttachment[];\r\n public readonly embeds: import(\"@lunibee/types\").APIEmbed[];\r\n public readonly mentions: User[];\r\n public readonly mentionRoles: string[];\r\n public pinned: boolean;\r\n public mentionEveryone: boolean;\r\n public type: number;\r\n public readonly reference?: import(\"@lunibee/types\").APIMessageReference;\r\n public readonly components: import(\"@lunibee/types\").APIMessageComponent[];\r\n public readonly referencedMessage?: Message | null;\r\n readonly #context?: ResourceContext;\r\n\r\n /** Creates a message structure from Discord message data. */\r\n public constructor(\r\n data: import(\"@lunibee/types\").APIMessage,\r\n context?: ResourceContext,\r\n ) {\r\n super(data.id);\r\n if (!/^\\d{1,20}$/.test(data.channel_id))\r\n throw new TypeError(\"Message channel_id must be a valid snowflake.\");\r\n this.content = data.content ?? \"\";\r\n this.author = new User(data.author);\r\n this.channelId = data.channel_id;\r\n this.guildId = data.guild_id;\r\n this.flags = data.flags ?? 0;\r\n this.timestamp = new Date(\r\n data.timestamp ?? Number((BigInt(this.id) >> 22n) + 1420070400000n),\r\n );\r\n this.attachments = data.attachments ?? [];\r\n this.embeds = data.embeds ?? [];\r\n this.components = data.components ?? [];\r\n this.mentions = (data.mentions ?? []).map((user) => new User(user));\r\n this.mentionRoles = data.mention_roles ?? [];\r\n this.pinned = data.pinned ?? false;\r\n this.mentionEveryone = data.mention_everyone ?? false;\r\n this.type = data.type ?? 0;\r\n this.reference = data.message_reference;\r\n this.referencedMessage = data.referenced_message\r\n ? new Message(data.referenced_message, context)\r\n : data.referenced_message === null\r\n ? null\r\n : undefined;\r\n this.#context = context;\r\n this.channel = new Channel(\r\n { id: data.channel_id, type: 0, guild_id: data.guild_id },\r\n context,\r\n );\r\n }\r\n\r\n /** Whether embeds are suppressed on this message. */\r\n public get embedsSuppressed(): boolean {\r\n return (this.flags & 4) !== 0;\r\n }\r\n\r\n /** Edits this message. @param options Message fields to change. @returns The updated message. @throws {Error} If the message is not attached to a client. */\r\n public edit(\r\n options: Record<string, unknown> & { content?: string },\r\n ): Promise<Message> {\r\n if (!this.#context)\r\n throw new Error(\"This message is not attached to a client.\");\r\n return this.#context.editMessage(this.channelId, this.id, options);\r\n }\r\n\r\n /** Updates this message using the same resource operation as edit. @param options Message fields to change. @returns The updated message. @throws {Error} If the message is not attached to a client. */\r\n public update(\r\n options: Record<string, unknown> & { content?: string },\r\n ): Promise<Message> {\r\n return this.edit(options);\r\n }\r\n\r\n /** Deletes this message. @returns A promise fulfilled when Discord confirms deletion. @throws {Error} If the message is not attached to a client. */\r\n public delete(): Promise<void> {\r\n if (!this.#context)\r\n throw new Error(\"This message is not attached to a client.\");\r\n return this.#context.deleteMessage(this.channelId, this.id);\r\n }\r\n\r\n /** Replies to this message. @param options Message content or payload. @returns The created reply message. @throws {Error} If the message is not attached to a client. */\r\n public reply(\r\n options: string | (Record<string, unknown> & { content?: string }),\r\n ): Promise<Message> {\r\n if (!this.#context)\r\n throw new Error(\"This message is not attached to a client.\");\r\n const payload =\r\n typeof options === \"string\" ? { content: options } : { ...options };\r\n payload.message_reference = {\r\n message_id: this.id,\r\n channel_id: this.channelId,\r\n guild_id: this.guildId,\r\n };\r\n return this.#context.sendMessage(this.channelId, payload);\r\n }\r\n\r\n /** Crossposts this message. @returns The resulting message. @throws {Error} If the message is not attached to a client. */\r\n public crosspost(): Promise<Message> {\r\n if (!this.#context)\r\n throw new Error(\"This message is not attached to a client.\");\r\n return this.#context.crosspostMessage(this.channelId, this.id);\r\n }\r\n\r\n /** Adds a reaction to this message. @param emoji Emoji identifier. @returns A promise fulfilled when the reaction is added. @throws {Error} If reactions are unavailable. */\r\n public react(emoji: string): Promise<void> {\r\n if (!this.#context?.addReaction)\r\n throw new Error(\"This message is not attached to a client.\");\r\n return this.#context.addReaction(this.channelId, this.id, emoji);\r\n }\r\n\r\n /** Removes a reaction from this message. @param emoji Emoji identifier. @param userId User whose reaction should be removed; omit to remove the current user's reaction. @returns A promise fulfilled when the reaction is removed. @throws {Error} If reaction operations are unavailable. */\r\n public removeReaction(emoji: string, userId?: string): Promise<void> {\r\n if (!this.#context)\r\n throw new Error(\"This message is not attached to a client.\");\r\n return userId\r\n ? (this.#context.removeReaction?.(\r\n this.channelId,\r\n this.id,\r\n emoji,\r\n userId,\r\n ) ?? Promise.reject(new Error(\"Reaction operations are unavailable.\")))\r\n : (this.#context.removeOwnReaction?.(this.channelId, this.id, emoji) ??\r\n Promise.reject(new Error(\"Reaction operations are unavailable.\")));\r\n }\r\n\r\n /** Removes all reactions from this message. @returns A promise fulfilled when reactions are removed. @throws {Error} If reaction operations are unavailable. */\r\n public removeAllReactions(): Promise<void> {\r\n if (!this.#context?.removeAllReactions)\r\n throw new Error(\"This message is not attached to a client.\");\r\n return this.#context.removeAllReactions(this.channelId, this.id);\r\n }\r\n\r\n /** Pins this message. @returns A promise fulfilled when the message is pinned. @throws {Error} If pin operations are unavailable. */\r\n public pin(): Promise<void> {\r\n if (!this.#context?.pinMessage)\r\n throw new Error(\"This message is not attached to a client.\");\r\n return this.#context.pinMessage(this.channelId, this.id);\r\n }\r\n\r\n /** Unpins this message. @returns A promise fulfilled when the message is unpinned. @throws {Error} If pin operations are unavailable. */\r\n public unpin(): Promise<void> {\r\n if (!this.#context?.unpinMessage)\r\n throw new Error(\"This message is not attached to a client.\");\r\n return this.#context.unpinMessage(this.channelId, this.id);\r\n }\r\n}\r\n\r\nexport { GuildMember, Role, TextChannel } from \"./resources.js\";\r\nexport * from \"./interactions.js\";\r\nexport { Embed } from \"./embed.js\";\r\n",
|
|
16
|
+
"import { Collection } from \"@lunibee/collection\";\r\nimport { REST, Routes } from \"@lunibee/rest\";\r\nimport { Message, type ResourceContext } from \"@lunibee/structures\";\r\n\r\nexport type MessageCreateOptions = Record<string, unknown> & {\r\n content?: string;\r\n};\r\nexport type MessageEditOptions = Record<string, unknown> & { content?: string };\r\n\r\nexport class MessageManager {\r\n public readonly cache = new Collection<string, Message>();\r\n readonly #rest: REST;\r\n readonly #context: ResourceContext;\r\n readonly #channelId: string;\r\n\r\n public constructor(rest: REST, context: ResourceContext, channelId: string) {\r\n if (!channelId) throw new TypeError(\"Channel ID is required.\");\r\n this.#rest = rest;\r\n this.#context = context;\r\n this.#channelId = channelId;\r\n }\r\n public async resolve(messageId: string): Promise<Message> {\r\n return this.cache.get(messageId) ?? this.fetch(messageId);\r\n }\r\n public async send(options: MessageCreateOptions): Promise<Message> {\r\n const data = await this.#rest.post<\r\n ConstructorParameters<typeof Message>[0]\r\n >(Routes.channelMessages(this.#channelId), options);\r\n return this.upsert(data);\r\n }\r\n public async fetch(messageId: string): Promise<Message> {\r\n const data = await this.#rest.get<ConstructorParameters<typeof Message>[0]>(\r\n Routes.message(this.#channelId, messageId),\r\n );\r\n return this.upsert(data);\r\n }\r\n public fetchMany(messageIds: Iterable<string>): Promise<Message[]> {\r\n return Promise.all(\r\n Array.from(messageIds, (messageId) => this.fetch(messageId)),\r\n );\r\n }\r\n public upsert(data: ConstructorParameters<typeof Message>[0]): Message {\r\n const existing = this.cache.get(data.id);\r\n const message = new Message(data, this.#context);\r\n if (existing) {\r\n Object.assign(existing, message);\r\n return existing;\r\n }\r\n this.cache.set(message.id, message);\r\n return message;\r\n }\r\n public delete(messageId: string): boolean {\r\n return this.cache.delete(messageId);\r\n }\r\n}\r\n",
|
|
15
17
|
"import { REST, Routes } from \"@lunibee/rest\";\nimport { Channel, type ResourceContext } from \"@lunibee/structures\";\n\n/** Manages thread resources created from a parent channel. */\nexport class ThreadManager {\n readonly #rest: REST;\n readonly #context: ResourceContext;\n readonly #channelId: string;\n /** Creates a thread manager. @param rest REST transport. @param context Structure resource context. @param channelId Parent channel identifier. @throws {TypeError} If channelId is empty. */\n public constructor(rest: REST, context: ResourceContext, channelId: string) {\n if (!channelId) throw new TypeError(\"Channel ID is required.\");\n this.#rest = rest;\n this.#context = context;\n this.#channelId = channelId;\n }\n /** Creates a thread from a message. @param messageId Message identifier. @param options Thread creation options. @returns Created thread channel. @throws {Error} If REST rejects the request. */\n public async createFromMessage(\n messageId: string,\n options: {\n name: string;\n autoArchiveDuration?: 60 | 1440 | 4320 | 10080;\n rateLimitPerUser?: number;\n },\n ): Promise<Channel> {\n const data = await this.#rest.post<\n ConstructorParameters<typeof Channel>[0]\n >(Routes.messageThread(this.#channelId, messageId), {\n name: options.name,\n auto_archive_duration: options.autoArchiveDuration,\n rate_limit_per_user: options.rateLimitPerUser,\n });\n return new Channel(data, this.#context);\n }\n}\n",
|
|
16
|
-
"import {
|
|
17
|
-
"import { Manager, ResourceManager } from \"./base.js\";\r\nexport { Manager, ResourceManager } from \"./base.js\";\r\n/** Collection-backed generic resource manager. */\r\nimport { Collection } from \"@lunibee/collection\";\r\nimport { REST, Routes } from \"@lunibee/rest\";\r\nimport {\r\n Channel,\r\n Message,\r\n User,\r\n Guild,\r\n type ResourceContext,\r\n} from \"@lunibee/structures\";\r\nimport { MessageManager } from \"./message.js\";\r\nimport { ThreadManager } from \"./thread.js\";\r\n\r\n/** Manages users. */\r\nexport class UserManager extends ResourceManager<string, User> {\r\n /** Creates a user manager. @param rest REST transport. */ public constructor(\r\n rest: REST,\r\n ) {\r\n super(\r\n async (id) =>\r\n new User(\r\n await rest.get<ConstructorParameters<typeof User>[0]>(\r\n Routes.userById(id),\r\n ),\r\n ),\r\n (user) => user.id,\r\n );\r\n }\r\n}\r\n/** Manages guilds. */\r\nexport class GuildManager extends ResourceManager<string, Guild> {\r\n /** Creates a guild manager. @param rest REST transport. */ public constructor(\r\n rest: REST,\r\n ) {\r\n super(\r\n async (id) =>\r\n new Guild(\r\n await rest.get<ConstructorParameters<typeof Guild>[0]>(\r\n Routes.guild(id),\r\n ),\r\n ),\r\n (guild) => guild.id,\r\n );\r\n }\r\n}\r\n/** Message creation options. */\r\nexport interface MessageCreateOptions {\r\n /** Message content. */ content?: string;\r\n}\r\n/** Message edit options. */\r\nexport interface MessageEditOptions {\r\n /** New message content. */ content?: string;\r\n}\r\n/** Message fetch options. */\r\nexport interface MessageFetchOptions {\r\n /** Whether to use cache. */ cache?: boolean;\r\n}\r\n/** Message list query options. */\r\nexport interface MessageQueryOptions {\r\n /** Message before this ID. */ before?: string;\r\n /** Message after this ID. */ after?: string;\r\n /** Message around this ID. */ around?: string;\r\n /** Maximum number of messages. */ limit?: number;\r\n}\r\n/** Message thread creation options. */\r\nexport interface MessageThreadOptions {\r\n /** Thread name. */ name: string;\r\n /** Auto archive duration. */ autoArchiveDuration?: 60 | 1440 | 4320 | 10080;\r\n /** Slowmode duration. */ rateLimitPerUser?: number;\r\n}\r\n/** Reaction list options. */\r\nexport interface ReactionFetchOptions {\r\n /** Maximum reactions. */ limit?: number;\r\n /** Reaction pagination cursor. */ after?: string;\r\n}\r\n/** Runtime compatibility placeholders for legacy value imports. */\r\nexport const MessageCreateOptions = undefined;\r\n/** Runtime compatibility placeholder. */\r\nexport const MessageEditOptions = undefined;\r\n/** Runtime compatibility placeholder. */\r\nexport const MessageFetchOptions = undefined;\r\n/** Runtime compatibility placeholder. */\r\nexport const MessageThreadOptions = undefined;\r\n/** Runtime compatibility placeholder. */\r\nexport const ReactionFetchOptions = undefined;\r\n\r\n/** Manages Discord channels and their message APIs. */\r\nexport class ChannelManager extends Manager<string, Channel> {\r\n readonly #rest: REST;\r\n readonly #context: ResourceContext;\r\n readonly #messageManagers = new Map<string, MessageManager>();\r\n /** Creates a channel manager. @param rest REST transport. */\r\n public constructor(rest: REST) {\r\n super();\r\n this.#rest = rest;\r\n this.#context = {\r\n sendMessage: (channelId, options) => this.send(channelId, options),\r\n editMessage: (channelId, messageId, options) =>\r\n this.editMessage(channelId, messageId, options),\r\n deleteMessage: (channelId, messageId) =>\r\n this.deleteMessage(channelId, messageId),\r\n crosspostMessage: (channelId, messageId) =>\r\n this.crosspostMessage(channelId, messageId),\r\n };\r\n }\r\n /** Gets the canonical message manager for a channel. @param channelId Channel ID. @returns Message manager. */ public messages(\r\n channelId: string,\r\n ): MessageManager {\r\n let manager = this.#messageManagers.get(channelId);\r\n if (!manager) {\r\n manager = new MessageManager(this.#rest, this.#context, channelId);\r\n this.#messageManagers.set(channelId, manager);\r\n }\r\n return manager;\r\n }\r\n /** Creates a thread manager. @param channelId Channel ID. @returns Thread manager. */ public threads(\r\n channelId: string,\r\n ): ThreadManager {\r\n return new ThreadManager(this.#rest, this.#context, channelId);\r\n }\r\n /** Fetches a channel. @param channelId Channel ID. @returns Channel. */ public async fetch(\r\n channelId: string,\r\n ): Promise<Channel> {\r\n const data = await this.#rest.get<ConstructorParameters<typeof Channel>[0]>(\r\n Routes.channel(channelId),\r\n );\r\n return this.upsert(data);\r\n }\r\n /** Resolves a channel. @param channelId Channel ID. @returns Canonical channel. */ public async resolve(\r\n channelId: string,\r\n ): Promise<Channel> {\r\n return this.get(channelId) ?? this.fetch(channelId);\r\n }\r\n /** Inserts or updates a channel. @param data Channel payload. @returns Canonical channel. */ public upsert(\r\n data: ConstructorParameters<typeof Channel>[0],\r\n ): Channel {\r\n const existing = this.get(data.id);\r\n const channel = new Channel(data, this.#context);\r\n if (existing) {\r\n Object.assign(existing, channel);\r\n return existing;\r\n }\r\n this.set(channel.id, channel);\r\n return channel;\r\n }\r\n /** Updates a channel. @param channel Channel. @returns This manager. */ public update(\r\n channel: Channel,\r\n ): this {\r\n return this.set(channel.id, channel);\r\n }\r\n /** Sends a message. @param channelId Channel ID. @param options Message options. @returns Created message. */ public send(\r\n channelId: string,\r\n options: MessageCreateOptions,\r\n ): Promise<Message> {\r\n return this.messages(channelId).send(options);\r\n }\r\n /** Alias for send. @param channelId Channel ID. @param options Message options. @returns Created message. */ public sendMessage(\r\n channelId: string,\r\n options: MessageCreateOptions,\r\n ): Promise<Message> {\r\n return this.send(channelId, options);\r\n }\r\n /** Fetches one message. @param channelId Channel ID. @param messageId Message ID. @param options Fetch options. @returns Message. */ public async fetchMessage(\r\n channelId: string,\r\n messageId: string,\r\n options: MessageFetchOptions = {},\r\n ): Promise<Message> {\r\n void options;\r\n return this.messages(channelId).fetch(messageId);\r\n }\r\n /** Fetches messages by query or by iterable IDs. @param channelId Channel ID. @param query Query options or message IDs. @returns Messages. */ public fetchMessages(\r\n channelId: string,\r\n query: MessageQueryOptions | Iterable<string>,\r\n ): Promise<Message[]> {\r\n if (isMessageQuery(query)) {\r\n const params = new URLSearchParams();\r\n if (query.before) params.set(\"before\", query.before);\r\n if (query.after) params.set(\"after\", query.after);\r\n if (query.around) params.set(\"around\", query.around);\r\n if (query.limit !== undefined) params.set(\"limit\", String(query.limit));\r\n const suffix = params.toString();\r\n return this.#rest\r\n .get<ConstructorParameters<typeof Message>[0][]>(\r\n `${Routes.channelMessages(channelId)}${suffix ? `?${suffix}` : \"\"}`,\r\n )\r\n .then((data) =>\r\n data.map((item) => this.messages(channelId).upsert(item)),\r\n );\r\n }\r\n return this.messages(channelId).fetchMany(query);\r\n }\r\n /** Inserts a message through the canonical cache path. @param data Message payload. @returns Canonical message. */ public upsertMessage(\r\n data: ConstructorParameters<typeof Message>[0],\r\n ): Message {\r\n return this.messages(data.channel_id).upsert(data);\r\n }\r\n /** Edits a message. @param channelId Channel ID. @param messageId Message ID. @param options Edit options. @returns Updated message. */ public async editMessage(\r\n channelId: string,\r\n messageId: string,\r\n options: MessageEditOptions,\r\n ): Promise<Message> {\r\n const data = await this.#rest.patch<\r\n ConstructorParameters<typeof Message>[0]\r\n >(Routes.message(channelId, messageId), options);\r\n return this.messages(channelId).upsert(data);\r\n }\r\n /** Deletes a message. @param channelId Channel ID. @param messageId Message ID. @returns Nothing. */ public async deleteMessage(\r\n channelId: string,\r\n messageId: string,\r\n ): Promise<void> {\r\n await this.#rest.delete(Routes.message(channelId, messageId));\r\n this.messages(channelId).delete(messageId);\r\n }\r\n /** Deletes a cached message. @param channelId Channel ID. @param messageId Message ID. @returns Whether removed. */ public deleteCachedMessage(\r\n channelId: string,\r\n messageId: string,\r\n ): boolean {\r\n return this.messages(channelId).delete(messageId);\r\n }\r\n /** Crossposts a message. @param channelId Channel ID. @param messageId Message ID. @returns Crossposted message. */ public async crosspostMessage(\r\n channelId: string,\r\n messageId: string,\r\n ): Promise<Message> {\r\n const data = await this.#rest.post<\r\n ConstructorParameters<typeof Message>[0]\r\n >(Routes.crosspostMessage(channelId, messageId));\r\n return this.messages(channelId).upsert(data);\r\n }\r\n /** Bulk deletes messages. @param channelId Channel ID. @param messageIds Message IDs. @returns Nothing. */ public async bulkDeleteMessages(\r\n channelId: string,\r\n messageIds: Iterable<string>,\r\n ): Promise<void> {\r\n const ids = [...messageIds];\r\n await this.#rest.post(Routes.channelBulkDelete(channelId), {\r\n messages: ids,\r\n });\r\n for (const id of ids) this.messages(channelId).delete(id);\r\n }\r\n /** Adds a reaction. @param channelId Channel ID. @param messageId Message ID. @param emoji Emoji identifier. @returns Nothing. */ public async addReaction(\r\n channelId: string,\r\n messageId: string,\r\n emoji: string,\r\n ): Promise<void> {\r\n await this.#rest.put(Routes.messageReactions(channelId, messageId, emoji));\r\n }\r\n /** Fetches users who reacted. @param channelId Channel ID. @param messageId Message ID. @param emoji Emoji identifier. @param options Query options. @returns Users. */ public async fetchReactions(\r\n channelId: string,\r\n messageId: string,\r\n emoji: string,\r\n options: ReactionFetchOptions = {},\r\n ): Promise<User[]> {\r\n const params = new URLSearchParams();\r\n if (options.limit !== undefined) params.set(\"limit\", String(options.limit));\r\n if (options.after) params.set(\"after\", options.after);\r\n const suffix = params.toString();\r\n const data = await this.#rest.get<ConstructorParameters<typeof User>[0][]>(\r\n `${Routes.messageReactions(channelId, messageId, emoji)}${suffix ? `?${suffix}` : \"\"}`,\r\n );\r\n return data.map((user) => new User(user));\r\n }\r\n /** Removes the current bot user's reaction. @param channelId Channel ID. @param messageId Message ID. @param emoji Emoji identifier. @returns Nothing. */ public async removeOwnReaction(\r\n channelId: string,\r\n messageId: string,\r\n emoji: string,\r\n ): Promise<void> {\r\n await this.#rest.delete(\r\n Routes.messageReactions(channelId, messageId, emoji) + \"/@me\",\r\n );\r\n }\r\n /** Removes a user's reaction. @param channelId Channel ID. @param messageId Message ID. @param emoji Emoji identifier. @param userId User ID. @returns Nothing. */ public async removeReaction(\r\n channelId: string,\r\n messageId: string,\r\n emoji: string,\r\n userId: string,\r\n ): Promise<void> {\r\n await this.#rest.delete(\r\n `${Routes.messageReactions(channelId, messageId, emoji)}/${userId}`,\r\n );\r\n }\r\n /** Removes all reactions. @param channelId Channel ID. @param messageId Message ID. @returns Nothing. */ public async removeAllReactions(\r\n channelId: string,\r\n messageId: string,\r\n ): Promise<void> {\r\n await this.#rest.delete(Routes.messageReactionsAll(channelId, messageId));\r\n }\r\n /** Fetches pinned messages. @param channelId Channel ID. @returns Pinned messages. */ public async fetchPinnedMessages(\r\n channelId: string,\r\n ): Promise<Message[]> {\r\n const data = await this.#rest.get<\r\n ConstructorParameters<typeof Message>[0][]\r\n >(Routes.channelPins(channelId));\r\n return data.map((item) => this.messages(channelId).upsert(item));\r\n }\r\n /** Pins a message. @param channelId Channel ID. @param messageId Message ID. @returns Nothing. */ public async pinMessage(\r\n channelId: string,\r\n messageId: string,\r\n ): Promise<void> {\r\n await this.#rest.put(Routes.channelPin(channelId, messageId));\r\n }\r\n /** Unpins a message. @param channelId Channel ID. @param messageId Message ID. @returns Nothing. */ public async unpinMessage(\r\n channelId: string,\r\n messageId: string,\r\n ): Promise<void> {\r\n await this.#rest.delete(Routes.channelPin(channelId, messageId));\r\n }\r\n /** Creates a thread from a message. @param channelId Channel ID. @param messageId Message ID. @param options Thread options. @returns Created thread channel. */ public createThreadFromMessage(\r\n channelId: string,\r\n messageId: string,\r\n options: MessageThreadOptions,\r\n ): Promise<Channel> {\r\n return this.threads(channelId).createFromMessage(messageId, options);\r\n }\r\n /** Deletes a channel and its message manager. @param channelId Channel ID. @returns Whether removed. */ public delete(\r\n channelId: string,\r\n ): boolean {\r\n this.#messageManagers.delete(channelId);\r\n return super.delete(channelId);\r\n }\r\n /** Clears all channels and message managers. @returns Nothing. */ public clear(): void {\r\n this.#messageManagers.clear();\r\n super.clear();\r\n }\r\n}\r\n/** Determines whether a message query object was supplied. @param value Candidate query. @returns True when it is a query object. */\r\nfunction isMessageQuery(\r\n value: MessageQueryOptions | Iterable<string>,\r\n): value is MessageQueryOptions {\r\n return (\r\n typeof value === \"object\" && value !== null && !(Symbol.iterator in value)\r\n );\r\n}\r\n/** Backward-compatible message option alias. */\r\nexport type CreateMessageOptions = MessageCreateOptions;\r\n/** Exposes the message manager class. */\r\nexport { MessageManager } from \"./message.js\";\r\n/** Exposes the thread manager class. */\r\nexport { ThreadManager } from \"./thread.js\";\r\n\r\nexport {\r\n RoleManager,\r\n type RoleCreateOptions,\r\n type RoleEditOptions,\r\n} from \"./role.js\";\r\nexport {\r\n GuildMemberManager,\r\n type MemberEditOptions,\r\n type BanOptions,\r\n} from \"./member.js\";\r\nexport { ApplicationCommandManager } from \"./application.js\";\r\n",
|
|
18
|
-
"/** Discord API snowflake identifier. */\r\nexport type Snowflake = string;\r\n\r\n/** Gateway intent bit flags supported by Discord (PascalCase). */\r\nexport const GatewayIntentBits = {\r\n Guilds: 1 << 0,\r\n GuildMembers: 1 << 1,\r\n GuildModeration: 1 << 2,\r\n GuildExpressions: 1 << 3,\r\n GuildIntegrations: 1 << 4,\r\n GuildWebhooks: 1 << 5,\r\n GuildInvites: 1 << 6,\r\n GuildVoiceStates: 1 << 7,\r\n GuildPresences: 1 << 8,\r\n GuildMessages: 1 << 9,\r\n GuildMessageReactions: 1 << 10,\r\n GuildMessageTyping: 1 << 11,\r\n DirectMessages: 1 << 12,\r\n DirectMessageReactions: 1 << 13,\r\n DirectMessageTyping: 1 << 14,\r\n MessageContent: 1 << 15,\r\n GuildScheduledEvents: 1 << 16,\r\n AutoModerationConfiguration: 1 << 20,\r\n AutoModerationExecution: 1 << 21,\r\n GuildMessagePolls: 1 << 24,\r\n DirectMessagePolls: 1 << 25,\r\n} as const;\r\n\r\n/** Idiomatic camelCase Gateway intent bit flags supported by Discord. */\r\nexport const IntentBits = {\r\n guild: 1 << 0,\r\n guilds: 1 << 0,\r\n guildMembers: 1 << 1,\r\n guildModeration: 1 << 2,\r\n guildBans: 1 << 2,\r\n guildExpressions: 1 << 3,\r\n guildEmojis: 1 << 3,\r\n guildEmojisAndStickers: 1 << 3,\r\n guildIntegrations: 1 << 4,\r\n guildWebhooks: 1 << 5,\r\n guildInvites: 1 << 6,\r\n guildVoiceStates: 1 << 7,\r\n guildPresences: 1 << 8,\r\n guildMessages: 1 << 9,\r\n guildMessage: 1 << 9,\r\n guildMessageReactions: 1 << 10,\r\n guildMessageTyping: 1 << 11,\r\n directMessages: 1 << 12,\r\n directMessageReactions: 1 << 13,\r\n directMessageTyping: 1 << 14,\r\n messageContent: 1 << 15,\r\n guildScheduledEvents: 1 << 16,\r\n autoModerationConfiguration: 1 << 20,\r\n autoModerationExecution: 1 << 21,\r\n guildMessagePolls: 1 << 24,\r\n directMessagePolls: 1 << 25,\r\n} as const;\r\n\r\n/** Alias for IntentBits. */\r\nexport const Intents = IntentBits;\r\n\r\n/** Gateway intent resolvable value (single bitfield, enum key, or array of bitfields/strings). */\r\nexport type GatewayIntentResolvable =\r\n | number\r\n | keyof typeof GatewayIntentBits\r\n | keyof typeof IntentBits\r\n | (\r\n number | keyof typeof GatewayIntentBits | keyof typeof IntentBits | string\r\n )[];\r\n\r\n/** Resolves any GatewayIntentResolvable into a raw bitfield integer. */\r\nexport function resolveGatewayIntents(\r\n intents: GatewayIntentResolvable,\r\n): number {\r\n if (typeof intents === \"number\") return intents;\r\n if (Array.isArray(intents)) {\r\n return intents.reduce<number>((acc, intent) => {\r\n return acc | resolveGatewayIntents(intent as any);\r\n }, 0);\r\n }\r\n if (typeof intents === \"string\") {\r\n if (intents in GatewayIntentBits)\r\n return (GatewayIntentBits as Record<string, number>)[intents]!;\r\n if (intents in IntentBits)\r\n return (IntentBits as Record<string, number>)[intents]!;\r\n const lower = intents.charAt(0).toLowerCase() + intents.slice(1);\r\n if (lower in IntentBits)\r\n return (IntentBits as Record<string, number>)[lower]!;\r\n const num = Number(intents);\r\n if (!Number.isNaN(num)) return num;\r\n }\r\n return 0;\r\n}\r\n\r\n/** Gateway connection properties (OS, browser, device). */\r\nexport interface GatewayProperties {\r\n os?: string;\r\n browser?: string;\r\n device?: string;\r\n [key: string]: unknown;\r\n}\r\n/** Gateway presence activity. */\r\nexport interface GatewayPresenceActivity {\r\n name: string;\r\n type?: number;\r\n url?: string;\r\n state?: string;\r\n}\r\n/** Gateway presence data. */\r\nexport interface GatewayPresence {\r\n status?: \"online\" | \"dnd\" | \"idle\" | \"invisible\" | \"offline\";\r\n activities?: GatewayPresenceActivity[];\r\n afk?: boolean;\r\n since?: number | null;\r\n}\r\n/** Client configuration. */\r\nexport interface ClientOptions {\r\n token: string;\r\n intents: GatewayIntentResolvable;\r\n gateway?: GatewayOptions;\r\n rest?: RESTOptions;\r\n}\r\n/** Gateway connection configuration. */\r\nexport interface GatewayOptions {\r\n intents?: GatewayIntentResolvable;\r\n reconnect?: boolean;\r\n maxReconnectAttempts?: number;\r\n reconnectBaseDelay?: number;\r\n reconnectMaxDelay?: number;\r\n shardId?: number;\r\n shardCount?: number;\r\n properties?: GatewayProperties;\r\n presence?: GatewayPresence;\r\n}\r\n\r\n/** REST request configuration. */\r\nexport interface RESTOptions {\r\n timeout?: number;\r\n retries?: number;\r\n baseURL?: string;\r\n}\r\n/** Discord user object. */\r\nexport interface UserData {\r\n id: Snowflake;\r\n username: string;\r\n discriminator?: string;\r\n global_name?: string | null;\r\n avatar?: string | null;\r\n bot?: boolean;\r\n system?: boolean;\r\n public_flags?: number;\r\n}\r\n/** Current authenticated bot user. */\r\nexport type ClientUser = UserData;\r\n/** Discord Gateway payload envelope. */\r\nexport interface GatewayPayload<T = unknown> {\r\n op: number;\r\n d: T | null;\r\n s: number | null;\r\n t: string | null;\r\n}\r\n/** Generic Discord API error payload. */\r\nexport interface APIError {\r\n code?: number;\r\n message?: string;\r\n errors?: Record<string, unknown>;\r\n}\r\n/** Discord message flags. */\r\nexport const MessageFlags = {\r\n Crossposted: 1,\r\n IsCrosspost: 2,\r\n SuppressEmbeds: 4,\r\n SourceMessageDeleted: 8,\r\n Urgent: 16,\r\n HasThread: 32,\r\n Ephemeral: 64,\r\n Loading: 128,\r\n IsComponentsV2: 32768,\r\n} as const;\r\n/** Discord channel types. */\r\nexport const ChannelType = {\r\n GuildText: 0,\r\n DM: 1,\r\n GuildVoice: 2,\r\n GroupDM: 3,\r\n GuildCategory: 4,\r\n GuildAnnouncement: 5,\r\n AnnouncementThread: 10,\r\n PublicThread: 11,\r\n PrivateThread: 12,\r\n GuildStageVoice: 13,\r\n GuildDirectory: 14,\r\n GuildForum: 15,\r\n GuildMedia: 16,\r\n} as const;\r\n\r\n/** Raw Discord embed object. */\r\nexport interface APIEmbed {\r\n title?: string;\r\n type?: string;\r\n description?: string;\r\n url?: string;\r\n timestamp?: string;\r\n color?: number;\r\n footer?: Record<string, unknown>;\r\n image?: Record<string, unknown>;\r\n thumbnail?: Record<string, unknown>;\r\n video?: Record<string, unknown>;\r\n provider?: Record<string, unknown>;\r\n author?: Record<string, unknown>;\r\n fields?: Array<Record<string, unknown>>;\r\n}\r\n/** Raw Discord attachment object. */\r\nexport interface APIAttachment {\r\n id: Snowflake;\r\n filename: string;\r\n description?: string | null;\r\n content_type?: string;\r\n size: number;\r\n url: string;\r\n proxy_url: string;\r\n height?: number | null;\r\n width?: number | null;\r\n ephemeral?: boolean;\r\n duration_secs?: number;\r\n waveform?: string;\r\n flags?: number;\r\n}\r\n/** Raw Discord message component object. */\r\nexport interface APIMessageComponent {\r\n type: number;\r\n id?: number;\r\n custom_id?: string;\r\n style?: number;\r\n label?: string;\r\n disabled?: boolean;\r\n emoji?: Record<string, unknown>;\r\n url?: string;\r\n options?: Array<Record<string, unknown>>;\r\n components?: APIMessageComponent[];\r\n}\r\n/** Raw Discord message reference. */\r\nexport interface APIMessageReference {\r\n type?: number;\r\n message_id?: Snowflake;\r\n channel_id?: Snowflake;\r\n guild_id?: Snowflake;\r\n fail_if_not_exists?: boolean;\r\n}\r\n/** Raw Discord message reaction. */\r\nexport interface APIMessageReaction {\r\n count: number;\r\n count_details?: Record<string, number>;\r\n me?: boolean;\r\n me_burst?: boolean;\r\n emoji: Record<string, unknown>;\r\n burst_colors?: string[];\r\n}\r\n/** Raw Discord message object. */\r\nexport interface APIMessage {\r\n id: Snowflake;\r\n channel_id: Snowflake;\r\n author: UserData;\r\n content: string;\r\n timestamp?: string;\r\n edited_timestamp?: string | null;\r\n tts?: boolean;\r\n mention_everyone?: boolean;\r\n mentions?: UserData[];\r\n mention_roles?: Snowflake[];\r\n mention_channels?: Array<Record<string, unknown>>;\r\n attachments?: APIAttachment[];\r\n embeds?: APIEmbed[];\r\n reactions?: APIMessageReaction[];\r\n nonce?: string | number | null;\r\n pinned?: boolean;\r\n webhook_id?: Snowflake;\r\n type?: number;\r\n activity?: Record<string, unknown>;\r\n application?: Record<string, unknown>;\r\n application_id?: Snowflake;\r\n message_reference?: APIMessageReference;\r\n flags?: number;\r\n referenced_message?: APIMessage | null;\r\n interaction_metadata?: Record<string, unknown>;\r\n thread?: Record<string, unknown>;\r\n components?: APIMessageComponent[];\r\n position?: number;\r\n role_subscription_data?: Record<string, unknown>;\r\n purchase_notification?: Record<string, unknown>;\r\n poll?: Record<string, unknown>;\r\n guild_id?: Snowflake;\r\n}\r\n/** Raw Discord channel object. */\r\nexport interface APIChannel {\r\n id: Snowflake;\r\n type: number;\r\n guild_id?: Snowflake;\r\n position?: number;\r\n permission_overwrites?: Array<Record<string, unknown>>;\r\n name?: string | null;\r\n topic?: string | null;\r\n nsfw?: boolean;\r\n last_message_id?: Snowflake | null;\r\n bitrate?: number;\r\n user_limit?: number;\r\n rate_limit_per_user?: number;\r\n recipients?: UserData[];\r\n icon?: string | null;\r\n owner_id?: Snowflake;\r\n application_id?: Snowflake;\r\n parent_id?: Snowflake | null;\r\n last_pin_timestamp?: string | null;\r\n rtc_region?: string | null;\r\n video_quality_mode?: number;\r\n message_count?: number;\r\n member_count?: number;\r\n thread_metadata?: Record<string, unknown>;\r\n default_auto_archive_duration?: number;\r\n flags?: number;\r\n total_message_sent?: number;\r\n available_tags?: Array<Record<string, unknown>>;\r\n default_reaction_emoji?: Record<string, unknown> | null;\r\n default_thread_rate_limit_per_user?: number;\r\n default_sort_order?: number | null;\r\n default_forum_layout?: number;\r\n}\r\n/** Raw Discord guild object. */\r\nexport interface APIGuild {\r\n id: Snowflake;\r\n name: string;\r\n icon?: string | null;\r\n icon_hash?: string | null;\r\n splash?: string | null;\r\n discovery_splash?: string | null;\r\n owner_id?: Snowflake;\r\n afk_channel_id?: Snowflake | null;\r\n afk_timeout?: number;\r\n widget_enabled?: boolean;\r\n widget_channel_id?: Snowflake | null;\r\n verification_level?: number;\r\n default_message_notifications?: number;\r\n explicit_content_filter?: number;\r\n roles?: Array<Record<string, unknown>>;\r\n emojis?: Array<Record<string, unknown>>;\r\n features?: string[];\r\n mfa_level?: number;\r\n application_id?: Snowflake | null;\r\n system_channel_id?: Snowflake | null;\r\n system_channel_flags?: number;\r\n rules_channel_id?: Snowflake | null;\r\n max_presences?: number | null;\r\n max_members?: number;\r\n vanity_url_code?: string | null;\r\n description?: string | null;\r\n banner?: string | null;\r\n premium_tier?: number;\r\n preferred_locale?: string;\r\n public_updates_channel_id?: Snowflake | null;\r\n max_video_channel_users?: number;\r\n approximate_member_count?: number;\r\n approximate_presence_count?: number;\r\n nsfw_level?: number;\r\n safety_alerts_channel_id?: Snowflake | null;\r\n}\r\n/** Raw Discord guild member object. */\r\nexport interface APIGuildMember {\r\n user: UserData;\r\n nick?: string | null;\r\n avatar?: string | null;\r\n roles: Snowflake[];\r\n joined_at: string;\r\n premium_since?: string | null;\r\n deaf?: boolean;\r\n mute?: boolean;\r\n flags?: number;\r\n pending?: boolean;\r\n permissions?: string;\r\n communication_disabled_until?: string | null;\r\n guild_id?: Snowflake;\r\n}\r\n/** Raw Discord reaction event payload. */\r\nexport interface APIMessageReactionEvent {\r\n user_id: Snowflake;\r\n channel_id: Snowflake;\r\n message_id: Snowflake;\r\n guild_id?: Snowflake;\r\n member?: APIGuildMember;\r\n emoji: Record<string, unknown>;\r\n message_author_id?: Snowflake;\r\n burst?: boolean;\r\n type?: number;\r\n}\r\n/** Raw Discord message deletion event payload. */\r\nexport interface APIMessageDeleteEvent {\r\n id: Snowflake;\r\n channel_id: Snowflake;\r\n guild_id?: Snowflake;\r\n}\r\n/** Raw Discord bulk message deletion event payload. */\r\nexport interface APIMessageDeleteBulkEvent {\r\n ids: Snowflake[];\r\n channel_id: Snowflake;\r\n guild_id?: Snowflake;\r\n}\r\n/** Raw Discord channel deletion event payload. */\r\nexport interface APIChannelDeleteEvent extends APIChannel {}\r\n/** Raw Discord guild deletion event payload. */\r\nexport interface APIGuildDeleteEvent {\r\n id: Snowflake;\r\n unavailable?: boolean;\r\n}\r\n/** Raw Discord thread lifecycle payload. */\r\nexport interface APIThreadEvent extends APIChannel {\r\n guild_id: Snowflake;\r\n member?: Record<string, unknown>;\r\n}\r\n/** Raw Discord READY event payload. */\r\nexport interface APIReadyEvent {\r\n v: number;\r\n user: UserData;\r\n guilds: Array<{ id: Snowflake; unavailable?: boolean }>;\r\n session_id: string;\r\n resume_gateway_url: string;\r\n shard?: [number, number];\r\n application?: { id: Snowflake; flags: number; [key: string]: unknown };\r\n}\r\n\r\n/** Discord application command option types. */\r\nexport const ApplicationCommandOptionType = {\r\n SubCommand: 1,\r\n SubCommandGroup: 2,\r\n String: 3,\r\n Integer: 4,\r\n Boolean: 5,\r\n User: 6,\r\n Channel: 7,\r\n Role: 8,\r\n Mentionable: 9,\r\n Number: 10,\r\n Attachment: 11,\r\n} as const;\r\n\r\n/** Discord application command types. */\r\nexport const ApplicationCommandType = {\r\n ChatInput: 1,\r\n User: 2,\r\n Message: 3,\r\n} as const;\r\n\r\n/** Raw Discord application command option. */\r\nexport interface APIApplicationCommandOption {\r\n type: number;\r\n name: string;\r\n description: string;\r\n required?: boolean;\r\n choices?: Array<{ name: string; value: string | number }>;\r\n options?: APIApplicationCommandOption[];\r\n min_value?: number;\r\n max_value?: number;\r\n min_length?: number;\r\n max_length?: number;\r\n autocomplete?: boolean;\r\n channel_types?: number[];\r\n}\r\n\r\n/** Raw Discord application command object (from API). */\r\nexport interface APIApplicationCommand {\r\n id: Snowflake;\r\n type?: number;\r\n application_id: Snowflake;\r\n guild_id?: Snowflake;\r\n name: string;\r\n description: string;\r\n options?: APIApplicationCommandOption[];\r\n default_member_permissions?: string | null;\r\n dm_permission?: boolean;\r\n nsfw?: boolean;\r\n version: Snowflake;\r\n}\r\n\r\n/** Data for creating/overwriting an application command. */\r\nexport interface ApplicationCommandData {\r\n name: string;\r\n description: string;\r\n type?: number;\r\n options?: APIApplicationCommandOption[];\r\n default_member_permissions?: string | null;\r\n dm_permission?: boolean;\r\n nsfw?: boolean;\r\n}\r\n\r\n/** Raw Discord role object. */\r\nexport interface APIRole {\r\n id: Snowflake;\r\n name: string;\r\n color: number;\r\n hoist: boolean;\r\n icon?: string | null;\r\n unicode_emoji?: string | null;\r\n position: number;\r\n permissions: string;\r\n managed: boolean;\r\n mentionable: boolean;\r\n tags?: Record<string, unknown>;\r\n flags?: number;\r\n}\r\n\r\n/** Raw Discord guild role event payload. */\r\nexport interface APIGuildRoleEvent {\r\n guild_id: Snowflake;\r\n role: APIRole;\r\n}\r\n\r\n/** Raw Discord guild role delete event payload. */\r\nexport interface APIGuildRoleDeleteEvent {\r\n guild_id: Snowflake;\r\n role_id: Snowflake;\r\n}\r\n\r\n/** Raw Discord guild ban event payload. */\r\nexport interface APIGuildBanEvent {\r\n guild_id: Snowflake;\r\n user: UserData;\r\n}\r\n\r\n/** Raw Discord emoji object. */\r\nexport interface APIEmoji {\r\n id: Snowflake | null;\r\n name: string | null;\r\n roles?: Snowflake[];\r\n user?: UserData;\r\n require_colons?: boolean;\r\n managed?: boolean;\r\n animated?: boolean;\r\n available?: boolean;\r\n}\r\n\r\n/** Raw Discord guild emojis update event payload. */\r\nexport interface APIGuildEmojisUpdateEvent {\r\n guild_id: Snowflake;\r\n emojis: APIEmoji[];\r\n}\r\n",
|
|
19
|
-
"import {\n resolveGatewayIntents,\n type GatewayPayload,\n type GatewayProperties,\n type GatewayPresence,\n type GatewayIntentResolvable,\n} from \"@lunibee/types\";\n\n/** Discord Gateway opcodes. */\nexport const GatewayOpcodes = {\n Dispatch: 0,\n Heartbeat: 1,\n Identify: 2,\n PresenceUpdate: 3,\n VoiceStateUpdate: 4,\n Resume: 6,\n Reconnect: 7,\n RequestGuildMembers: 8,\n InvalidSession: 9,\n Hello: 10,\n HeartbeatAck: 11,\n} as const;\n/** Gateway connection lifecycle states. */\nexport enum GatewayState {\n /** Initial connection state. */ Connect = \"CONNECT\",\n /** Gateway HELLO received state. */ Hello = \"HELLO\",\n /** IDENTIFY operation in progress. */ Identify = \"IDENTIFY\",\n /** RESUME operation in progress. */ Resume = \"RESUME\",\n /** Gateway READY state. */ Ready = \"READY\",\n /** Gateway dispatch processing state. */ Dispatch = \"DISPATCH\",\n /** Heartbeat processing state. */ Heartbeat = \"HEARTBEAT\",\n /** Reconnect in progress. */ Reconnect = \"RECONNECT\",\n /** Gateway is permanently closed. */ Closed = \"CLOSED\",\n}\n/** Gateway protocol error. */\nexport class GatewayError extends Error {\n /** Gateway close/error code. */ public readonly code?: number;\n /** Creates a Gateway error. @param message Error message. @param code Optional Gateway code. @param options Optional error metadata. */ public constructor(\n message: string,\n code?: number,\n options?: ErrorOptions,\n ) {\n super(message, options);\n this.name = \"GatewayError\";\n this.code = code;\n }\n}\n/** Gateway connection configuration. */\nexport interface GatewayOptions {\n /** Authentication token. */ token: string;\n /** Gateway intent bitfield or resolvable. */ intents: GatewayIntentResolvable;\n /** Shard identifier. */ shardId?: number;\n /** Total shard count. */ shardCount?: number;\n /** Whether automatic reconnect is enabled. */ reconnect?: boolean;\n /** Maximum reconnect attempts. */ maxReconnectAttempts?: number;\n /** Initial reconnect delay. */ reconnectBaseDelay?: number;\n /** Maximum reconnect delay. */ reconnectMaxDelay?: number;\n /** Heartbeat acknowledgement timeout. */ heartbeatAckTimeout?: number;\n /** Zombie connection timeout. */ zombieTimeout?: number;\n /** Identification properties. */ properties?: GatewayProperties;\n /** Presence data. */ presence?: GatewayPresence;\n}\n/** Gateway event listener. */\ntype GatewayListener = (data: unknown) => unknown;\n/** Manages a Discord Gateway connection. */\nexport class Gateway {\n /** Current Gateway lifecycle state. */\n public state: GatewayState = GatewayState.Connect;\n #options: Required<Omit<GatewayOptions, \"properties\" | \"presence\">> & {\n properties?: GatewayProperties;\n presence?: GatewayPresence;\n };\n #ws?: WebSocket;\n #sequence: number | null = null;\n #sessionId?: string;\n #resumeURL?: string;\n #heartbeatTimer?: ReturnType<typeof setInterval>;\n #initialHeartbeat?: ReturnType<typeof setTimeout>;\n #heartbeatAckTimer?: ReturnType<typeof setTimeout>;\n #heartbeatACK = true;\n #heartbeatInterval = 0;\n #heartbeatSentAt = 0;\n #lastMessageAt = 0;\n #zombieTimer?: ReturnType<typeof setInterval>;\n #zombieReported = false;\n #closed = false;\n #attempt = 0;\n #reconnectTimer?: ReturnType<typeof setTimeout>;\n #connectPromise?: Promise<void>;\n #resolveConnect?: () => void;\n #rejectConnect?: (error: GatewayError) => void;\n readonly #listeners = new Map<string, Set<GatewayListener>>();\n readonly #sendTimestamps: number[] = [];\n /** Creates a Gateway connection manager. @param options Gateway configuration. @throws {TypeError|RangeError} If configuration is invalid. */\n public constructor(options: GatewayOptions) {\n if (!options.token?.trim())\n throw new TypeError(\"A Gateway token is required.\");\n const resolvedIntents = resolveGatewayIntents(options.intents);\n if (!Number.isInteger(resolvedIntents) || resolvedIntents < 0)\n throw new TypeError(\"Gateway intents must be a non-negative integer.\");\n this.#options = {\n shardId: 0,\n shardCount: 1,\n reconnect: true,\n maxReconnectAttempts: Infinity,\n reconnectBaseDelay: 1000,\n reconnectMaxDelay: 30000,\n heartbeatAckTimeout: 10000,\n zombieTimeout: 30000,\n properties: {\n os: \"Android\",\n browser: \"Discord Android\",\n device: \"Discord Android\",\n },\n presence: { status: \"online\", activities: [], afk: false, since: null },\n ...options,\n };\n if (\n this.#options.shardId < 0 ||\n this.#options.shardId >= this.#options.shardCount\n )\n throw new RangeError(\n \"Gateway shardId must be within the configured shard count.\",\n );\n if (this.#options.zombieTimeout <= this.#options.heartbeatAckTimeout)\n throw new RangeError(\n \"Gateway zombieTimeout must be greater than heartbeatAckTimeout\",\n );\n }\n\n /** Opens the Gateway connection. @param url Gateway WebSocket URL. @returns Promise fulfilled when the socket opens. @throws {GatewayError} If permanently closed or unable to connect. */\n public connect(\n url = \"wss://gateway.discord.gg/?v=10&encoding=json\",\n ): Promise<void> {\n if (this.state === GatewayState.Closed)\n throw new GatewayError(\"Gateway has been permanently closed.\");\n if (this.#connectPromise) return this.#connectPromise;\n this.#closed = false;\n this.#setState(GatewayState.Connect);\n this.#connectPromise = new Promise<void>((resolve, reject) => {\n this.#resolveConnect = resolve;\n this.#rejectConnect = reject;\n this.#open(url);\n });\n return this.#connectPromise;\n }\n /** Permanently closes the Gateway connection. */\n public close(): void {\n this.#closed = true;\n this.#clearTimers();\n this.#settleConnect(\n new GatewayError(\"Gateway connection closed before socket open.\"),\n );\n const ws = this.#ws;\n this.#ws = undefined;\n try {\n ws?.close(1000, \"Client closed connection\");\n } catch (error) {\n this.#emitError(error);\n }\n this.#setState(GatewayState.Closed);\n }\n /** Registers a Gateway event listener. @param event Event name. @param listener Event callback. @returns This Gateway. */\n /** Emits an event to all registered listeners. @param event Event name. @param data Event payload. */\n public emit(event: string, data?: unknown): void {\n this.#emit(event, data);\n }\n public on(event: string, listener: GatewayListener): this {\n if (!event || typeof listener !== \"function\")\n throw new TypeError(\"Gateway event and listener are required.\");\n let listeners = this.#listeners.get(event);\n if (!listeners) this.#listeners.set(event, (listeners = new Set()));\n listeners.add(listener);\n return this;\n }\n /** Removes a Gateway event listener. @param event Event name. @param listener Event callback. @returns This Gateway. */\n public off(event: string, listener: GatewayListener): this {\n this.#listeners.get(event)?.delete(listener);\n return this;\n }\n /** Sends a Gateway payload. @param payload Gateway payload. @returns Whether it was sent. */\n public send(payload: GatewayPayload): boolean {\n if (!payload || !Number.isInteger(payload.op))\n throw new TypeError(\"Gateway payload must contain an integer opcode.\");\n if (this.#ws?.readyState !== WebSocket.OPEN) return false;\n const now = Date.now();\n while (\n this.#sendTimestamps.length &&\n now - this.#sendTimestamps[0]! >= 60000\n )\n this.#sendTimestamps.shift();\n if (this.#sendTimestamps.length >= 115) {\n this.#emitError(new GatewayError(\"Gateway send rate budget exhausted.\"));\n return false;\n }\n try {\n this.#ws.send(JSON.stringify(payload));\n this.#sendTimestamps.push(now);\n return true;\n } catch (error) {\n this.#emitError(error);\n return false;\n }\n }\n /** Sends a presence update. @param data Presence payload. @returns Whether it was sent. */\n public setPresence(data: GatewayPresence): boolean {\n this.#options.presence = { ...this.#options.presence, ...data };\n const payload = {\n since: this.#options.presence.since ?? null,\n activities: this.#options.presence.activities ?? [],\n status: this.#options.presence.status ?? \"online\",\n afk: Boolean(this.#options.presence.afk),\n };\n return this.send({\n op: GatewayOpcodes.PresenceUpdate,\n d: payload,\n s: null,\n t: null,\n });\n }\n /** Sends a voice state update. @param data Voice state payload. @returns Whether it was sent. */\n public setVoiceState(data: Record<string, unknown>): boolean {\n return this.send({\n op: GatewayOpcodes.VoiceStateUpdate,\n d: data,\n s: null,\n t: null,\n });\n }\n /** Requests guild members. @param data Guild member request payload. @returns Whether it was sent. */\n public requestGuildMembers(data: Record<string, unknown>): boolean {\n return this.send({\n op: GatewayOpcodes.RequestGuildMembers,\n d: data,\n s: null,\n t: null,\n });\n }\n #open(url: string): void {\n if (this.#closed) return;\n let ws: WebSocket;\n try {\n ws = new WebSocket(url);\n } catch (error) {\n const failure = this.#normalizeError(error);\n this.#emitError(failure);\n if (this.#options.reconnect) {\n this.#setState(GatewayState.Reconnect);\n this.#scheduleReconnect();\n } else this.#settleConnect(failure);\n return;\n }\n this.#ws = ws;\n ws.addEventListener(\"open\", () => {\n this.#lastMessageAt = Date.now();\n this.#zombieReported = false;\n this.#startZombieDetection();\n this.#emit(\"open\", undefined);\n this.#settleConnect();\n });\n ws.addEventListener(\"message\", (event) => {\n this.#lastMessageAt = Date.now();\n this.#zombieReported = false;\n this.#message(ws, String(event.data));\n });\n ws.addEventListener(\"close\", (event) => this.#close(ws, event.code));\n ws.addEventListener(\"error\", () =>\n this.#emitError(new GatewayError(\"Gateway WebSocket error\")),\n );\n }\n #startZombieDetection(): void {\n if (this.#zombieTimer) clearInterval(this.#zombieTimer);\n const interval = Math.max(\n 1,\n Math.min(\n 250,\n this.#options.heartbeatAckTimeout,\n this.#options.zombieTimeout / 2,\n ),\n );\n this.#zombieTimer = setInterval(() => {\n if (\n this.#closed ||\n this.#ws?.readyState !== WebSocket.OPEN ||\n this.#lastMessageAt === 0\n )\n return;\n const silentFor = Date.now() - this.#lastMessageAt;\n const deadline = Math.max(\n this.#options.zombieTimeout,\n this.#heartbeatInterval + this.#options.heartbeatAckTimeout,\n );\n if (silentFor < deadline || this.#zombieReported) return;\n this.#zombieReported = true;\n const error = new GatewayError(\n `Gateway connection appears stale after ${silentFor}ms without traffic.`,\n );\n this.#emit(\"zombie\", { silentFor, timeout: deadline });\n this.#emitError(error);\n try {\n this.#ws.close(1001, \"Zombie Gateway connection\");\n } catch (closeError) {\n this.#emitError(closeError);\n }\n }, interval);\n }\n #message(ws: WebSocket, raw: string): void {\n let payload: GatewayPayload;\n try {\n payload = JSON.parse(raw) as GatewayPayload;\n } catch (error) {\n this.#emitError(\n new GatewayError(\"Gateway returned invalid JSON\", undefined, {\n cause: error,\n }),\n );\n ws.close(1002, \"Invalid JSON\");\n return;\n }\n if (!payload || typeof payload.op !== \"number\") {\n this.#emitError(new GatewayError(\"Gateway returned an invalid payload\"));\n ws.close(1002, \"Invalid payload\");\n return;\n }\n if (typeof payload.s === \"number\") this.#sequence = payload.s;\n switch (payload.op) {\n case GatewayOpcodes.Dispatch:\n this.#setState(GatewayState.Dispatch);\n this.#handleDispatch(payload.t, payload.d);\n break;\n case GatewayOpcodes.Hello:\n this.#handleHello(payload.d);\n break;\n case GatewayOpcodes.Heartbeat:\n this.#setState(GatewayState.Heartbeat);\n this.#sendHeartbeat();\n break;\n case GatewayOpcodes.HeartbeatAck:\n this.#heartbeatACK = true;\n this.#clearHeartbeatAckTimer();\n this.#emit(\"heartbeatAck\", payload.d);\n break;\n case GatewayOpcodes.Reconnect:\n ws.close(1001, \"Server requested reconnect\");\n break;\n case GatewayOpcodes.InvalidSession:\n this.#sessionId = undefined;\n this.#sequence = null;\n this.#emit(\"invalidSession\", payload.d);\n ws.close(1000, \"Invalid session\");\n break;\n }\n }\n #handleDispatch(event: string | null, data: unknown): void {\n if (event === \"READY\") {\n const ready = data as {\n session_id?: unknown;\n resume_gateway_url?: unknown;\n };\n if (\n typeof ready?.session_id !== \"string\" ||\n typeof ready?.resume_gateway_url !== \"string\"\n ) {\n this.#emitError(\n new GatewayError(\n \"Gateway READY payload is missing session information\",\n ),\n );\n return;\n }\n this.#sessionId = ready.session_id;\n this.#resumeURL = ready.resume_gateway_url;\n this.#attempt = 0;\n this.#setState(GatewayState.Ready);\n this.#emit(\"ready\", data);\n }\n this.#emit(event ?? \"dispatch\", data);\n }\n #handleHello(data: unknown): void {\n const interval = (data as { heartbeat_interval?: unknown })\n ?.heartbeat_interval;\n if (\n typeof interval !== \"number\" ||\n !Number.isFinite(interval) ||\n interval <= 0\n ) {\n this.#emitError(\n new GatewayError(\n \"Gateway HELLO payload contains an invalid heartbeat interval\",\n ),\n );\n this.#ws?.close(1002, \"Invalid heartbeat interval\");\n return;\n }\n this.#heartbeatInterval = interval;\n this.#setState(\n this.#sessionId && this.#sequence !== null && this.#resumeURL\n ? GatewayState.Resume\n : GatewayState.Hello,\n );\n this.#startHeartbeat(interval);\n this.#identifyOrResume();\n }\n #identifyOrResume(): void {\n if (this.#sessionId && this.#sequence !== null && this.#resumeURL) {\n this.#setState(GatewayState.Resume);\n this.send({\n op: GatewayOpcodes.Resume,\n d: {\n token: this.#options.token,\n session_id: this.#sessionId,\n seq: this.#sequence,\n },\n s: null,\n t: null,\n });\n return;\n }\n this.#setState(GatewayState.Identify);\n const props = this.#options.properties ?? {\n os: \"Android\",\n browser: \"Discord Android\",\n device: \"Discord Android\",\n };\n const os = props.os ?? \"Android\";\n const browser = props.browser ?? \"Discord Android\";\n const device = props.device ?? \"Discord Android\";\n this.send({\n op: GatewayOpcodes.Identify,\n d: {\n token: this.#options.token,\n intents: this.#options.intents,\n properties: {\n os,\n browser,\n device,\n $os: os,\n $browser: browser,\n $device: device,\n ...props,\n },\n presence: {\n since: this.#options.presence?.since ?? null,\n activities: this.#options.presence?.activities ?? [],\n status: this.#options.presence?.status ?? \"online\",\n afk: Boolean(this.#options.presence?.afk),\n },\n shard: [this.#options.shardId, this.#options.shardCount],\n },\n s: null,\n t: null,\n });\n }\n #startHeartbeat(interval: number): void {\n this.#clearHeartbeatTimers();\n this.#heartbeatACK = true;\n this.#initialHeartbeat = setTimeout(\n () => this.#sendHeartbeat(),\n Math.random() * interval,\n );\n this.#heartbeatTimer = setInterval(() => this.#sendHeartbeat(), interval);\n }\n #sendHeartbeat(): void {\n this.#heartbeatACK = false;\n this.#heartbeatSentAt = Date.now();\n if (\n !this.send({\n op: GatewayOpcodes.Heartbeat,\n d: this.#sequence,\n s: null,\n t: null,\n })\n ) {\n this.#emitError(\n new GatewayError(\n \"Unable to send Gateway heartbeat because the WebSocket is not open.\",\n ),\n );\n return;\n }\n this.#clearHeartbeatAckTimer();\n this.#heartbeatAckTimer = setTimeout(() => {\n if (!this.#heartbeatACK) {\n const elapsed = Date.now() - this.#heartbeatSentAt;\n this.#emitError(\n new GatewayError(\n `Gateway heartbeat acknowledgement timed out after ${elapsed}ms.`,\n ),\n );\n try {\n this.#ws?.close(1001, \"Heartbeat timeout\");\n } catch (error) {\n this.#emitError(error);\n }\n }\n }, this.#options.heartbeatAckTimeout);\n }\n #close(ws: WebSocket, code: number): void {\n if (this.#ws !== ws) return;\n this.#ws = undefined;\n this.#clearTimers();\n const action = this.#closeAction(code);\n this.#emit(\"close\", { code, action });\n if (this.#closed || !this.#options.reconnect || action === \"stop\") {\n this.#setState(this.#closed ? GatewayState.Closed : GatewayState.Connect);\n if (this.#connectPromise)\n this.#settleConnect(\n new GatewayError(`Gateway closed before READY (code ${code}).`, code),\n );\n return;\n }\n if (action === \"identify\") {\n this.#sequence = null;\n this.#sessionId = undefined;\n }\n this.#setState(GatewayState.Reconnect);\n this.#scheduleReconnect();\n }\n #closeAction(code: number): \"resume\" | \"identify\" | \"stop\" {\n if ([4004, 4010, 4011, 4012, 4013, 4014].includes(code)) return \"stop\";\n if ([4007, 4009].includes(code)) return \"identify\";\n return this.#sessionId && this.#sequence !== null ? \"resume\" : \"identify\";\n }\n #scheduleReconnect(): void {\n if (this.#closed || !this.#options.reconnect || this.#reconnectTimer)\n return;\n if (this.#attempt >= this.#options.maxReconnectAttempts) {\n this.#settleConnect(\n new GatewayError(\"Gateway reconnect attempts exhausted.\"),\n );\n this.#setState(GatewayState.Connect);\n return;\n }\n const delay = Math.min(\n this.#options.reconnectMaxDelay,\n this.#options.reconnectBaseDelay * 2 ** this.#attempt++,\n );\n const jitter = Math.random() * Math.min(250, Math.max(1, delay * 0.25));\n this.#reconnectTimer = setTimeout(() => {\n this.#reconnectTimer = undefined;\n this.#open(\n this.#resumeURL ?? \"wss://gateway.discord.gg/?v=10&encoding=json\",\n );\n }, delay + jitter);\n }\n #settleConnect(error?: GatewayError): void {\n const resolve = this.#resolveConnect;\n const reject = this.#rejectConnect;\n this.#resolveConnect = undefined;\n this.#rejectConnect = undefined;\n this.#connectPromise = undefined;\n if (error) reject?.(error);\n else resolve?.();\n }\n #clearHeartbeatAckTimer(): void {\n if (this.#heartbeatAckTimer) clearTimeout(this.#heartbeatAckTimer);\n this.#heartbeatAckTimer = undefined;\n }\n #clearHeartbeatTimers(): void {\n if (this.#heartbeatTimer) clearInterval(this.#heartbeatTimer);\n if (this.#initialHeartbeat) clearTimeout(this.#initialHeartbeat);\n this.#clearHeartbeatAckTimer();\n this.#heartbeatTimer = undefined;\n this.#initialHeartbeat = undefined;\n }\n #clearTimers(): void {\n if (this.#reconnectTimer) clearTimeout(this.#reconnectTimer);\n if (this.#zombieTimer) clearInterval(this.#zombieTimer);\n this.#reconnectTimer = undefined;\n this.#zombieTimer = undefined;\n this.#clearHeartbeatTimers();\n }\n #normalizeError(error: unknown): GatewayError {\n return error instanceof GatewayError\n ? error\n : new GatewayError(\"Gateway connection failed.\", undefined, {\n cause: error,\n });\n }\n #emitError(error: unknown): void {\n this.#emit(\n \"error\",\n error instanceof Error ? error : new GatewayError(String(error)),\n );\n }\n #emit(event: string, data: unknown): void {\n for (const listener of this.#listeners.get(event) ?? []) {\n try {\n const result = listener(data);\n if (\n result &&\n typeof (result as PromiseLike<unknown>).then === \"function\"\n )\n void Promise.resolve(result).catch((error) => {\n if (event !== \"error\") this.#emitError(error);\n });\n } catch (error) {\n if (event !== \"error\") this.#emitError(error);\n }\n }\n }\n /** Changes the Gateway lifecycle state. @param next Next lifecycle state. */\n #setState(next: GatewayState): void {\n if (this.state === next) return;\n const previous = this.state;\n this.state = next;\n this.#emit(\"stateChange\", { previous, next });\n }\n}\n",
|
|
20
|
-
"/** Discord API embed field payload. */\nexport interface EmbedField {\n /** Field name. */ name: string;\n /** Field value. */ value: string;\n /** Whether the field is displayed inline. */ inline?: boolean;\n}\n/** Discord API embed footer payload. */\nexport interface EmbedFooter {\n /** Footer text. */ text: string;\n /** Footer icon URL. */ icon_url?: string;\n}\n/** Discord API embed author payload. */\nexport interface EmbedAuthor {\n /** Author display name. */ name: string;\n /** Author URL. */ url?: string;\n /** Author icon URL. */ icon_url?: string;\n}\n/** Strict Discord API embed payload. */\nexport interface APIEmbed {\n /** Embed title. */ title?: string;\n /** Embed description. */ description?: string;\n /** Embed URL. */ url?: string;\n /** Embed color. */ color?: number;\n /** ISO-8601 timestamp. */ timestamp?: string;\n /** Embed footer. */ footer?: EmbedFooter;\n /** Embed author. */ author?: EmbedAuthor;\n /** Thumbnail payload. */ thumbnail?: { /** Thumbnail URL. */ url: string };\n /** Image payload. */ image?: { /** Image URL. */ url: string };\n /** Embed fields. */ fields?: EmbedField[];\n}\n\n/** Builds compile-time-safe rich embed payloads for Discord API requests. */\nexport class EmbedBuilder {\n readonly #data: APIEmbed = {};\n /** Sets the embed title. @param value Title text. @returns This builder. @throws {RangeError} If title exceeds Discord's limit. */ public setTitle(\n value: string,\n ): this {\n this.#data.title = validate(value, 256, \"Embed title\");\n return this;\n }\n /** Sets the embed description. @param value Description text. @returns This builder. @throws {RangeError} If description exceeds Discord's limit. */ public setDescription(\n value: string,\n ): this {\n this.#data.description = validate(value, 4096, \"Embed description\");\n return this;\n }\n /** Sets the embed URL. @param value Absolute URL. @returns This builder. @throws {TypeError} If URL is invalid. */ public setURL(\n value: string,\n ): this {\n this.#data.url = url(value, \"Embed URL\");\n return this;\n }\n /** Sets the embed color. @param value RGB integer. @returns This builder. @throws {RangeError} If color is outside 24-bit RGB range. */ public setColor(\n value: number,\n ): this {\n if (!Number.isInteger(value) || value < 0 || value > 0xffffff)\n throw new RangeError(\n \"Embed color must be an integer between 0 and 16777215.\",\n );\n this.#data.color = value;\n return this;\n }\n /** Sets the embed timestamp. @param value Date value. @returns This builder. @throws {RangeError} If date is invalid. */ public setTimestamp(\n value = new Date(),\n ): this {\n const date = value instanceof Date ? value : new Date(value);\n if (Number.isNaN(date.getTime()))\n throw new RangeError(\"Embed timestamp must be a valid date.\");\n this.#data.timestamp = date.toISOString();\n return this;\n }\n /** Sets the embed footer. @param value Footer payload. @returns This builder. @throws {RangeError} If footer text exceeds Discord's limit. */ public setFooter(\n value: EmbedFooter,\n ): this {\n this.#data.footer = {\n text: validate(value.text, 2048, \"Footer text\"),\n ...(value.icon_url\n ? { icon_url: url(value.icon_url, \"Footer icon URL\") }\n : {}),\n };\n return this;\n }\n /** Sets the embed author. @param value Author payload. @returns This builder. @throws {RangeError} If author name exceeds Discord's limit. */ public setAuthor(\n value: EmbedAuthor,\n ): this {\n this.#data.author = {\n name: validate(value.name, 256, \"Author name\"),\n ...(value.url ? { url: url(value.url, \"Author URL\") } : {}),\n ...(value.icon_url\n ? { icon_url: url(value.icon_url, \"Author icon URL\") }\n : {}),\n };\n return this;\n }\n /** Sets the thumbnail URL. @param value Thumbnail URL or payload. @returns This builder. @throws {TypeError} If URL is invalid. */ public setThumbnail(\n value: { url: string } | string,\n ): this {\n const valueURL = typeof value === \"string\" ? value : value.url;\n this.#data.thumbnail = { url: url(valueURL, \"Thumbnail URL\") };\n return this;\n }\n /** Sets the image URL. @param value Image URL or payload. @returns This builder. @throws {TypeError} If URL is invalid. */ public setImage(\n value: { url: string } | string,\n ): this {\n const valueURL = typeof value === \"string\" ? value : value.url;\n this.#data.image = { url: url(valueURL, \"Image URL\") };\n return this;\n }\n /** Adds embed fields. @param fields Field payloads. @returns This builder. @throws {RangeError} If the 25-field limit is exceeded. */ public addFields(\n ...fields: EmbedField[]\n ): this {\n if (!fields.length)\n throw new TypeError(\"At least one embed field is required.\");\n const current = this.#data.fields ?? [];\n if (current.length + fields.length > 25)\n throw new RangeError(\"An embed cannot contain more than 25 fields.\");\n for (const field of fields) {\n validate(field.name, 256, \"Embed field name\");\n validate(field.value, 1024, \"Embed field value\");\n }\n this.#data.fields = [...current, ...fields.map((field) => ({ ...field }))];\n return this;\n }\n public setFields(fields: EmbedField[]): this {\n this.#data.fields = [];\n return this.addFields(...fields);\n }\n /** Replaces fields starting at an index. @param index Start index. @param deleteCount Number of fields to remove. @param fields Replacement fields. @returns This builder. @throws {RangeError} If arguments are invalid or the 25-field limit is exceeded. */ public spliceFields(\n index: number,\n deleteCount: number,\n ...fields: EmbedField[]\n ): this {\n const current = [...(this.#data.fields ?? [])];\n if (\n !Number.isInteger(index) ||\n !Number.isInteger(deleteCount) ||\n index < 0 ||\n deleteCount < 0\n )\n throw new RangeError(\n \"Field index and delete count must be non-negative integers.\",\n );\n current.splice(index, deleteCount, ...fields);\n if (current.length > 25)\n throw new RangeError(\"An embed cannot contain more than 25 fields.\");\n this.#data.fields = current;\n return this;\n }\n /** Removes all embed fields. @returns This builder. */ public clearFields(): this {\n delete this.#data.fields;\n return this;\n }\n /** Removes the embed title. @returns This builder. */ public clearTitle(): this {\n delete this.#data.title;\n return this;\n }\n /** Removes the embed description. @returns This builder. */ public clearDescription(): this {\n delete this.#data.description;\n return this;\n }\n /** Returns a deep-cloned Discord API payload. @returns Strict embed payload. */ public get data(): APIEmbed {\n return this.toJSON();\n }\n public toJSON(): APIEmbed {\n return structuredClone(this.#data);\n }\n}\n/** Validates a bounded Discord string field. @param value Field value. @param max Maximum length. @param field Human-readable field name. @returns Validated value. @throws {RangeError} If length is invalid. */\nfunction validate(value: string, max: number, field: string): string {\n if (typeof value !== \"string\" || value.length === 0 || value.length > max)\n throw new RangeError(`${field} must contain 1-${max} characters.`);\n return value;\n}\n/** Validates and normalizes an absolute URL. @param value URL value. @param field Human-readable field name. @returns Normalized URL. @throws {TypeError} If URL is invalid. */\nfunction url(value: string, field: string): string {\n try {\n return new URL(value).toString();\n } catch (error) {\n throw new TypeError(`${field} must be a valid URL.`, { cause: error });\n }\n}\n",
|
|
21
|
-
"/** Component type constants exposed by Lunibee. */\nexport const ComponentType = {\n ActionRow: 1,\n Button: 2,\n StringSelect: 3,\n TextInput: 4,\n UserSelect: 5,\n RoleSelect: 6,\n MentionableSelect: 7,\n ChannelSelect: 8,\n} as const;\nexport const ButtonStyle = {\n Primary: 1,\n Secondary: 2,\n Success: 3,\n Danger: 4,\n Link: 5,\n} as const;\nexport const TextInputStyle = { Short: 1, Paragraph: 2 } as const;\nexport interface APIComponentEmoji {\n id?: string | null;\n name?: string | null;\n animated?: boolean;\n}\nexport interface APIButtonComponent {\n type: typeof ComponentType.Button;\n style: 1 | 2 | 3 | 4 | 5;\n custom_id?: string;\n label?: string;\n emoji?: APIComponentEmoji;\n url?: string;\n disabled?: boolean;\n}\nexport interface APISelectOption {\n label: string;\n value: string;\n description?: string;\n emoji?: APIComponentEmoji;\n default?: boolean;\n}\nexport interface APIStringSelectComponent {\n type: typeof ComponentType.StringSelect;\n custom_id?: string;\n placeholder?: string;\n min_values?: number;\n max_values?: number;\n required?: boolean;\n disabled?: boolean;\n options?: APISelectOption[];\n}\nexport interface APIEntitySelectComponent {\n type:\n | typeof ComponentType.UserSelect\n | typeof ComponentType.RoleSelect\n | typeof ComponentType.MentionableSelect\n | typeof ComponentType.ChannelSelect;\n custom_id?: string;\n placeholder?: string;\n min_values?: number;\n max_values?: number;\n required?: boolean;\n disabled?: boolean;\n}\nexport interface APITextInputComponent {\n type: typeof ComponentType.TextInput;\n style: typeof TextInputStyle.Short | typeof TextInputStyle.Paragraph;\n custom_id?: string;\n label?: string;\n placeholder?: string;\n min_length?: number;\n max_length?: number;\n required?: boolean;\n value?: string;\n}\nexport interface APIModalComponent {\n type: 9;\n custom_id?: string;\n title?: string;\n components: APIActionRowComponent[];\n}\nexport type APIActionRowChild =\n | APIButtonComponent\n | APIStringSelectComponent\n | APIEntitySelectComponent\n | APITextInputComponent;\nexport interface APIActionRowComponent {\n type: typeof ComponentType.ActionRow;\n components: APIActionRowChild[];\n}\n\nexport class ActionRowBuilder<\n T extends { toJSON(): APIActionRowChild } = { toJSON(): APIActionRowChild },\n> {\n readonly #components: T[] = [];\n public addComponents(...components: T[]): this {\n if (!components.length)\n throw new TypeError(\"At least one component is required.\");\n if (this.#components.length + components.length > 5)\n throw new RangeError(\n \"An action row cannot contain more than 5 components.\",\n );\n this.#components.push(...components);\n return this;\n }\n public clearComponents(): this {\n this.#components.length = 0;\n return this;\n }\n public toJSON(): APIActionRowComponent {\n return {\n type: ComponentType.ActionRow,\n components: this.#components.map((component) => component.toJSON()),\n };\n }\n}\nexport class StringSelectBuilder {\n readonly #data: APIStringSelectComponent = {\n type: ComponentType.StringSelect,\n };\n public setCustomId(value: string): this {\n validateText(value, 100, \"Component custom ID\");\n this.#data.custom_id = value;\n return this;\n }\n public setPlaceholder(value: string): this {\n validateText(value, 150, \"Component placeholder\");\n this.#data.placeholder = value;\n return this;\n }\n public setMinValues(value: number): this {\n validateCount(value, \"min_values\", 0);\n this.#data.min_values = value;\n return this;\n }\n public setMaxValues(value: number): this {\n validateCount(value, \"max_values\", 1);\n this.#data.max_values = value;\n return this;\n }\n public setRequired(value = true): this {\n this.#data.required = value;\n return this;\n }\n public setDisabled(value = true): this {\n this.#data.disabled = value;\n return this;\n }\n public addOptions(...options: APISelectOption[]): this {\n if (!options.length)\n throw new TypeError(\"At least one select option is required.\");\n const current = this.#data.options ?? [];\n if (current.length + options.length > 25)\n throw new RangeError(\n \"A string select cannot contain more than 25 options.\",\n );\n for (const option of options) {\n validateText(option.label, 100, \"Select option label\");\n validateText(option.value, 100, \"Select option value\");\n if (option.description)\n validateText(option.description, 100, \"Select option description\");\n }\n this.#data.options = [\n ...current,\n ...options.map((option) => ({ ...option })),\n ];\n return this;\n }\n public toJSON(): APIStringSelectComponent {\n return structuredClone(this.#data);\n }\n}\nexport class ButtonBuilder {\n readonly #data: APIButtonComponent = {\n type: ComponentType.Button,\n style: ButtonStyle.Secondary,\n };\n public setStyle(style: APIButtonComponent[\"style\"]): this {\n this.#data.style = style;\n if (style === ButtonStyle.Link) delete this.#data.custom_id;\n return this;\n }\n public setCustomId(value: string): this {\n validateText(value, 100, \"Button custom ID\");\n if (this.#data.style === ButtonStyle.Link)\n throw new TypeError(\"Link buttons cannot use custom IDs.\");\n this.#data.custom_id = value;\n return this;\n }\n public setLabel(value: string): this {\n validateText(value, 80, \"Button label\");\n this.#data.label = value;\n return this;\n }\n public setURL(value: string): this {\n validateText(value, 512, \"Button URL\");\n let url: URL;\n try {\n url = new URL(value);\n } catch (error) {\n throw new TypeError(\"Button URL must be a valid URL.\", { cause: error });\n }\n this.#data.style = ButtonStyle.Link;\n delete this.#data.custom_id;\n this.#data.url = url.toString();\n return this;\n }\n public setEmoji(emoji: APIComponentEmoji | string): this {\n this.#data.emoji =\n typeof emoji === \"string\" ? { name: emoji } : { ...emoji };\n return this;\n }\n public setDisabled(value = true): this {\n this.#data.disabled = value;\n return this;\n }\n public toJSON(): APIButtonComponent {\n return structuredClone(this.#data);\n }\n}\nexport class EntitySelectBuilder {\n readonly #data: APIEntitySelectComponent;\n public constructor(\n type:\n | typeof ComponentType.UserSelect\n | typeof ComponentType.RoleSelect\n | typeof ComponentType.MentionableSelect\n | typeof ComponentType.ChannelSelect,\n ) {\n if (\n type !== ComponentType.UserSelect &&\n type !== ComponentType.RoleSelect &&\n type !== ComponentType.MentionableSelect &&\n type !== ComponentType.ChannelSelect\n )\n throw new TypeError(\"Invalid select component type.\");\n this.#data = { type };\n }\n public setCustomId(value: string): this {\n validateText(value, 100, \"Component custom ID\");\n this.#data.custom_id = value;\n return this;\n }\n public setPlaceholder(value: string): this {\n validateText(value, 150, \"Component placeholder\");\n this.#data.placeholder = value;\n return this;\n }\n public setMinValues(value: number): this {\n validateCount(value, \"min_values\", 0);\n this.#data.min_values = value;\n return this;\n }\n public setMaxValues(value: number): this {\n validateCount(value, \"max_values\", 1);\n this.#data.max_values = value;\n return this;\n }\n public setRequired(value = true): this {\n this.#data.required = value;\n return this;\n }\n public setDisabled(value = true): this {\n this.#data.disabled = value;\n return this;\n }\n public setDefaultValues(\n ...values: { id: string; type: \"user\" | \"role\" | \"channel\" }[]\n ): this {\n (this.#data as any).default_values = values;\n return this;\n }\n public toJSON(): APIEntitySelectComponent {\n return structuredClone(this.#data);\n }\n}\nexport class ModalBuilder {\n readonly #components: Array<{ toJSON(): APIActionRowComponent }> = [];\n #custom_id?: string;\n #title?: string;\n public setCustomId(value: string): this {\n validateText(value, 100, \"Modal custom ID\");\n this.#custom_id = value;\n return this;\n }\n public setTitle(value: string): this {\n validateText(value, 45, \"Modal title\");\n this.#title = value;\n return this;\n }\n public addComponents(\n ...components: Array<{ toJSON(): APIActionRowComponent }>\n ): this {\n if (!components.length)\n throw new TypeError(\"At least one modal component is required.\");\n if (this.#components.length + components.length > 5)\n throw new RangeError(\"A modal cannot contain more than 5 action rows.\");\n this.#components.push(...components);\n return this;\n }\n public toJSON(): APIModalComponent {\n return {\n type: 9,\n ...(this.#custom_id ? { custom_id: this.#custom_id } : {}),\n ...(this.#title ? { title: this.#title } : {}),\n components: this.#components.map((component) => component.toJSON()),\n };\n }\n}\nexport class TextInputBuilder {\n readonly #data: APITextInputComponent = {\n type: ComponentType.TextInput,\n style: TextInputStyle.Short,\n };\n public setStyle(style: APITextInputComponent[\"style\"]): this {\n this.#data.style = style;\n return this;\n }\n public setCustomId(value: string): this {\n validateText(value, 100, \"Text input custom ID\");\n this.#data.custom_id = value;\n return this;\n }\n public setLabel(value: string): this {\n validateText(value, 45, \"Text input label\");\n this.#data.label = value;\n return this;\n }\n public setPlaceholder(value: string): this {\n validateText(value, 100, \"Text input placeholder\");\n this.#data.placeholder = value;\n return this;\n }\n public setMinLength(value: number): this {\n validateLength(value, \"min_length\", 4000);\n this.#data.min_length = value;\n return this;\n }\n public setMaxLength(value: number): this {\n validateLength(value, \"max_length\", 4000);\n this.#data.max_length = value;\n return this;\n }\n public setRequired(value = true): this {\n this.#data.required = value;\n return this;\n }\n public setValue(value: string): this {\n validateText(value, 4000, \"Text input value\");\n this.#data.value = value;\n return this;\n }\n public toJSON(): APITextInputComponent {\n return structuredClone(this.#data);\n }\n}\nfunction validateText(value: string, max: number, field: string): void {\n if (typeof value !== \"string\")\n throw new TypeError(`${field} must be a string.`);\n if (!value.trim())\n throw new RangeError(`${field} must be a non-empty string.`);\n if (value.length > max)\n throw new RangeError(`${field} cannot exceed ${max} characters.`);\n}\nfunction validateCount(\n value: number,\n field: string,\n min: number,\n max = 25,\n): void {\n if (!Number.isInteger(value) || value < min || value > max)\n throw new RangeError(\n `${field} must be an integer between ${min} and ${max}.`,\n );\n}\nfunction validateLength(value: number, field: string, max = 4000): void {\n if (!Number.isInteger(value) || value < 0 || value > max)\n throw new RangeError(`${field} must be an integer between 0 and ${max}.`);\n}\n",
|
|
22
|
-
"/** Discord application command option types. */\nexport const ApplicationCommandOptionType = {\n Subcommand: 1,\n SubcommandGroup: 2,\n String: 3,\n Integer: 4,\n Boolean: 5,\n User: 6,\n Channel: 7,\n Role: 8,\n Mentionable: 9,\n Number: 10,\n Attachment: 11,\n} as const;\n\n/** Builds Discord application command payloads. */\nexport class SlashCommandBuilder {\n readonly #data: Record<string, unknown> = { type: 1 };\n /** Sets the command name. */ public setName(name: string): this {\n validateName(name, \"Command name\");\n this.#data.name = name;\n return this;\n }\n /** Sets the command description. */ public setDescription(\n description: string,\n ): this {\n validateText(description, \"Command description\", 100);\n this.#data.description = description;\n return this;\n }\n /** Sets whether the command is available in direct messages. */ public setDMPermission(\n enabled: boolean,\n ): this {\n this.#data.dm_permission = enabled;\n return this;\n }\n /** Sets whether the command is NSFW. */\n public setNSFW(nsfw = true): this {\n this.#data.nsfw = nsfw;\n return this;\n }\n /** Sets whether the command is NSFW. */\n public setNsfw(nsfw = true): this {\n return this.setNSFW(nsfw);\n }\n /** Sets command default member permissions. */ public setDefaultMemberPermissions(\n permissions: bigint | number | string | null,\n ): this {\n this.#data.default_member_permissions =\n permissions === null ? null : BigInt(permissions).toString();\n return this;\n }\n /** Sets command integration types. */ public setIntegrationTypes(\n ...types: number[]\n ): this {\n this.#data.integration_types = [...types];\n return this;\n }\n /** Adds a string option. */ public addStringOption(\n configure: (option: StringOptionBuilder) => StringOptionBuilder,\n ): this {\n return this.addOption(configure(new StringOptionBuilder()));\n }\n /** Adds an integer option. */ public addIntegerOption(\n configure: (option: IntegerOptionBuilder) => IntegerOptionBuilder,\n ): this {\n return this.addOption(configure(new IntegerOptionBuilder()));\n }\n /** Adds a number option. */ public addNumberOption(\n configure: (option: NumberOptionBuilder) => NumberOptionBuilder,\n ): this {\n return this.addOption(configure(new NumberOptionBuilder()));\n }\n /** Adds a boolean option. */ public addBooleanOption(\n configure: (option: BooleanOptionBuilder) => BooleanOptionBuilder,\n ): this {\n return this.addOption(configure(new BooleanOptionBuilder()));\n }\n /** Adds a user option. */ public addUserOption(\n configure: (option: UserOptionBuilder) => UserOptionBuilder,\n ): this {\n return this.addOption(configure(new UserOptionBuilder()));\n }\n /** Adds a channel option. */ public addChannelOption(\n configure: (option: ChannelOptionBuilder) => ChannelOptionBuilder,\n ): this {\n return this.addOption(configure(new ChannelOptionBuilder()));\n }\n /** Adds a role option. */ public addRoleOption(\n configure: (option: RoleOptionBuilder) => RoleOptionBuilder,\n ): this {\n return this.addOption(configure(new RoleOptionBuilder()));\n }\n /** Adds a mentionable option. */ public addMentionableOption(\n configure: (option: MentionableOptionBuilder) => MentionableOptionBuilder,\n ): this {\n return this.addOption(configure(new MentionableOptionBuilder()));\n }\n /** Adds an attachment option. */ public addAttachmentOption(\n configure: (option: AttachmentOptionBuilder) => AttachmentOptionBuilder,\n ): this {\n return this.addOption(configure(new AttachmentOptionBuilder()));\n }\n /** Adds a subcommand. */ public addSubcommand(\n configure: (option: SubcommandBuilder) => SubcommandBuilder,\n ): this {\n return this.addOption(configure(new SubcommandBuilder()));\n }\n /** Adds a subcommand group. */ public addSubcommandGroup(\n configure: (option: SubcommandGroupBuilder) => SubcommandGroupBuilder,\n ): this {\n return this.addOption(configure(new SubcommandGroupBuilder()));\n }\n /** Serializes the command payload. */ public toJSON(): Record<\n string,\n unknown\n > {\n return structuredClone(this.#data);\n }\n /** Adds a validated top-level command option. */ protected addOption(\n option: CommandOptionBuilder,\n ): this {\n const options = (this.#data.options as unknown[] | undefined) ?? [];\n if (options.length >= 25)\n throw new RangeError(\n \"An application command cannot contain more than 25 options.\",\n );\n const payload = option.toJSON();\n if (\n options.some(\n (existing) =>\n (existing as Record<string, unknown>).name === payload.name,\n )\n )\n throw new RangeError(`Duplicate option name: ${String(payload.name)}.`);\n if (\n payload.required === true &&\n options.some(\n (existing) => (existing as Record<string, unknown>).required !== true,\n )\n )\n throw new RangeError(\n \"Required application command options must be placed before optional options.\",\n );\n options.push(payload);\n this.#data.options = options;\n return this;\n }\n}\n\n/** Base builder for command options. */\nexport class CommandOptionBuilder {\n protected readonly data: Record<string, unknown>;\n /** Creates an option builder. */ public constructor(type: number) {\n this.data = { type };\n }\n /** Sets the option name. */ public setName(name: string): this {\n validateName(name, \"Option name\");\n this.data.name = name;\n return this;\n }\n /** Sets the option description. */ public setDescription(\n description: string,\n ): this {\n validateText(description, \"Option description\", 100);\n this.data.description = description;\n return this;\n }\n /** Makes the option required or optional. */ public setRequired(\n required = true,\n ): this {\n this.data.required = required;\n return this;\n }\n /** Sets autocomplete. */ public setAutocomplete(enabled = true): this {\n this.data.autocomplete = enabled;\n return this;\n }\n /** Serializes the option payload. */ public toJSON(): Record<\n string,\n unknown\n > {\n return structuredClone(this.data);\n }\n}\n\n/** Builds a string command option. */\nexport class StringOptionBuilder extends CommandOptionBuilder {\n /** Creates a string option. */ public constructor() {\n super(ApplicationCommandOptionType.String);\n }\n /** Adds string choices. */ public addChoices(\n ...choices: Array<{ name: string; value: string }>\n ): this {\n const current = (this.data.choices as unknown[] | undefined) ?? [];\n if (!choices.length)\n throw new TypeError(\"At least one choice is required.\");\n if (this.data.autocomplete === true)\n throw new RangeError(\"Autocomplete options cannot define choices.\");\n if (current.length + choices.length > 25)\n throw new RangeError(\"An option cannot contain more than 25 choices.\");\n for (const choice of choices) {\n validateText(choice.name, \"Choice name\", 100);\n validateText(choice.value, \"Choice value\", 100);\n }\n this.data.choices = [\n ...current,\n ...choices.map((choice) => ({ ...choice })),\n ];\n return this;\n }\n /** Sets the minimum string length. */ public setMinLength(\n value: number,\n ): this {\n validateIntegerRange(value, 0, 6000, \"min_length\");\n this.data.min_length = value;\n return this;\n }\n /** Sets the maximum string length. */ public setMaxLength(\n value: number,\n ): this {\n validateIntegerRange(value, 1, 6000, \"max_length\");\n if (\n (this.data.min_length as number | undefined) !== undefined &&\n (this.data.min_length as number) > value\n )\n throw new RangeError(\"min_length cannot exceed max_length.\");\n this.data.max_length = value;\n return this;\n }\n}\n/** Builds an integer command option. */\nexport class IntegerOptionBuilder extends CommandOptionBuilder {\n public constructor() {\n super(ApplicationCommandOptionType.Integer);\n }\n public setMinValue(value: number): this {\n validateNumberRange(\n value,\n -9_007_199_254_740_991,\n 9_007_199_254_740_991,\n \"min_value\",\n true,\n );\n this.data.min_value = value;\n return this;\n }\n public setMaxValue(value: number): this {\n validateNumberRange(\n value,\n -9_007_199_254_740_991,\n 9_007_199_254_740_991,\n \"max_value\",\n true,\n );\n if (\n (this.data.min_value as number | undefined) !== undefined &&\n (this.data.min_value as number) > value\n )\n throw new RangeError(\"min_value cannot exceed max_value.\");\n this.data.max_value = value;\n return this;\n }\n public setAutocomplete(enabled = true): this {\n if (enabled && Array.isArray(this.data.choices) && this.data.choices.length)\n throw new RangeError(\"Autocomplete options cannot define choices.\");\n this.data.autocomplete = enabled;\n return this;\n }\n public addChoices(...choices: { name: string; value: number }[]): this {\n const current = (this.data.choices as unknown[] | undefined) ?? [];\n if (!choices.length)\n throw new TypeError(\"At least one choice is required.\");\n if (this.data.autocomplete === true)\n throw new RangeError(\"Autocomplete options cannot define choices.\");\n if (current.length + choices.length > 25)\n throw new RangeError(\"An option cannot contain more than 25 choices.\");\n this.data.choices = [...current, ...choices];\n return this;\n }\n}\n/** Builds a number command option. */\nexport class NumberOptionBuilder extends CommandOptionBuilder {\n public constructor() {\n super(ApplicationCommandOptionType.Number);\n }\n public setMinValue(value: number): this {\n validateNumberRange(\n value,\n -9_007_199_254_740_991,\n 9_007_199_254_740_991,\n \"min_value\",\n false,\n );\n this.data.min_value = value;\n return this;\n }\n public setMaxValue(value: number): this {\n validateNumberRange(\n value,\n -9_007_199_254_740_991,\n 9_007_199_254_740_991,\n \"max_value\",\n false,\n );\n if (\n (this.data.min_value as number | undefined) !== undefined &&\n (this.data.min_value as number) > value\n )\n throw new RangeError(\"min_value cannot exceed max_value.\");\n this.data.max_value = value;\n return this;\n }\n public setAutocomplete(enabled = true): this {\n if (enabled && Array.isArray(this.data.choices) && this.data.choices.length)\n throw new RangeError(\"Autocomplete options cannot define choices.\");\n this.data.autocomplete = enabled;\n return this;\n }\n public addChoices(...choices: { name: string; value: number }[]): this {\n const current = (this.data.choices as unknown[] | undefined) ?? [];\n if (!choices.length)\n throw new TypeError(\"At least one choice is required.\");\n if (this.data.autocomplete === true)\n throw new RangeError(\"Autocomplete options cannot define choices.\");\n if (current.length + choices.length > 25)\n throw new RangeError(\"An option cannot contain more than 25 choices.\");\n this.data.choices = [...current, ...choices];\n return this;\n }\n}\n/** Builds a boolean command option. */ export class BooleanOptionBuilder extends CommandOptionBuilder {\n /** Creates a boolean option. */ public constructor() {\n super(ApplicationCommandOptionType.Boolean);\n }\n}\n/** Builds a user command option. */ export class UserOptionBuilder extends CommandOptionBuilder {\n /** Creates a user option. */ public constructor() {\n super(ApplicationCommandOptionType.User);\n }\n}\n/** Builds a role command option. */ export class RoleOptionBuilder extends CommandOptionBuilder {\n /** Creates a role option. */ public constructor() {\n super(ApplicationCommandOptionType.Role);\n }\n}\n/** Builds a mentionable command option. */ export class MentionableOptionBuilder extends CommandOptionBuilder {\n /** Creates a mentionable option. */ public constructor() {\n super(ApplicationCommandOptionType.Mentionable);\n }\n}\n/** Builds an attachment command option. */ export class AttachmentOptionBuilder extends CommandOptionBuilder {\n /** Creates an attachment option. */ public constructor() {\n super(ApplicationCommandOptionType.Attachment);\n }\n}\n/** Builds a channel command option. */ export class ChannelOptionBuilder extends CommandOptionBuilder {\n /** Creates a channel option. */ public constructor() {\n super(ApplicationCommandOptionType.Channel);\n }\n /** Restricts accepted channel types. */ public addChannelTypes(\n ...types: number[]\n ): this {\n if (types.some((type) => !Number.isInteger(type) || type < 0))\n throw new RangeError(\"Channel types must be non-negative integers.\");\n this.data.channel_types = [...new Set(types)];\n return this;\n }\n}\n/** Builds a nested subcommand. */ export class SubcommandBuilder extends CommandOptionBuilder {\n /** Creates a subcommand. */ public constructor() {\n super(ApplicationCommandOptionType.Subcommand);\n }\n /** Adds a string option to this subcommand. */ public addStringOption(\n configure: (option: StringOptionBuilder) => StringOptionBuilder,\n ): this {\n return this.addChildOption(configure(new StringOptionBuilder()));\n }\n /** Adds an integer option to this subcommand. */ public addIntegerOption(\n configure: (option: IntegerOptionBuilder) => IntegerOptionBuilder,\n ): this {\n return this.addChildOption(configure(new IntegerOptionBuilder()));\n }\n /** Adds a number option to this subcommand. */ public addNumberOption(\n configure: (option: NumberOptionBuilder) => NumberOptionBuilder,\n ): this {\n return this.addChildOption(configure(new NumberOptionBuilder()));\n }\n /** Adds a boolean option to this subcommand. */ public addBooleanOption(\n configure: (option: BooleanOptionBuilder) => BooleanOptionBuilder,\n ): this {\n return this.addChildOption(configure(new BooleanOptionBuilder()));\n }\n /** Adds a user option to this subcommand. */ public addUserOption(\n configure: (option: UserOptionBuilder) => UserOptionBuilder,\n ): this {\n return this.addChildOption(configure(new UserOptionBuilder()));\n }\n /** Adds a channel option to this subcommand. */ public addChannelOption(\n configure: (option: ChannelOptionBuilder) => ChannelOptionBuilder,\n ): this {\n return this.addChildOption(configure(new ChannelOptionBuilder()));\n }\n /** Adds a role option to this subcommand. */ public addRoleOption(\n configure: (option: RoleOptionBuilder) => RoleOptionBuilder,\n ): this {\n return this.addChildOption(configure(new RoleOptionBuilder()));\n }\n /** Adds a mentionable option to this subcommand. */ public addMentionableOption(\n configure: (option: MentionableOptionBuilder) => MentionableOptionBuilder,\n ): this {\n return this.addChildOption(configure(new MentionableOptionBuilder()));\n }\n /** Adds an attachment option to this subcommand. */ public addAttachmentOption(\n configure: (option: AttachmentOptionBuilder) => AttachmentOptionBuilder,\n ): this {\n return this.addChildOption(configure(new AttachmentOptionBuilder()));\n }\n protected addChildOption(option: CommandOptionBuilder): this {\n const options = (this.data.options as unknown[] | undefined) ?? [];\n if (options.length >= 25)\n throw new RangeError(\"A subcommand cannot contain more than 25 options.\");\n const payload = option.toJSON();\n if (\n options.some(\n (existing) =>\n (existing as Record<string, unknown>).name === payload.name,\n )\n )\n throw new RangeError(`Duplicate option name: ${String(payload.name)}.`);\n if (\n payload.required === true &&\n options.some(\n (existing) => (existing as Record<string, unknown>).required !== true,\n )\n )\n throw new RangeError(\n \"Required subcommand options must be placed before optional options.\",\n );\n if (\n options.some(\n (existing) =>\n (existing as Record<string, unknown>).type ===\n ApplicationCommandOptionType.Subcommand,\n )\n )\n throw new RangeError(\"Subcommands cannot contain nested subcommands.\");\n options.push(payload);\n this.data.options = options;\n return this;\n }\n}\n/** Builds a nested subcommand group. */ export class SubcommandGroupBuilder extends CommandOptionBuilder {\n /** Creates a subcommand group. */ public constructor() {\n super(ApplicationCommandOptionType.SubcommandGroup);\n }\n /** Adds a subcommand to this group. */ public addSubcommand(\n configure: (option: SubcommandBuilder) => SubcommandBuilder,\n ): this {\n const options = (this.data.options as unknown[] | undefined) ?? [];\n if (options.length >= 25)\n throw new RangeError(\n \"A subcommand group cannot contain more than 25 subcommands.\",\n );\n const payload = configure(new SubcommandBuilder()).toJSON();\n if (\n options.some(\n (existing) =>\n (existing as Record<string, unknown>).name === payload.name,\n )\n )\n throw new RangeError(\n `Duplicate subcommand name: ${String(payload.name)}.`,\n );\n if (payload.type !== ApplicationCommandOptionType.Subcommand)\n throw new TypeError(\"Subcommand group children must be subcommands.\");\n options.push(payload);\n this.data.options = options;\n return this;\n }\n}\nfunction validateName(value: string, field: string): void {\n if (!/^[\\p{L}\\p{N}_-]{1,32}$/u.test(value) || value !== value.toLowerCase())\n throw new RangeError(\n `${field} must contain 1-32 lowercase letters, numbers, underscores, or hyphens.`,\n );\n}\nfunction validateText(value: string, field: string, max: number): void {\n if (typeof value !== \"string\" || !value.trim() || value.length > max)\n throw new RangeError(`${field} must contain 1-${max} characters.`);\n}\nfunction validateIntegerRange(\n value: number,\n minimum: number,\n maximum: number,\n field: string,\n): void {\n if (!Number.isInteger(value) || value < minimum || value > maximum)\n throw new RangeError(\n `${field} must be an integer between ${minimum} and ${maximum}.`,\n );\n}\nfunction validateNumberRange(\n value: number,\n minimum: number,\n maximum: number,\n field: string,\n integerOnly = true,\n): void {\n if (\n !Number.isFinite(value) ||\n (integerOnly && !Number.isInteger(value)) ||\n value < minimum ||\n value > maximum\n )\n throw new RangeError(\n `${field} must be ${integerOnly ? \"an integer\" : \"a number\"} between ${minimum} and ${maximum}.`,\n );\n}\n",
|
|
23
|
-
"import { EventEmitter } from \"node:events\";\n\nexport interface CollectorOptions<T> {\n /** Filter predicate to accept or reject items. */\n filter?: (item: T) => boolean | Promise<boolean>;\n /** Lifetime of the collector in milliseconds. */\n time?: number;\n /** Maximum number of elements to collect. */\n max?: number;\n /** Maximum number of processed elements. */\n maxProcessed?: number;\n}\n\n/** General-purpose event collector for interactions and messages. */\nexport class Collector<K, V> extends EventEmitter {\n public readonly collected = new Map<K, V>();\n public readonly options: CollectorOptions<V>;\n public ended = false;\n public endReason?: string;\n public totalProcessed = 0;\n readonly #timeoutTimer?: ReturnType<typeof setTimeout>;\n\n public constructor(options: CollectorOptions<V> = {}) {\n super();\n this.options = options;\n\n if (options.time && options.time > 0) {\n this.#timeoutTimer = setTimeout(() => {\n this.stop(\"time\");\n }, options.time);\n }\n }\n\n /** Handles a candidate item for collection. */\n public async handle(key: K, item: V): Promise<boolean> {\n if (this.ended) return false;\n this.totalProcessed++;\n\n if (this.options.filter) {\n const passed = await this.options.filter(item);\n if (!passed) return false;\n }\n\n this.collected.set(key, item);\n this.emit(\"collect\", item);\n\n if (this.options.max && this.collected.size >= this.options.max) {\n this.stop(\"limit\");\n return true;\n }\n\n if (\n this.options.maxProcessed &&\n this.totalProcessed >= this.options.maxProcessed\n ) {\n this.stop(\"processedLimit\");\n return true;\n }\n\n return true;\n }\n\n /** Stops the collector and emits the \"end\" event. */\n public stop(reason = \"user\"): void {\n if (this.ended) return;\n this.ended = true;\n this.endReason = reason;\n if (this.#timeoutTimer) clearTimeout(this.#timeoutTimer);\n this.emit(\"end\", this.collected, reason);\n this.removeAllListeners();\n }\n\n /** Returns a Promise that resolves with the next collected item or rejects on end/timeout. */\n public next(): Promise<V> {\n return new Promise<V>((resolve, reject) => {\n if (this.ended) {\n return reject(\n new Error(`Collector already ended: ${this.endReason ?? \"unknown\"}`),\n );\n }\n\n this.once(\"collect\", (item: V) => {\n resolve(item);\n });\n\n this.once(\"end\", (_collected, reason) => {\n reject(\n new Error(`Collector ended before item was collected: ${reason}`),\n );\n });\n });\n }\n}\n",
|
|
24
|
-
"export {\r\n Permission,\r\n Permissions,\r\n PermissionFlagsBits,\r\n PermissionSet,\r\n PermissionsBitField,\r\n PermissionOverwriteType,\r\n type PermissionName,\r\n} from \"./permissions.js\";\r\nimport { Collection } from \"@lunibee/collection\";\r\nimport {\r\n ApplicationCommandManager,\r\n ChannelManager,\r\n GuildManager,\r\n UserManager,\r\n} from \"@lunibee/managers\";\r\nimport { REST, Routes } from \"@lunibee/rest\";\r\nimport {\r\n User,\r\n Guild,\r\n Channel,\r\n Message,\r\n Interaction,\r\n createInteraction,\r\n type InteractionClient,\r\n type ResourceContext,\r\n} from \"@lunibee/structures\";\r\nimport { Gateway } from \"@lunibee/ws\";\r\nimport type {\r\n APIChannel,\r\n APIGuild,\r\n APIGuildMember,\r\n APIGuildRoleEvent,\r\n APIGuildRoleDeleteEvent,\r\n APIGuildBanEvent,\r\n APIGuildEmojisUpdateEvent,\r\n APIMessageDeleteBulkEvent,\r\n APIMessageDeleteEvent,\r\n APIMessageReactionEvent,\r\n APIReadyEvent,\r\n APIRole,\r\n APIThreadEvent,\r\n ClientOptions,\r\n ClientUser,\r\n} from \"@lunibee/types\";\r\n\r\n/** Events emitted by the Lunibee client. */\r\nexport interface ClientEvents {\r\n /** Client is ready. */ ready: [ClientUser];\r\n /** Raw gateway dispatch envelope. */ raw: [{ event: string; data: unknown }];\r\n /** Normalized client error. */ error: [Error];\r\n /** Gateway opened. */ open: [];\r\n /** Gateway closed. */ close: [{ code: number; action: string }];\r\n /** Message created. */ messageCreate: [Message];\r\n /** Message updated. */ messageUpdate: [Message];\r\n /** Message deleted. */ messageDelete: [APIMessageDeleteEvent];\r\n /** Messages deleted in bulk. */ messageDeleteBulk: [\r\n APIMessageDeleteBulkEvent,\r\n ];\r\n /** Guild became available. */ guildCreate: [APIGuild];\r\n /** Guild updated. */ guildUpdate: [APIGuild];\r\n /** Guild became unavailable or was removed. */ guildDelete: [\r\n { id: string; unavailable?: boolean },\r\n ];\r\n /** Channel created. */ channelCreate: [Channel];\r\n /** Channel updated. */ channelUpdate: [Channel];\r\n /** Channel deleted. */ channelDelete: [APIChannel];\r\n /** Thread created. */ threadCreate: [Channel];\r\n /** Thread updated. */ threadUpdate: [Channel];\r\n /** Thread deleted. */ threadDelete: [APIThreadEvent];\r\n /** Guild member added. */ guildMemberAdd: [APIGuildMember];\r\n /** Guild member updated. */ guildMemberUpdate: [APIGuildMember];\r\n /** Guild member removed. */ guildMemberRemove: [APIGuildMember];\r\n /** Reaction added. */ messageReactionAdd: [APIMessageReactionEvent];\r\n /** Reaction removed. */ messageReactionRemove: [APIMessageReactionEvent];\r\n /** All reactions removed. */ messageReactionRemoveAll: [\r\n APIMessageDeleteEvent,\r\n ];\r\n /** Interaction created. */ interactionCreate: [Interaction];\r\n /** Guild role created. */ guildRoleCreate: [APIGuildRoleEvent];\r\n /** Guild role updated. */ guildRoleUpdate: [APIGuildRoleEvent];\r\n /** Guild role deleted. */ guildRoleDelete: [APIGuildRoleDeleteEvent];\r\n /** Guild ban added. */ guildBanAdd: [APIGuildBanEvent];\r\n /** Guild ban removed. */ guildBanRemove: [APIGuildBanEvent];\r\n /** Guild emojis updated. */ guildEmojisUpdate: [APIGuildEmojisUpdateEvent];\r\n}\r\n/** Lifecycle state of a client. */\r\nexport type ClientState = \"idle\" | \"connecting\" | \"ready\" | \"destroyed\";\r\ntype Listener<T extends unknown[]> = (...args: T) => unknown;\r\n/** Minimal typed event emitter used by the client. */\r\nclass EventEmitter<Events extends { [K in keyof Events]: unknown[] }> {\r\n readonly #listeners = new Map<keyof Events, Set<Listener<any>>>();\r\n /** Registers a listener. @param event Event name. @param listener Listener callback. @returns This emitter. */ public on<\r\n K extends keyof Events,\r\n >(event: K, listener: Listener<Events[K]>): this {\r\n if (typeof listener !== \"function\")\r\n throw new TypeError(\"Event listener must be a function.\");\r\n let listeners = this.#listeners.get(event);\r\n if (!listeners) this.#listeners.set(event, (listeners = new Set()));\r\n listeners.add(listener);\r\n return this;\r\n }\r\n /** Registers a one-shot listener. @param event Event name. @param listener Listener callback. @returns This emitter. */ public once<\r\n K extends keyof Events,\r\n >(event: K, listener: Listener<Events[K]>): this {\r\n const wrapped: Listener<Events[K]> = (...args) => {\r\n this.off(event, wrapped);\r\n return listener(...args);\r\n };\r\n return this.on(event, wrapped);\r\n }\r\n /** Removes a listener. @param event Event name. @param listener Listener callback. @returns This emitter. */ public off<\r\n K extends keyof Events,\r\n >(event: K, listener: Listener<Events[K]>): this {\r\n this.#listeners.get(event)?.delete(listener);\r\n return this;\r\n }\r\n /** Removes listeners. @param event Optional event name. @returns This emitter. */ public removeAllListeners<\r\n K extends keyof Events,\r\n >(event?: K): this {\r\n if (event === undefined) this.#listeners.clear();\r\n else this.#listeners.delete(event);\r\n return this;\r\n }\r\n /** Emits an event. @param event Event name. @param args Event arguments. @returns Whether listeners were invoked. */ protected emit<\r\n K extends keyof Events,\r\n >(event: K, ...args: Events[K]): boolean {\r\n const listeners = this.#listeners.get(event);\r\n if (!listeners?.size) return false;\r\n for (const listener of [...listeners]) {\r\n try {\r\n const result = listener(...args);\r\n if (\r\n result &&\r\n typeof (result as PromiseLike<unknown>).then === \"function\"\r\n )\r\n void Promise.resolve(result).catch((error) =>\r\n this.#handleError(event, error),\r\n );\r\n } catch (error) {\r\n this.#handleError(event, error);\r\n }\r\n }\r\n return true;\r\n }\r\n /** Forwards listener failures to error handlers. @param event Event whose listener failed. @param error Failure. @returns Nothing. */ #handleError(\r\n event: keyof Events,\r\n error: unknown,\r\n ): void {\r\n if (event === \"error\") return;\r\n const normalized =\r\n error instanceof Error\r\n ? error\r\n : new Error(String(error), { cause: error });\r\n for (const listener of [\r\n ...(this.#listeners.get(\"error\" as keyof Events) ?? []),\r\n ]) {\r\n try {\r\n void listener(normalized);\r\n } catch {}\r\n }\r\n }\r\n}\r\n/** Main Lunibee Discord client. */\r\nexport class Client\r\n extends EventEmitter<ClientEvents>\r\n implements InteractionClient\r\n{\r\n /** REST transport used by all managers. */ public readonly rest: REST;\r\n /** User resource manager. */ public readonly users: UserManager;\r\n /** Guild resource manager. */ public readonly guilds: GuildManager;\r\n /** Channel and message resource manager. */ public readonly channels: ChannelManager;\r\n /** Application command manager (available after login). */ public readonly application: {\r\n /** Application command registration API. */ commands: ApplicationCommandManager;\r\n };\r\n /** Underlying WebSocket Gateway connection. */ public get ws(): Gateway {\r\n return this.#gateway;\r\n }\r\n /** Underlying WebSocket Gateway connection. */ public get gateway(): Gateway {\r\n return this.#gateway;\r\n }\r\n /** Current authenticated bot user. */ public user?: ClientUser;\r\n /** Time at which the gateway became ready. */ public readyAt?: Date;\r\n /** Current client lifecycle state. */ public state: ClientState = \"idle\";\r\n /** Time in milliseconds since the client became ready, or null if not ready. */\r\n public get uptime(): number | null {\r\n return this.readyAt ? Date.now() - this.readyAt.getTime() : null;\r\n }\r\n readonly #gateway: Gateway;\r\n readonly #resourceContext: ResourceContext;\r\n /** Creates a client. @param options Client configuration. @throws {TypeError} If no token is supplied. */ public constructor(\r\n public readonly options: ClientOptions,\r\n ) {\r\n super();\r\n if (!options.token?.trim())\r\n throw new TypeError(\"Client token is required.\");\r\n this.rest = new REST({ token: options.token, ...options.rest });\r\n this.users = new UserManager(this.rest);\r\n this.guilds = new GuildManager(this.rest);\r\n this.channels = new ChannelManager(this.rest);\r\n // application.commands is lazily re-pointed to the real app ID after READY;\r\n // a placeholder is created now so the property is always accessible.\r\n const placeholderAppCommands = new ApplicationCommandManager(\r\n this.rest,\r\n \"0\",\r\n );\r\n this.application = { commands: placeholderAppCommands };\r\n this.#resourceContext = {\r\n sendMessage: (channelId, options) =>\r\n this.channels.send(channelId, options),\r\n editMessage: (channelId, messageId, options) =>\r\n this.channels.editMessage(channelId, messageId, options),\r\n deleteMessage: (channelId, messageId) =>\r\n this.channels.deleteMessage(channelId, messageId),\r\n crosspostMessage: (channelId, messageId) =>\r\n this.channels.crosspostMessage(channelId, messageId),\r\n };\r\n this.#gateway = new Gateway({\r\n token: options.token,\r\n intents: options.intents,\r\n ...options.gateway,\r\n });\r\n this.#gateway.on(\"READY\", (data) => {\r\n const ready = data as APIReadyEvent;\r\n this.user = ready.user;\r\n this.users.set(this.user.id, new User(this.user));\r\n this.readyAt = new Date();\r\n this.state = \"ready\";\r\n // Reinitialise application.commands with the real application ID from READY\r\n const appId = ready.application?.id ?? this.user.id;\r\n (this.application as { commands: ApplicationCommandManager }).commands =\r\n new ApplicationCommandManager(this.rest, appId);\r\n this.emit(\"ready\", this.user);\r\n });\r\n this.#gateway.on(\"open\", () => this.emit(\"open\"));\r\n this.#gateway.on(\"close\", (data) => {\r\n if (this.state !== \"destroyed\") this.state = \"idle\";\r\n this.emit(\"close\", data as { code: number; action: string });\r\n });\r\n this.#gateway.on(\"MESSAGE_CREATE\", (data) => {\r\n const message = new Message(\r\n data as import(\"@lunibee/types\").APIMessage,\r\n this.#resourceContext,\r\n );\r\n this.channels.set(message.channelId, message.channel);\r\n this.users.set(message.author.id, message.author);\r\n this.emit(\"messageCreate\", message);\r\n });\r\n this.#gateway.on(\"MESSAGE_UPDATE\", (data) => {\r\n const message = new Message(\r\n data as import(\"@lunibee/types\").APIMessage,\r\n this.#resourceContext,\r\n );\r\n this.channels.set(message.channelId, message.channel);\r\n this.users.set(message.author.id, message.author);\r\n this.emit(\"messageUpdate\", message);\r\n });\r\n this.#gateway.on(\"MESSAGE_DELETE\", (data) =>\r\n this.emit(\"messageDelete\", data as APIMessageDeleteEvent),\r\n );\r\n this.#gateway.on(\"MESSAGE_DELETE_BULK\", (data) =>\r\n this.emit(\"messageDeleteBulk\", data as APIMessageDeleteBulkEvent),\r\n );\r\n this.#gateway.on(\"GUILD_CREATE\", (data) => {\r\n const guild = new Guild(data as APIGuild);\r\n this.guilds.set(guild.id, guild);\r\n const payload = data as APIGuild & {\r\n members?: APIGuildMember[];\r\n channels?: APIChannel[];\r\n threads?: APIChannel[];\r\n };\r\n for (const member of payload.members ?? [])\r\n this.users.set(member.user.id, new User(member.user));\r\n for (const channelData of [\r\n ...(payload.channels ?? []),\r\n ...(payload.threads ?? []),\r\n ]) {\r\n const channel = new Channel(channelData, this.#resourceContext);\r\n this.channels.set(channel.id, channel);\r\n }\r\n this.emit(\"guildCreate\", data as APIGuild);\r\n });\r\n this.#gateway.on(\"GUILD_UPDATE\", (data) => {\r\n const guild = new Guild(data as APIGuild);\r\n this.guilds.update(guild);\r\n this.emit(\"guildUpdate\", data as APIGuild);\r\n });\r\n this.#gateway.on(\"GUILD_DELETE\", (data) => {\r\n const payload = data as { id: string; unavailable?: boolean };\r\n if (!payload.unavailable) this.guilds.delete(payload.id);\r\n this.emit(\"guildDelete\", payload);\r\n });\r\n this.#gateway.on(\"CHANNEL_CREATE\", (data) => {\r\n const channel = new Channel(data as APIChannel, this.#resourceContext);\r\n this.channels.update(channel);\r\n this.emit(\"channelCreate\", channel);\r\n });\r\n this.#gateway.on(\"CHANNEL_UPDATE\", (data) => {\r\n const channel = new Channel(data as APIChannel, this.#resourceContext);\r\n this.channels.update(channel);\r\n this.emit(\"channelUpdate\", channel);\r\n });\r\n this.#gateway.on(\"CHANNEL_DELETE\", (data) => {\r\n const payload = data as APIChannel;\r\n this.channels.delete(payload.id);\r\n this.emit(\"channelDelete\", payload);\r\n });\r\n this.#gateway.on(\"THREAD_CREATE\", (data) => {\r\n const channel = new Channel(\r\n data as APIThreadEvent,\r\n this.#resourceContext,\r\n );\r\n this.channels.update(channel);\r\n this.emit(\"threadCreate\", channel);\r\n });\r\n this.#gateway.on(\"THREAD_UPDATE\", (data) => {\r\n const channel = new Channel(\r\n data as APIThreadEvent,\r\n this.#resourceContext,\r\n );\r\n this.channels.update(channel);\r\n this.emit(\"threadUpdate\", channel);\r\n });\r\n this.#gateway.on(\"THREAD_DELETE\", (data) => {\r\n const payload = data as APIThreadEvent;\r\n this.channels.delete(payload.id);\r\n this.emit(\"threadDelete\", payload);\r\n });\r\n this.#gateway.on(\"GUILD_MEMBER_ADD\", (data) => {\r\n const member = data as APIGuildMember;\r\n this.users.set(member.user.id, new User(member.user));\r\n this.emit(\"guildMemberAdd\", member);\r\n });\r\n this.#gateway.on(\"GUILD_MEMBER_UPDATE\", (data) => {\r\n const member = data as APIGuildMember;\r\n this.users.set(member.user.id, new User(member.user));\r\n this.emit(\"guildMemberUpdate\", member);\r\n });\r\n this.#gateway.on(\"GUILD_MEMBER_REMOVE\", (data) =>\r\n this.emit(\"guildMemberRemove\", data as APIGuildMember),\r\n );\r\n this.#gateway.on(\"MESSAGE_REACTION_ADD\", (data) =>\r\n this.emit(\"messageReactionAdd\", data as APIMessageReactionEvent),\r\n );\r\n this.#gateway.on(\"MESSAGE_REACTION_REMOVE\", (data) =>\r\n this.emit(\"messageReactionRemove\", data as APIMessageReactionEvent),\r\n );\r\n this.#gateway.on(\"MESSAGE_REACTION_REMOVE_ALL\", (data) =>\r\n this.emit(\"messageReactionRemoveAll\", data as APIMessageDeleteEvent),\r\n );\r\n this.#gateway.on(\"INTERACTION_CREATE\", (data) =>\r\n this.emit(\"interactionCreate\", createInteraction(this, data as any)),\r\n );\r\n // Phase 1.4 — Guild role / ban / emoji events\r\n this.#gateway.on(\"GUILD_ROLE_CREATE\", (data) =>\r\n this.emit(\"guildRoleCreate\", data as APIGuildRoleEvent),\r\n );\r\n this.#gateway.on(\"GUILD_ROLE_UPDATE\", (data) =>\r\n this.emit(\"guildRoleUpdate\", data as APIGuildRoleEvent),\r\n );\r\n this.#gateway.on(\"GUILD_ROLE_DELETE\", (data) =>\r\n this.emit(\"guildRoleDelete\", data as APIGuildRoleDeleteEvent),\r\n );\r\n this.#gateway.on(\"GUILD_BAN_ADD\", (data) =>\r\n this.emit(\"guildBanAdd\", data as APIGuildBanEvent),\r\n );\r\n this.#gateway.on(\"GUILD_BAN_REMOVE\", (data) =>\r\n this.emit(\"guildBanRemove\", data as APIGuildBanEvent),\r\n );\r\n this.#gateway.on(\"GUILD_EMOJIS_UPDATE\", (data) =>\r\n this.emit(\"guildEmojisUpdate\", data as APIGuildEmojisUpdateEvent),\r\n );\r\n for (const event of [\r\n \"READY\",\r\n \"MESSAGE_CREATE\",\r\n \"MESSAGE_UPDATE\",\r\n \"MESSAGE_DELETE\",\r\n \"MESSAGE_DELETE_BULK\",\r\n \"GUILD_CREATE\",\r\n \"GUILD_UPDATE\",\r\n \"GUILD_DELETE\",\r\n \"CHANNEL_CREATE\",\r\n \"CHANNEL_UPDATE\",\r\n \"CHANNEL_DELETE\",\r\n \"THREAD_CREATE\",\r\n \"THREAD_UPDATE\",\r\n \"THREAD_DELETE\",\r\n \"GUILD_MEMBER_ADD\",\r\n \"GUILD_MEMBER_UPDATE\",\r\n \"GUILD_MEMBER_REMOVE\",\r\n \"MESSAGE_REACTION_ADD\",\r\n \"MESSAGE_REACTION_REMOVE\",\r\n \"MESSAGE_REACTION_REMOVE_ALL\",\r\n \"INTERACTION_CREATE\",\r\n \"GUILD_ROLE_CREATE\",\r\n \"GUILD_ROLE_UPDATE\",\r\n \"GUILD_ROLE_DELETE\",\r\n \"GUILD_BAN_ADD\",\r\n \"GUILD_BAN_REMOVE\",\r\n \"GUILD_EMOJIS_UPDATE\",\r\n ])\r\n this.#gateway.on(event, (data) => this.emit(\"raw\", { event, data }));\r\n this.#gateway.on(\"error\", (data) => this.emit(\"error\", data as Error));\r\n }\r\n /** Indicates whether the client has completed gateway readiness. @returns True when ready. */ public isReady(): this is Client & {\r\n user: ClientUser;\r\n readyAt: Date;\r\n } {\r\n return (\r\n this.state === \"ready\" &&\r\n this.user !== undefined &&\r\n this.readyAt !== undefined\r\n );\r\n }\r\n /** Connects the REST and gateway clients. @returns A promise fulfilled after the gateway socket opens. @throws {Error} If the client is destroyed or connection fails. */ public async login(): Promise<void> {\r\n if (this.state === \"destroyed\")\r\n throw new Error(\"Cannot login a destroyed client.\");\r\n if (this.state === \"connecting\" || this.state === \"ready\") return;\r\n this.state = \"connecting\";\r\n try {\r\n this.user = await this.rest.get<ClientUser>(Routes.user());\r\n this.users.set(this.user.id, new User(this.user));\r\n await this.#gateway.connect();\r\n } catch (error) {\r\n this.state = \"idle\";\r\n throw error;\r\n }\r\n }\r\n /** Closes the gateway and destroys cached resources. @returns Nothing. */ public destroy(): void {\r\n if (this.state === \"destroyed\") return;\r\n this.#gateway.close();\r\n this.users.clear();\r\n this.guilds.clear();\r\n this.channels.clear();\r\n this.state = \"destroyed\";\r\n this.readyAt = undefined;\r\n this.user = undefined;\r\n }\r\n /** Posts an interaction callback through REST. @param id Interaction identifier. @param token Interaction token. @param response Interaction response. @returns REST response. */ public postInteractionResponse(\r\n id: string,\r\n token: string,\r\n response: import(\"@lunibee/structures\").InteractionResponse,\r\n ): Promise<unknown> {\r\n return this.rest.post(\r\n Routes.interactionCallback(id, token),\r\n response.toJSON(),\r\n );\r\n }\r\n /** Edits the original interaction response. @param token Interaction token. @param data Reply payload. @returns REST response. */ public editInteractionReply(\r\n token: string,\r\n data: import(\"@lunibee/structures\").InteractionReplyOptions,\r\n ): Promise<unknown> {\r\n if (!this.user?.id)\r\n throw new Error(\"Client user is unavailable; login is required.\");\r\n return this.rest.patch(\r\n Routes.interactionOriginalResponse(this.user.id, token),\r\n data,\r\n );\r\n }\r\n /** Deletes the original interaction response. @param token Interaction token. @returns Nothing. */ public async deleteInteractionReply(\r\n token: string,\r\n ): Promise<void> {\r\n if (!this.user?.id)\r\n throw new Error(\"Client user is unavailable; login is required.\");\r\n await this.rest.delete(\r\n Routes.interactionOriginalResponse(this.user.id, token),\r\n );\r\n }\r\n /** Sets the client gateway presence. @param presence Presence options. @returns Whether the presence update was sent. */\r\n public setPresence(\r\n presence: import(\"@lunibee/types\").GatewayPresence,\r\n ): boolean {\r\n return this.#gateway.setPresence(presence);\r\n }\r\n /** Sends a follow-up interaction webhook message. @param token Interaction token. @param data Follow-up payload. @returns REST response. */ public followUpInteraction(\r\n token: string,\r\n data: import(\"@lunibee/structures\").InteractionReplyOptions,\r\n ): Promise<unknown> {\r\n if (!this.user?.id)\r\n throw new Error(\"Client user is unavailable; login is required.\");\r\n return this.rest.post(Routes.webhook(this.user.id, token), data);\r\n }\r\n}\r\n\r\nexport { Collection } from \"@lunibee/collection\";\r\nexport { REST, RESTError, Routes } from \"@lunibee/rest\";\r\nexport { Gateway, GatewayError, GatewayOpcodes } from \"@lunibee/ws\";\r\nexport {\r\n User,\r\n Guild,\r\n Channel,\r\n Message,\r\n type ResourceContext,\r\n} from \"@lunibee/structures\";\r\nexport {\r\n EmbedBuilder,\r\n ButtonBuilder,\r\n ActionRowBuilder,\r\n StringSelectBuilder,\r\n SlashCommandBuilder,\r\n StringOptionBuilder,\r\n} from \"@lunibee/builders\";\r\nexport * from \"@lunibee/types\";\r\nexport {\r\n Manager,\r\n ResourceManager,\r\n UserManager,\r\n GuildManager,\r\n ChannelManager,\r\n MessageCreateOptions,\r\n MessageEditOptions,\r\n MessageFetchOptions,\r\n MessageThreadOptions,\r\n ReactionFetchOptions,\r\n} from \"@lunibee/managers\";\r\n\r\nexport { Collector, type CollectorOptions } from \"./collector.js\";\r\nexport { ApplicationCommandManager } from \"@lunibee/managers\";\r\nexport type {\r\n APIApplicationCommand,\r\n ApplicationCommandData,\r\n APIRole,\r\n APIGuildRoleEvent,\r\n APIGuildRoleDeleteEvent,\r\n APIGuildBanEvent,\r\n APIEmoji,\r\n APIGuildEmojisUpdateEvent,\r\n ApplicationCommandOptionType,\r\n ApplicationCommandType,\r\n} from \"@lunibee/types\";\r\n"
|
|
18
|
+
"import { ResourceManager } from \"./base.js\";\r\nimport { User } from \"@lunibee/structures\";\r\nimport { type REST, Routes } from \"@lunibee/rest\";\r\nimport type { APIChannel } from \"@lunibee/types\";\r\n\r\ntype UserData = ConstructorParameters<typeof User>[0];\r\n\r\nexport interface UserEditOptions {\r\n username?: string;\r\n avatar?: string | null;\r\n}\r\n\r\nexport class UserManager extends ResourceManager<string, User> {\r\n readonly #rest: REST;\r\n public constructor(rest: REST) {\r\n super(\r\n async (id) => new User(await rest.get<UserData>(Routes.userById(id))),\r\n (user) => user.id,\r\n );\r\n this.#rest = rest;\r\n }\r\n\r\n /** Gets the currently logged-in bot user. */\r\n public async fetchMe(): Promise<User> {\r\n const data = await this.#rest.get<UserData>(\"/users/@me\");\r\n return this.upsert(new User(data));\r\n }\r\n\r\n /** Modifies the currently logged-in bot user. */\r\n public async editMe(options: UserEditOptions): Promise<User> {\r\n const data = await this.#rest.patch<UserData>(\"/users/@me\", options);\r\n return this.upsert(new User(data));\r\n }\r\n\r\n /** Leaves a guild. */\r\n public async leaveGuild(guildId: string): Promise<void> {\r\n await this.#rest.delete(`/users/@me/guilds/${guildId}`);\r\n }\r\n\r\n /** Creates a DM channel with a user. */\r\n public async createDM(userId: string): Promise<APIChannel> {\r\n return this.#rest.post<APIChannel>(\"/users/@me/channels\", {\r\n recipient_id: userId,\r\n });\r\n }\r\n}\r\n",
|
|
19
|
+
"import { ResourceManager } from \"./base.js\";\r\nimport { Guild } from \"@lunibee/structures\";\r\nimport { type REST, Routes } from \"@lunibee/rest\";\r\nimport {\r\n type APIChannel,\r\n type APIGuildPreview,\r\n type APIInvite,\r\n type APIWebhook,\r\n} from \"@lunibee/types\";\r\n\r\ntype GuildData = ConstructorParameters<typeof Guild>[0];\r\n\r\nexport interface GuildCreateOptions extends Record<string, unknown> {\r\n name: string;\r\n}\r\nexport interface GuildEditOptions extends Record<string, unknown> {}\r\n\r\nexport class GuildManager extends ResourceManager<string, Guild> {\r\n readonly #rest: REST;\r\n public constructor(rest: REST) {\r\n super(\r\n async (id) => new Guild(await rest.get<GuildData>(Routes.guild(id))),\r\n (guild) => guild.id,\r\n );\r\n this.#rest = rest;\r\n }\r\n\r\n /** Creates a new guild. (Bot must be in fewer than 10 guilds). */\r\n public async create(options: GuildCreateOptions): Promise<Guild> {\r\n const data = await this.#rest.post<GuildData>(\"/guilds\", options);\r\n return this.upsert(new Guild(data));\r\n }\r\n\r\n /** Modifies a guild's settings. */\r\n public async edit(id: string, options: GuildEditOptions): Promise<Guild> {\r\n const data = await this.#rest.patch<GuildData>(Routes.guild(id), options);\r\n return this.upsert(new Guild(data));\r\n }\r\n\r\n /** Deletes a guild permanently. User must be the owner. */\r\n public async deleteGuild(id: string): Promise<void> {\r\n await this.#rest.delete(Routes.guild(id));\r\n }\r\n\r\n /** Fetches a guild's preview (even if the bot is not in the guild). */\r\n public async fetchPreview(id: string): Promise<APIGuildPreview> {\r\n return this.#rest.get<APIGuildPreview>(Routes.guildPreview(id));\r\n }\r\n\r\n /** Fetches all active threads in the guild. */\r\n public async fetchActiveThreads(\r\n id: string,\r\n ): Promise<{ threads: APIChannel[]; members: unknown[] }> {\r\n return this.#rest.get<{ threads: APIChannel[]; members: unknown[] }>(\r\n Routes.guildActiveThreads(id),\r\n );\r\n }\r\n\r\n /** Fetches all webhooks in the guild. */\r\n public async fetchWebhooks(id: string): Promise<APIWebhook[]> {\r\n return this.#rest.get<APIWebhook[]>(Routes.guildWebhooks(id));\r\n }\r\n\r\n /** Fetches all invites in the guild. */\r\n public async fetchInvites(id: string): Promise<APIInvite[]> {\r\n return this.#rest.get<APIInvite[]>(Routes.guildInvites(id));\r\n }\r\n}\r\n",
|
|
20
|
+
"import { REST, Routes } from \"@lunibee/rest\";\nimport type {\n APIApplicationCommand,\n ApplicationCommandData,\n} from \"@lunibee/types\";\n\n/** Manages global and guild-scoped application commands for a Discord application. */\nexport class ApplicationCommandManager {\n readonly #rest: REST;\n readonly #applicationId: string;\n\n /** Creates an application command manager. @param rest REST transport. @param applicationId Application identifier. */\n public constructor(rest: REST, applicationId: string) {\n this.#rest = rest;\n this.#applicationId = applicationId;\n }\n\n // ──────────────────── Global commands ────────────────────\n\n /** Fetches all global application commands. @returns Array of registered commands. */\n public fetch(): Promise<APIApplicationCommand[]> {\n return this.#rest.get<APIApplicationCommand[]>(\n Routes.applicationCommands(this.#applicationId),\n );\n }\n\n /** Creates a single global application command. @param data Command data. @returns Created command. */\n public create(data: ApplicationCommandData): Promise<APIApplicationCommand> {\n return this.#rest.post<APIApplicationCommand>(\n Routes.applicationCommands(this.#applicationId),\n data,\n );\n }\n\n /** Overwrites all global application commands atomically. @param commands Array of command data. @returns New full command list. */\n public set(\n commands: ApplicationCommandData[],\n ): Promise<APIApplicationCommand[]> {\n return this.#rest.put<APIApplicationCommand[]>(\n Routes.applicationCommands(this.#applicationId),\n commands,\n );\n }\n\n /** Edits a global application command. @param commandId Command identifier. @param data Partial command data. @returns Updated command. */\n public edit(\n commandId: string,\n data: Partial<ApplicationCommandData>,\n ): Promise<APIApplicationCommand> {\n return this.#rest.patch<APIApplicationCommand>(\n Routes.applicationCommand(this.#applicationId, commandId),\n data,\n );\n }\n\n /** Deletes a global application command. @param commandId Command identifier. @returns Nothing. */\n public async delete(commandId: string): Promise<void> {\n await this.#rest.delete(\n Routes.applicationCommand(this.#applicationId, commandId),\n );\n }\n\n // ──────────────────── Guild-scoped commands ────────────────────\n\n /** Fetches all guild-scoped application commands. @param guildId Guild identifier. @returns Array of registered guild commands. */\n public fetchGuild(guildId: string): Promise<APIApplicationCommand[]> {\n return this.#rest.get<APIApplicationCommand[]>(\n Routes.guildApplicationCommands(this.#applicationId, guildId),\n );\n }\n\n /** Creates a single guild-scoped application command. @param guildId Guild identifier. @param data Command data. @returns Created command. */\n public createGuild(\n guildId: string,\n data: ApplicationCommandData,\n ): Promise<APIApplicationCommand> {\n return this.#rest.post<APIApplicationCommand>(\n Routes.guildApplicationCommands(this.#applicationId, guildId),\n data,\n );\n }\n\n /** Overwrites all guild-scoped application commands atomically. @param guildId Guild identifier. @param commands Array of command data. @returns New full command list. */\n public setGuild(\n guildId: string,\n commands: ApplicationCommandData[],\n ): Promise<APIApplicationCommand[]> {\n return this.#rest.put<APIApplicationCommand[]>(\n Routes.guildApplicationCommands(this.#applicationId, guildId),\n commands,\n );\n }\n\n /** Edits a guild-scoped application command. @param guildId Guild identifier. @param commandId Command identifier. @param data Partial command data. @returns Updated command. */\n public editGuild(\n guildId: string,\n commandId: string,\n data: Partial<ApplicationCommandData>,\n ): Promise<APIApplicationCommand> {\n return this.#rest.patch<APIApplicationCommand>(\n Routes.guildApplicationCommand(this.#applicationId, guildId, commandId),\n data,\n );\n }\n\n /** Deletes a guild-scoped application command. @param guildId Guild identifier. @param commandId Command identifier. @returns Nothing. */\n public async deleteGuild(guildId: string, commandId: string): Promise<void> {\n await this.#rest.delete(\n Routes.guildApplicationCommand(this.#applicationId, guildId, commandId),\n );\n }\n}\n",
|
|
21
|
+
"import { Manager, ResourceManager } from \"./base.js\";\r\nexport { Manager, ResourceManager } from \"./base.js\";\r\nimport { Collection } from \"@lunibee/collection\";\r\nimport { REST, Routes } from \"@lunibee/rest\";\r\nimport {\r\n Channel,\r\n Message,\r\n User,\r\n Guild,\r\n type ResourceContext,\r\n} from \"@lunibee/structures\";\r\nimport {\r\n MessageManager,\r\n type MessageCreateOptions as ManagerMessageCreateOptions,\r\n} from \"./message.js\";\r\nimport { ThreadManager } from \"./thread.js\";\r\n\r\nexport { UserManager } from \"./user.js\";\r\nexport { GuildManager } from \"./guild.js\";\r\n\r\nexport type MessageCreateOptions = ManagerMessageCreateOptions;\r\nexport type MessageEditOptions = Record<string, unknown> & { content?: string };\r\nexport interface MessageFetchOptions {\r\n cache?: boolean;\r\n}\r\nexport interface MessageQueryOptions {\r\n before?: string;\r\n after?: string;\r\n around?: string;\r\n limit?: number;\r\n}\r\nexport interface MessageThreadOptions {\r\n name: string;\r\n autoArchiveDuration?: 60 | 1440 | 4320 | 10080;\r\n rateLimitPerUser?: number;\r\n}\r\nexport interface ReactionFetchOptions {\r\n limit?: number;\r\n after?: string;\r\n}\r\n\r\nexport interface ChannelCreateOptions extends Record<string, unknown> {\r\n name: string;\r\n type: number;\r\n guild_id?: string;\r\n parent_id?: string | null;\r\n}\r\nexport type ChannelEditOptions = Record<string, unknown>;\r\n\r\nexport class ChannelManager extends Manager<string, Channel> {\r\n readonly #rest: REST;\r\n readonly #context: ResourceContext;\r\n readonly #messageManagers = new Map<string, MessageManager>();\r\n public constructor(rest: REST) {\r\n super();\r\n this.#rest = rest;\r\n this.#context = {\r\n sendMessage: (channelId, options) => this.send(channelId, options),\r\n editMessage: (channelId, messageId, options) =>\r\n this.editMessage(channelId, messageId, options),\r\n deleteMessage: (channelId, messageId) =>\r\n this.deleteMessage(channelId, messageId),\r\n crosspostMessage: (channelId, messageId) =>\r\n this.crosspostMessage(channelId, messageId),\r\n editChannel: (channelId, options) => this.edit(channelId, options),\r\n deleteChannel: (channelId) => this.deleteChannel(channelId),\r\n addReaction: (channelId, messageId, emoji) =>\r\n this.addReaction(channelId, messageId, emoji),\r\n removeOwnReaction: (channelId, messageId, emoji) =>\r\n this.removeOwnReaction(channelId, messageId, emoji),\r\n removeReaction: (channelId, messageId, emoji, userId) =>\r\n this.removeReaction(channelId, messageId, emoji, userId),\r\n removeAllReactions: (channelId, messageId) =>\r\n this.removeAllReactions(channelId, messageId),\r\n pinMessage: (channelId, messageId) =>\r\n this.pinMessage(channelId, messageId),\r\n unpinMessage: (channelId, messageId) =>\r\n this.unpinMessage(channelId, messageId),\r\n };\r\n }\r\n public messages(channelId: string): MessageManager {\r\n let manager = this.#messageManagers.get(channelId);\r\n if (!manager) {\r\n manager = new MessageManager(this.#rest, this.#context, channelId);\r\n this.#messageManagers.set(channelId, manager);\r\n }\r\n return manager;\r\n }\r\n public threads(channelId: string): ThreadManager {\r\n return new ThreadManager(this.#rest, this.#context, channelId);\r\n }\r\n public async fetch(channelId: string): Promise<Channel> {\r\n return this.upsert(\r\n await this.#rest.get<ConstructorParameters<typeof Channel>[0]>(\r\n Routes.channel(channelId),\r\n ),\r\n );\r\n }\r\n public async resolve(channelId: string): Promise<Channel> {\r\n return this.get(channelId) ?? this.fetch(channelId);\r\n }\r\n public upsert(data: ConstructorParameters<typeof Channel>[0]): Channel {\r\n const existing = this.get(data.id);\r\n const channel = new Channel(data, this.#context);\r\n if (existing) {\r\n Object.assign(existing, channel);\r\n return existing;\r\n }\r\n this.set(channel.id, channel);\r\n return channel;\r\n }\r\n public update(channel: Channel): this {\r\n return this.set(channel.id, channel);\r\n }\r\n public async create(\r\n guildId: string,\r\n options: ChannelCreateOptions,\r\n ): Promise<Channel> {\r\n return this.upsert(\r\n await this.#rest.post<ConstructorParameters<typeof Channel>[0]>(\r\n Routes.guildChannels(guildId),\r\n options,\r\n ),\r\n );\r\n }\r\n public async edit(\r\n channelId: string,\r\n options: ChannelEditOptions,\r\n ): Promise<Channel> {\r\n return this.upsert(\r\n await this.#rest.patch<ConstructorParameters<typeof Channel>[0]>(\r\n Routes.channel(channelId),\r\n options,\r\n ),\r\n );\r\n }\r\n\r\n public async deleteChannel(channelId: string): Promise<void> {\r\n await this.#rest.delete(Routes.channel(channelId));\r\n this.#messageManagers.delete(channelId);\r\n super.delete(channelId);\r\n }\r\n public send(\r\n channelId: string,\r\n options: MessageCreateOptions,\r\n ): Promise<Message> {\r\n return this.messages(channelId).send(options);\r\n }\r\n public sendMessage(\r\n channelId: string,\r\n options: MessageCreateOptions,\r\n ): Promise<Message> {\r\n return this.send(channelId, options);\r\n }\r\n public async fetchMessage(\r\n channelId: string,\r\n messageId: string,\r\n options: MessageFetchOptions = {},\r\n ): Promise<Message> {\r\n void options;\r\n return this.messages(channelId).fetch(messageId);\r\n }\r\n public fetchMessages(\r\n channelId: string,\r\n query: MessageQueryOptions | Iterable<string>,\r\n ): Promise<Message[]> {\r\n if (isMessageQuery(query)) {\r\n const params = new URLSearchParams();\r\n if (query.before) params.set(\"before\", query.before);\r\n if (query.after) params.set(\"after\", query.after);\r\n if (query.around) params.set(\"around\", query.around);\r\n if (query.limit !== undefined) params.set(\"limit\", String(query.limit));\r\n const suffix = params.toString();\r\n return this.#rest\r\n .get<ConstructorParameters<typeof Message>[0][]>(\r\n `${Routes.channelMessages(channelId)}${suffix ? `?${suffix}` : \"\"}`,\r\n )\r\n .then((data) =>\r\n data.map((item) => this.messages(channelId).upsert(item)),\r\n );\r\n }\r\n return this.messages(channelId).fetchMany(query);\r\n }\r\n public upsertMessage(\r\n data: ConstructorParameters<typeof Message>[0],\r\n ): Message {\r\n return this.messages(data.channel_id).upsert(data);\r\n }\r\n public async editMessage(\r\n channelId: string,\r\n messageId: string,\r\n options: MessageEditOptions,\r\n ): Promise<Message> {\r\n return this.messages(channelId).upsert(\r\n await this.#rest.patch<ConstructorParameters<typeof Message>[0]>(\r\n Routes.message(channelId, messageId),\r\n options,\r\n ),\r\n );\r\n }\r\n public async deleteMessage(\r\n channelId: string,\r\n messageId: string,\r\n ): Promise<void> {\r\n await this.#rest.delete(Routes.message(channelId, messageId));\r\n this.messages(channelId).delete(messageId);\r\n }\r\n public deleteCachedMessage(channelId: string, messageId: string): boolean {\r\n return this.messages(channelId).delete(messageId);\r\n }\r\n public async crosspostMessage(\r\n channelId: string,\r\n messageId: string,\r\n ): Promise<Message> {\r\n return this.messages(channelId).upsert(\r\n await this.#rest.post<ConstructorParameters<typeof Message>[0]>(\r\n Routes.crosspostMessage(channelId, messageId),\r\n ),\r\n );\r\n }\r\n public async bulkDeleteMessages(\r\n channelId: string,\r\n messageIds: Iterable<string>,\r\n ): Promise<void> {\r\n const ids = [...messageIds];\r\n await this.#rest.post(Routes.channelBulkDelete(channelId), {\r\n messages: ids,\r\n });\r\n for (const id of ids) this.messages(channelId).delete(id);\r\n }\r\n public async addReaction(\r\n channelId: string,\r\n messageId: string,\r\n emoji: string,\r\n ): Promise<void> {\r\n await this.#rest.put(Routes.messageReactions(channelId, messageId, emoji));\r\n }\r\n public async fetchReactions(\r\n channelId: string,\r\n messageId: string,\r\n emoji: string,\r\n options: ReactionFetchOptions = {},\r\n ): Promise<User[]> {\r\n const params = new URLSearchParams();\r\n if (options.limit !== undefined) params.set(\"limit\", String(options.limit));\r\n if (options.after) params.set(\"after\", options.after);\r\n const suffix = params.toString();\r\n const data = await this.#rest.get<ConstructorParameters<typeof User>[0][]>(\r\n `${Routes.messageReactions(channelId, messageId, emoji)}${suffix ? `?${suffix}` : \"\"}`,\r\n );\r\n return data.map((user) => new User(user));\r\n }\r\n public async removeOwnReaction(\r\n channelId: string,\r\n messageId: string,\r\n emoji: string,\r\n ): Promise<void> {\r\n await this.#rest.delete(\r\n `${Routes.messageReactions(channelId, messageId, emoji)}/@me`,\r\n );\r\n }\r\n public async removeReaction(\r\n channelId: string,\r\n messageId: string,\r\n emoji: string,\r\n userId: string,\r\n ): Promise<void> {\r\n await this.#rest.delete(\r\n `${Routes.messageReactions(channelId, messageId, emoji)}/${userId}`,\r\n );\r\n }\r\n public async removeAllReactions(\r\n channelId: string,\r\n messageId: string,\r\n ): Promise<void> {\r\n await this.#rest.delete(Routes.messageReactionsAll(channelId, messageId));\r\n }\r\n public async fetchPinnedMessages(channelId: string): Promise<Message[]> {\r\n const data = await this.#rest.get<\r\n ConstructorParameters<typeof Message>[0][]\r\n >(Routes.channelPins(channelId));\r\n return data.map((item) => this.messages(channelId).upsert(item));\r\n }\r\n public async pinMessage(channelId: string, messageId: string): Promise<void> {\r\n await this.#rest.put(Routes.channelPin(channelId, messageId));\r\n }\r\n public async unpinMessage(\r\n channelId: string,\r\n messageId: string,\r\n ): Promise<void> {\r\n await this.#rest.delete(Routes.channelPin(channelId, messageId));\r\n }\r\n public createThreadFromMessage(\r\n channelId: string,\r\n messageId: string,\r\n options: MessageThreadOptions,\r\n ): Promise<Channel> {\r\n return this.threads(channelId).createFromMessage(messageId, options);\r\n }\r\n public delete(channelId: string): boolean {\r\n this.#messageManagers.delete(channelId);\r\n return super.delete(channelId);\r\n }\r\n public clear(): void {\r\n this.#messageManagers.clear();\r\n super.clear();\r\n }\r\n}\r\n\r\nfunction isMessageQuery(\r\n value: MessageQueryOptions | Iterable<string>,\r\n): value is MessageQueryOptions {\r\n return (\r\n typeof value === \"object\" && value !== null && !(Symbol.iterator in value)\r\n );\r\n}\r\nexport type CreateMessageOptions = MessageCreateOptions;\r\nexport { MessageManager } from \"./message.js\";\r\nexport { ThreadManager } from \"./thread.js\";\r\nexport {\r\n RoleManager,\r\n type RoleCreateOptions,\r\n type RoleEditOptions,\r\n} from \"./role.js\";\r\nexport {\r\n GuildMemberManager,\r\n type MemberEditOptions,\r\n type BanOptions,\r\n} from \"./member.js\";\r\nexport { ApplicationCommandManager } from \"./application.js\";\r\n",
|
|
22
|
+
"import {\r\n resolveGatewayIntents,\r\n type GatewayPayload,\r\n type GatewayProperties,\r\n type GatewayPresence,\r\n type GatewayIntentResolvable,\r\n} from \"@lunibee/types\";\r\n\r\n/** Discord Gateway opcodes. */\r\nexport const GatewayOpcodes = {\r\n Dispatch: 0,\r\n Heartbeat: 1,\r\n Identify: 2,\r\n PresenceUpdate: 3,\r\n VoiceStateUpdate: 4,\r\n Resume: 6,\r\n Reconnect: 7,\r\n RequestGuildMembers: 8,\r\n InvalidSession: 9,\r\n Hello: 10,\r\n HeartbeatAck: 11,\r\n} as const;\r\n/** Gateway connection lifecycle states. */\r\nexport enum GatewayState {\r\n /** Initial connection state. */ Connect = \"CONNECT\",\r\n /** Gateway HELLO received state. */ Hello = \"HELLO\",\r\n /** IDENTIFY operation in progress. */ Identify = \"IDENTIFY\",\r\n /** RESUME operation in progress. */ Resume = \"RESUME\",\r\n /** Gateway READY state. */ Ready = \"READY\",\r\n /** Gateway dispatch processing state. */ Dispatch = \"DISPATCH\",\r\n /** Heartbeat processing state. */ Heartbeat = \"HEARTBEAT\",\r\n /** Reconnect in progress. */ Reconnect = \"RECONNECT\",\r\n /** Gateway is permanently closed. */ Closed = \"CLOSED\",\r\n}\r\n/** Gateway protocol error. */\r\nexport class GatewayError extends Error {\r\n /** Gateway close/error code. */ public readonly code?: number;\r\n /** Creates a Gateway error. @param message Error message. @param code Optional Gateway code. @param options Optional error metadata. */ public constructor(\r\n message: string,\r\n code?: number,\r\n options?: ErrorOptions,\r\n ) {\r\n super(message, options);\r\n this.name = \"GatewayError\";\r\n this.code = code;\r\n }\r\n}\r\n/** Gateway connection configuration. */\r\nexport interface GatewayOptions {\r\n /** Authentication token. */ token: string;\r\n /** Gateway intent bitfield or resolvable. */ intents: GatewayIntentResolvable;\r\n /** Shard identifier. */ shardId?: number;\r\n /** Total shard count. */ shardCount?: number;\r\n /** Whether automatic reconnect is enabled. */ reconnect?: boolean;\r\n /** Maximum reconnect attempts. */ maxReconnectAttempts?: number;\r\n /** Initial reconnect delay. */ reconnectBaseDelay?: number;\r\n /** Maximum reconnect delay. */ reconnectMaxDelay?: number;\r\n /** Heartbeat acknowledgement timeout. */ heartbeatAckTimeout?: number;\r\n /** Zombie connection timeout. */ zombieTimeout?: number;\r\n /** Identification properties. */ properties?: GatewayProperties;\r\n /** Presence data. */ presence?: GatewayPresence;\r\n}\r\n/** Gateway event listener. */\r\ntype GatewayListener = (data: unknown) => unknown;\r\n/** Manages a Discord Gateway connection. */\r\nexport class Gateway {\r\n /** Current Gateway lifecycle state. */\r\n public state: GatewayState = GatewayState.Connect;\r\n #options: Required<Omit<GatewayOptions, \"properties\" | \"presence\">> & {\r\n properties?: GatewayProperties;\r\n presence?: GatewayPresence;\r\n };\r\n #ws?: WebSocket;\r\n #sequence: number | null = null;\r\n #sessionId?: string;\r\n #resumeURL?: string;\r\n #heartbeatTimer?: ReturnType<typeof setInterval>;\r\n #initialHeartbeat?: ReturnType<typeof setTimeout>;\r\n #heartbeatAckTimer?: ReturnType<typeof setTimeout>;\r\n #heartbeatACK = true;\r\n #heartbeatInterval = 0;\r\n #heartbeatSentAt = 0;\r\n #lastMessageAt = 0;\r\n #zombieTimer?: ReturnType<typeof setInterval>;\r\n #zombieReported = false;\r\n #closed = false;\r\n #attempt = 0;\r\n #reconnectTimer?: ReturnType<typeof setTimeout>;\r\n #connectPromise?: Promise<void>;\r\n #resolveConnect?: () => void;\r\n #rejectConnect?: (error: GatewayError) => void;\r\n readonly #listeners = new Map<string, Set<GatewayListener>>();\r\n readonly #sendTimestamps: number[] = [];\r\n /** Creates a Gateway connection manager. @param options Gateway configuration. @throws {TypeError|RangeError} If configuration is invalid. */\r\n public constructor(options: GatewayOptions) {\r\n if (!options.token?.trim())\r\n throw new TypeError(\"A Gateway token is required.\");\r\n const resolvedIntents = resolveGatewayIntents(options.intents);\r\n if (!Number.isInteger(resolvedIntents) || resolvedIntents < 0)\r\n throw new TypeError(\"Gateway intents must be a non-negative integer.\");\r\n this.#options = {\r\n shardId: 0,\r\n shardCount: 1,\r\n reconnect: true,\r\n maxReconnectAttempts: Infinity,\r\n reconnectBaseDelay: 1000,\r\n reconnectMaxDelay: 30000,\r\n heartbeatAckTimeout: 10000,\r\n zombieTimeout: 30000,\r\n properties: {\r\n os: \"Android\",\r\n browser: \"Discord Android\",\r\n device: \"Discord Android\",\r\n },\r\n presence: { status: \"online\", activities: [], afk: false, since: null },\r\n ...options,\r\n };\r\n if (\r\n this.#options.shardId < 0 ||\r\n this.#options.shardId >= this.#options.shardCount\r\n )\r\n throw new RangeError(\r\n \"Gateway shardId must be within the configured shard count.\",\r\n );\r\n if (this.#options.zombieTimeout <= this.#options.heartbeatAckTimeout)\r\n throw new RangeError(\r\n \"Gateway zombieTimeout must be greater than heartbeatAckTimeout\",\r\n );\r\n }\r\n\r\n /** Opens the Gateway connection. @param url Gateway WebSocket URL. @returns Promise fulfilled when the socket opens. @throws {GatewayError} If permanently closed or unable to connect. */\r\n public connect(\r\n url = \"wss://gateway.discord.gg/?v=10&encoding=json\",\r\n ): Promise<void> {\r\n if (this.state === GatewayState.Closed)\r\n throw new GatewayError(\"Gateway has been permanently closed.\");\r\n if (this.#connectPromise) return this.#connectPromise;\r\n this.#closed = false;\r\n this.#setState(GatewayState.Connect);\r\n this.#connectPromise = new Promise<void>((resolve, reject) => {\r\n this.#resolveConnect = resolve;\r\n this.#rejectConnect = reject;\r\n this.#open(url);\r\n });\r\n return this.#connectPromise;\r\n }\r\n /** Permanently closes the Gateway connection. */\r\n public close(): void {\r\n this.#closed = true;\r\n this.#clearTimers();\r\n this.#settleConnect(\r\n new GatewayError(\"Gateway connection closed before socket open.\"),\r\n );\r\n const ws = this.#ws;\r\n this.#ws = undefined;\r\n try {\r\n ws?.close(1000, \"Client closed connection\");\r\n } catch (error) {\r\n this.#emitError(error);\r\n }\r\n this.#setState(GatewayState.Closed);\r\n }\r\n /** Registers a Gateway event listener. @param event Event name. @param listener Event callback. @returns This Gateway. */\r\n /** Emits an event to all registered listeners. @param event Event name. @param data Event payload. */\r\n public emit(event: string, data?: unknown): void {\r\n this.#emit(event, data);\r\n }\r\n public on(event: string, listener: GatewayListener): this {\r\n if (!event || typeof listener !== \"function\")\r\n throw new TypeError(\"Gateway event and listener are required.\");\r\n let listeners = this.#listeners.get(event);\r\n if (!listeners) this.#listeners.set(event, (listeners = new Set()));\r\n listeners.add(listener);\r\n return this;\r\n }\r\n /** Removes a Gateway event listener. @param event Event name. @param listener Event callback. @returns This Gateway. */\r\n public off(event: string, listener: GatewayListener): this {\r\n this.#listeners.get(event)?.delete(listener);\r\n return this;\r\n }\r\n /** Sends a Gateway payload. @param payload Gateway payload. @returns Whether it was sent. */\r\n public send(payload: GatewayPayload): boolean {\r\n if (!payload || !Number.isInteger(payload.op))\r\n throw new TypeError(\"Gateway payload must contain an integer opcode.\");\r\n if (this.#ws?.readyState !== WebSocket.OPEN) return false;\r\n const now = Date.now();\r\n while (\r\n this.#sendTimestamps.length &&\r\n now - this.#sendTimestamps[0]! >= 60000\r\n )\r\n this.#sendTimestamps.shift();\r\n if (this.#sendTimestamps.length >= 115) {\r\n this.#emitError(new GatewayError(\"Gateway send rate budget exhausted.\"));\r\n return false;\r\n }\r\n try {\r\n this.#ws.send(JSON.stringify(payload));\r\n this.#sendTimestamps.push(now);\r\n return true;\r\n } catch (error) {\r\n this.#emitError(error);\r\n return false;\r\n }\r\n }\r\n /** Sends a presence update. @param data Presence payload. @returns Whether it was sent. */\r\n public setPresence(data: GatewayPresence): boolean {\r\n this.#options.presence = { ...this.#options.presence, ...data };\r\n const payload = {\r\n since: this.#options.presence.since ?? null,\r\n activities: this.#options.presence.activities ?? [],\r\n status: this.#options.presence.status ?? \"online\",\r\n afk: Boolean(this.#options.presence.afk),\r\n };\r\n return this.send({\r\n op: GatewayOpcodes.PresenceUpdate,\r\n d: payload,\r\n s: null,\r\n t: null,\r\n });\r\n }\r\n /** Sends a voice state update. @param data Voice state payload. @returns Whether it was sent. */\r\n public setVoiceState(data: Record<string, unknown>): boolean {\r\n return this.send({\r\n op: GatewayOpcodes.VoiceStateUpdate,\r\n d: data,\r\n s: null,\r\n t: null,\r\n });\r\n }\r\n /** Requests guild members. @param data Guild member request payload. @returns Whether it was sent. */\r\n public requestGuildMembers(data: Record<string, unknown>): boolean {\r\n return this.send({\r\n op: GatewayOpcodes.RequestGuildMembers,\r\n d: data,\r\n s: null,\r\n t: null,\r\n });\r\n }\r\n #open(url: string): void {\r\n if (this.#closed) return;\r\n let ws: WebSocket;\r\n try {\r\n ws = new WebSocket(url);\r\n } catch (error) {\r\n const failure = this.#normalizeError(error);\r\n this.#emitError(failure);\r\n if (this.#options.reconnect) {\r\n this.#setState(GatewayState.Reconnect);\r\n this.#scheduleReconnect();\r\n } else this.#settleConnect(failure);\r\n return;\r\n }\r\n this.#ws = ws;\r\n ws.addEventListener(\"open\", () => {\r\n this.#lastMessageAt = Date.now();\r\n this.#zombieReported = false;\r\n this.#startZombieDetection();\r\n this.#emit(\"open\", undefined);\r\n this.#settleConnect();\r\n });\r\n ws.addEventListener(\"message\", (event) => {\r\n this.#lastMessageAt = Date.now();\r\n this.#zombieReported = false;\r\n this.#message(ws, String(event.data));\r\n });\r\n ws.addEventListener(\"close\", (event) => this.#close(ws, event.code));\r\n ws.addEventListener(\"error\", () =>\r\n this.#emitError(new GatewayError(\"Gateway WebSocket error\")),\r\n );\r\n }\r\n #startZombieDetection(): void {\r\n if (this.#zombieTimer) clearInterval(this.#zombieTimer);\r\n const interval = Math.max(\r\n 1,\r\n Math.min(\r\n 250,\r\n this.#options.heartbeatAckTimeout,\r\n this.#options.zombieTimeout / 2,\r\n ),\r\n );\r\n this.#zombieTimer = setInterval(() => {\r\n if (\r\n this.#closed ||\r\n this.#ws?.readyState !== WebSocket.OPEN ||\r\n this.#lastMessageAt === 0\r\n )\r\n return;\r\n const silentFor = Date.now() - this.#lastMessageAt;\r\n const deadline = Math.max(\r\n this.#options.zombieTimeout,\r\n this.#heartbeatInterval + this.#options.heartbeatAckTimeout,\r\n );\r\n if (silentFor < deadline || this.#zombieReported) return;\r\n this.#zombieReported = true;\r\n const error = new GatewayError(\r\n `Gateway connection appears stale after ${silentFor}ms without traffic.`,\r\n );\r\n this.#emit(\"zombie\", { silentFor, timeout: deadline });\r\n this.#emitError(error);\r\n try {\r\n this.#ws.close(1001, \"Zombie Gateway connection\");\r\n } catch (closeError) {\r\n this.#emitError(closeError);\r\n }\r\n }, interval);\r\n }\r\n #message(ws: WebSocket, raw: string): void {\r\n let payload: GatewayPayload;\r\n try {\r\n payload = JSON.parse(raw) as GatewayPayload;\r\n } catch (error) {\r\n this.#emitError(\r\n new GatewayError(\"Gateway returned invalid JSON\", undefined, {\r\n cause: error,\r\n }),\r\n );\r\n ws.close(1002, \"Invalid JSON\");\r\n return;\r\n }\r\n if (!payload || typeof payload.op !== \"number\") {\r\n this.#emitError(new GatewayError(\"Gateway returned an invalid payload\"));\r\n ws.close(1002, \"Invalid payload\");\r\n return;\r\n }\r\n if (typeof payload.s === \"number\") this.#sequence = payload.s;\r\n switch (payload.op) {\r\n case GatewayOpcodes.Dispatch:\r\n this.#setState(GatewayState.Dispatch);\r\n this.#handleDispatch(payload.t, payload.d);\r\n break;\r\n case GatewayOpcodes.Hello:\r\n this.#handleHello(payload.d);\r\n break;\r\n case GatewayOpcodes.Heartbeat:\r\n this.#setState(GatewayState.Heartbeat);\r\n this.#sendHeartbeat();\r\n break;\r\n case GatewayOpcodes.HeartbeatAck:\r\n this.#heartbeatACK = true;\r\n this.#clearHeartbeatAckTimer();\r\n this.#emit(\"heartbeatAck\", payload.d);\r\n break;\r\n case GatewayOpcodes.Reconnect:\r\n ws.close(1001, \"Server requested reconnect\");\r\n break;\r\n case GatewayOpcodes.InvalidSession:\r\n this.#sessionId = undefined;\r\n this.#sequence = null;\r\n this.#emit(\"invalidSession\", payload.d);\r\n ws.close(1000, \"Invalid session\");\r\n break;\r\n }\r\n }\r\n #handleDispatch(event: string | null, data: unknown): void {\r\n if (event === \"READY\") {\r\n const ready = data as {\r\n session_id?: unknown;\r\n resume_gateway_url?: unknown;\r\n };\r\n if (\r\n typeof ready?.session_id !== \"string\" ||\r\n typeof ready?.resume_gateway_url !== \"string\"\r\n ) {\r\n this.#emitError(\r\n new GatewayError(\r\n \"Gateway READY payload is missing session information\",\r\n ),\r\n );\r\n return;\r\n }\r\n this.#sessionId = ready.session_id;\r\n this.#resumeURL = ready.resume_gateway_url;\r\n this.#attempt = 0;\r\n this.#setState(GatewayState.Ready);\r\n this.#emit(\"ready\", data);\r\n }\r\n this.#emit(\"RAW\", { event: event ?? \"UNKNOWN\", data });\r\n if (this.#closed) return;\r\n this.#emit(event ?? \"dispatch\", data);\r\n }\r\n #handleHello(data: unknown): void {\r\n const interval = (data as { heartbeat_interval?: unknown })\r\n ?.heartbeat_interval;\r\n if (\r\n typeof interval !== \"number\" ||\r\n !Number.isFinite(interval) ||\r\n interval <= 0\r\n ) {\r\n this.#emitError(\r\n new GatewayError(\r\n \"Gateway HELLO payload contains an invalid heartbeat interval\",\r\n ),\r\n );\r\n this.#ws?.close(1002, \"Invalid heartbeat interval\");\r\n return;\r\n }\r\n this.#heartbeatInterval = interval;\r\n this.#setState(\r\n this.#sessionId && this.#sequence !== null && this.#resumeURL\r\n ? GatewayState.Resume\r\n : GatewayState.Hello,\r\n );\r\n this.#startHeartbeat(interval);\r\n this.#identifyOrResume();\r\n }\r\n #identifyOrResume(): void {\r\n if (this.#sessionId && this.#sequence !== null && this.#resumeURL) {\r\n this.#setState(GatewayState.Resume);\r\n this.send({\r\n op: GatewayOpcodes.Resume,\r\n d: {\r\n token: this.#options.token,\r\n session_id: this.#sessionId,\r\n seq: this.#sequence,\r\n },\r\n s: null,\r\n t: null,\r\n });\r\n return;\r\n }\r\n this.#setState(GatewayState.Identify);\r\n const props = this.#options.properties ?? {\r\n os: \"Android\",\r\n browser: \"Discord Android\",\r\n device: \"Discord Android\",\r\n };\r\n const os = props.os ?? \"Android\";\r\n const browser = props.browser ?? \"Discord Android\";\r\n const device = props.device ?? \"Discord Android\";\r\n this.send({\r\n op: GatewayOpcodes.Identify,\r\n d: {\r\n token: this.#options.token,\r\n intents: this.#options.intents,\r\n properties: {\r\n os,\r\n browser,\r\n device,\r\n $os: os,\r\n $browser: browser,\r\n $device: device,\r\n ...props,\r\n },\r\n presence: {\r\n since: this.#options.presence?.since ?? null,\r\n activities: this.#options.presence?.activities ?? [],\r\n status: this.#options.presence?.status ?? \"online\",\r\n afk: Boolean(this.#options.presence?.afk),\r\n },\r\n shard: [this.#options.shardId, this.#options.shardCount],\r\n },\r\n s: null,\r\n t: null,\r\n });\r\n }\r\n #startHeartbeat(interval: number): void {\r\n this.#clearHeartbeatTimers();\r\n this.#heartbeatACK = true;\r\n this.#initialHeartbeat = setTimeout(\r\n () => this.#sendHeartbeat(),\r\n Math.random() * interval,\r\n );\r\n this.#heartbeatTimer = setInterval(() => this.#sendHeartbeat(), interval);\r\n }\r\n #sendHeartbeat(): void {\r\n this.#heartbeatACK = false;\r\n this.#heartbeatSentAt = Date.now();\r\n if (\r\n !this.send({\r\n op: GatewayOpcodes.Heartbeat,\r\n d: this.#sequence,\r\n s: null,\r\n t: null,\r\n })\r\n ) {\r\n this.#emitError(\r\n new GatewayError(\r\n \"Unable to send Gateway heartbeat because the WebSocket is not open.\",\r\n ),\r\n );\r\n return;\r\n }\r\n this.#clearHeartbeatAckTimer();\r\n this.#heartbeatAckTimer = setTimeout(() => {\r\n if (!this.#heartbeatACK) {\r\n const elapsed = Date.now() - this.#heartbeatSentAt;\r\n this.#emitError(\r\n new GatewayError(\r\n `Gateway heartbeat acknowledgement timed out after ${elapsed}ms.`,\r\n ),\r\n );\r\n try {\r\n this.#ws?.close(1001, \"Heartbeat timeout\");\r\n } catch (error) {\r\n this.#emitError(error);\r\n }\r\n }\r\n }, this.#options.heartbeatAckTimeout);\r\n }\r\n #close(ws: WebSocket, code: number): void {\r\n if (this.#ws !== ws) return;\r\n this.#ws = undefined;\r\n this.#clearTimers();\r\n const action = this.#closeAction(code);\r\n this.#emit(\"close\", { code, action });\r\n if (this.#closed || !this.#options.reconnect || action === \"stop\") {\r\n this.#setState(this.#closed ? GatewayState.Closed : GatewayState.Connect);\r\n if (this.#connectPromise)\r\n this.#settleConnect(\r\n new GatewayError(`Gateway closed before READY (code ${code}).`, code),\r\n );\r\n return;\r\n }\r\n if (action === \"identify\") {\r\n this.#sequence = null;\r\n this.#sessionId = undefined;\r\n }\r\n this.#setState(GatewayState.Reconnect);\r\n this.#scheduleReconnect();\r\n }\r\n #closeAction(code: number): \"resume\" | \"identify\" | \"stop\" {\r\n if ([4004, 4010, 4011, 4012, 4013, 4014].includes(code)) return \"stop\";\r\n if ([4007, 4009].includes(code)) return \"identify\";\r\n return this.#sessionId && this.#sequence !== null ? \"resume\" : \"identify\";\r\n }\r\n #scheduleReconnect(): void {\r\n if (this.#closed || !this.#options.reconnect || this.#reconnectTimer)\r\n return;\r\n if (this.#attempt >= this.#options.maxReconnectAttempts) {\r\n this.#settleConnect(\r\n new GatewayError(\"Gateway reconnect attempts exhausted.\"),\r\n );\r\n this.#setState(GatewayState.Connect);\r\n return;\r\n }\r\n const delay = Math.min(\r\n this.#options.reconnectMaxDelay,\r\n this.#options.reconnectBaseDelay * 2 ** this.#attempt++,\r\n );\r\n const jitter = Math.random() * Math.min(250, Math.max(1, delay * 0.25));\r\n this.#reconnectTimer = setTimeout(() => {\r\n this.#reconnectTimer = undefined;\r\n this.#open(\r\n this.#resumeURL ?? \"wss://gateway.discord.gg/?v=10&encoding=json\",\r\n );\r\n }, delay + jitter);\r\n }\r\n #settleConnect(error?: GatewayError): void {\r\n const resolve = this.#resolveConnect;\r\n const reject = this.#rejectConnect;\r\n this.#resolveConnect = undefined;\r\n this.#rejectConnect = undefined;\r\n this.#connectPromise = undefined;\r\n if (error) reject?.(error);\r\n else resolve?.();\r\n }\r\n #clearHeartbeatAckTimer(): void {\r\n if (this.#heartbeatAckTimer) clearTimeout(this.#heartbeatAckTimer);\r\n this.#heartbeatAckTimer = undefined;\r\n }\r\n #clearHeartbeatTimers(): void {\r\n if (this.#heartbeatTimer) clearInterval(this.#heartbeatTimer);\r\n if (this.#initialHeartbeat) clearTimeout(this.#initialHeartbeat);\r\n this.#clearHeartbeatAckTimer();\r\n this.#heartbeatTimer = undefined;\r\n this.#initialHeartbeat = undefined;\r\n }\r\n #clearTimers(): void {\r\n if (this.#reconnectTimer) clearTimeout(this.#reconnectTimer);\r\n if (this.#zombieTimer) clearInterval(this.#zombieTimer);\r\n this.#reconnectTimer = undefined;\r\n this.#zombieTimer = undefined;\r\n this.#clearHeartbeatTimers();\r\n }\r\n #normalizeError(error: unknown): GatewayError {\r\n return error instanceof GatewayError\r\n ? error\r\n : new GatewayError(\"Gateway connection failed.\", undefined, {\r\n cause: error,\r\n });\r\n }\r\n #emitError(error: unknown): void {\r\n this.#emit(\r\n \"error\",\r\n error instanceof Error ? error : new GatewayError(String(error)),\r\n );\r\n }\r\n #emit(event: string, data: unknown): void {\r\n for (const listener of this.#listeners.get(event) ?? []) {\r\n try {\r\n const result = listener(data);\r\n if (\r\n result &&\r\n typeof (result as PromiseLike<unknown>).then === \"function\"\r\n )\r\n void Promise.resolve(result).catch((error) => {\r\n if (event !== \"error\") this.#emitError(error);\r\n });\r\n } catch (error) {\r\n if (event !== \"error\") this.#emitError(error);\r\n }\r\n }\r\n }\r\n /** Changes the Gateway lifecycle state. @param next Next lifecycle state. */\r\n #setState(next: GatewayState): void {\r\n if (this.state === next) return;\r\n const previous = this.state;\r\n this.state = next;\r\n this.#emit(\"stateChange\", { previous, next });\r\n }\r\n}\r\n",
|
|
23
|
+
"export {\r\n Permission,\r\n Permissions,\r\n PermissionFlagsBits,\r\n PermissionSet,\r\n PermissionsBitField,\r\n PermissionOverwriteType,\r\n type PermissionName,\r\n} from \"./permissions.js\";\r\nexport {\r\n ClientEvent,\r\n type ClientEventName,\r\n type ClientListener,\r\n} from \"./events.js\";\r\nexport {\r\n GatewayIntentBits,\r\n IntentBits,\r\n Intents,\r\n resolveGatewayIntents,\r\n type GatewayIntentResolvable,\r\n} from \"@lunibee/types\";\r\n\r\nimport { Collection } from \"@lunibee/collection\";\r\nimport {\r\n ApplicationCommandManager,\r\n ChannelManager,\r\n GuildManager,\r\n UserManager,\r\n} from \"@lunibee/managers\";\r\nimport { REST, Routes } from \"@lunibee/rest\";\r\nimport {\r\n User,\r\n Guild,\r\n Channel,\r\n Message,\r\n Interaction,\r\n createInteraction,\r\n type InteractionClient,\r\n type ResourceContext,\r\n} from \"@lunibee/structures\";\r\nimport { Gateway } from \"@lunibee/ws\";\r\nimport type {\r\n APIChannel,\r\n APIGuild,\r\n APIGuildMember,\r\n APIGuildRoleEvent,\r\n APIGuildRoleDeleteEvent,\r\n APIGuildBanEvent,\r\n APIGuildEmojisUpdateEvent,\r\n APIGuildStickersUpdateEvent,\r\n APIMessageDeleteBulkEvent,\r\n APIMessageDeleteEvent,\r\n APIMessageReactionEvent,\r\n APIMessageReactionRemoveEmojiEvent,\r\n APIReadyEvent,\r\n APIRole,\r\n APIThreadEvent,\r\n APIThreadListSync,\r\n APIThreadMembersUpdate,\r\n APIVoiceState,\r\n APIVoiceServerUpdate,\r\n APIPresenceUpdate,\r\n APITypingStart,\r\n APIInviteCreate,\r\n APIInviteDelete,\r\n APIWebhooksUpdate,\r\n APIAutoModerationRule,\r\n APIAutoModerationActionExecution,\r\n APIGuildScheduledEvent,\r\n APIGuildScheduledEventUserEvent,\r\n APIStageInstance,\r\n APIChannelPinsUpdate,\r\n APIGuildMembersChunk,\r\n APIMessagePollVoteEvent,\r\n APIThreadMember,\r\n ClientOptions,\r\n ClientUser,\r\n} from \"@lunibee/types\";\r\nimport { ClientEvent } from \"./events.js\";\r\n\r\n/** Lifecycle state of a client. */\r\nexport type ClientState = \"idle\" | \"connecting\" | \"ready\" | \"destroyed\";\r\ntype Listener<T extends unknown[]> = (...args: T) => unknown;\r\n\r\n/** Minimal typed event emitter used by the client. */\r\nclass EventEmitter<Events extends { [K in keyof Events]: unknown[] }> {\r\n readonly #listeners = new Map<keyof Events, Set<Listener<any>>>();\r\n public on<K extends keyof Events>(\r\n event: K,\r\n listener: Listener<Events[K]>,\r\n ): this {\r\n if (typeof listener !== \"function\")\r\n throw new TypeError(\"Event listener must be a function.\");\r\n let listeners = this.#listeners.get(event);\r\n if (!listeners) this.#listeners.set(event, (listeners = new Set()));\r\n listeners.add(listener);\r\n return this;\r\n }\r\n public once<K extends keyof Events>(\r\n event: K,\r\n listener: Listener<Events[K]>,\r\n ): this {\r\n const wrapped: Listener<Events[K]> = (...args) => {\r\n this.off(event, wrapped);\r\n return listener(...args);\r\n };\r\n return this.on(event, wrapped);\r\n }\r\n public off<K extends keyof Events>(\r\n event: K,\r\n listener: Listener<Events[K]>,\r\n ): this {\r\n this.#listeners.get(event)?.delete(listener);\r\n return this;\r\n }\r\n public removeAllListeners<K extends keyof Events>(event?: K): this {\r\n if (event === undefined) this.#listeners.clear();\r\n else this.#listeners.delete(event);\r\n return this;\r\n }\r\n protected emit<K extends keyof Events>(\r\n event: K,\r\n ...args: Events[K]\r\n ): boolean {\r\n const listeners = this.#listeners.get(event);\r\n if (!listeners?.size) return false;\r\n for (const listener of [...listeners]) {\r\n try {\r\n const result = listener(...args);\r\n if (\r\n result &&\r\n typeof (result as PromiseLike<unknown>).then === \"function\"\r\n )\r\n void Promise.resolve(result).catch((error) =>\r\n this.#handleError(event, error),\r\n );\r\n } catch (error) {\r\n this.#handleError(event, error);\r\n }\r\n }\r\n return true;\r\n }\r\n #handleError(event: keyof Events, error: unknown): void {\r\n if (event === ClientEvent.Error) return;\r\n const normalized =\r\n error instanceof Error\r\n ? error\r\n : new Error(String(error), { cause: error });\r\n for (const listener of [\r\n ...(this.#listeners.get(ClientEvent.Error as keyof Events) ?? []),\r\n ]) {\r\n try {\r\n void listener(normalized);\r\n } catch {}\r\n }\r\n }\r\n}\r\n\r\n/** Main Lunibee Discord client. */\r\nexport class Client\r\n extends EventEmitter<ClientEvents>\r\n implements InteractionClient\r\n{\r\n public readonly rest: REST;\r\n public readonly users: UserManager;\r\n public readonly guilds: GuildManager;\r\n public readonly channels: ChannelManager;\r\n public readonly application: { commands: ApplicationCommandManager };\r\n public get ws(): Gateway {\r\n return this.#gateway;\r\n }\r\n public get gateway(): Gateway {\r\n return this.#gateway;\r\n }\r\n public user?: ClientUser;\r\n public readyAt?: Date;\r\n public state: ClientState = \"idle\";\r\n public get uptime(): number | null {\r\n return this.readyAt ? Date.now() - this.readyAt.getTime() : null;\r\n }\r\n /** Whether the client is ready and connected. */\r\n public isReady(): boolean {\r\n return this.state === \"ready\";\r\n }\r\n /** Sets the bot's presence / status. @param data Presence payload. @returns Whether the payload was sent. */\r\n public setPresence(data: import(\"@lunibee/types\").GatewayPresence): boolean {\r\n return this.#gateway.setPresence?.(data) ?? false;\r\n }\r\n readonly #gateway: Gateway;\r\n readonly #resourceContext: ResourceContext;\r\n\r\n public constructor(public readonly options: ClientOptions) {\r\n super();\r\n if (!options.token?.trim())\r\n throw new TypeError(\"Client token is required.\");\r\n this.rest = new REST({ token: options.token, ...options.rest });\r\n this.users = new UserManager(this.rest);\r\n this.guilds = new GuildManager(this.rest);\r\n this.channels = new ChannelManager(this.rest);\r\n const placeholderAppCommands = new ApplicationCommandManager(\r\n this.rest,\r\n \"0\",\r\n );\r\n this.application = { commands: placeholderAppCommands };\r\n this.#resourceContext = {\r\n sendMessage: (channelId, options) =>\r\n this.channels.send(channelId, options),\r\n editMessage: (channelId, messageId, options) =>\r\n this.channels.editMessage(channelId, messageId, options),\r\n deleteMessage: (channelId, messageId) =>\r\n this.channels.deleteMessage(channelId, messageId),\r\n crosspostMessage: (channelId, messageId) =>\r\n this.channels.crosspostMessage(channelId, messageId),\r\n editChannel: (channelId, options) => this.channels.edit(channelId, options),\r\n deleteChannel: (channelId) => this.channels.deleteChannel(channelId),\r\n addReaction: (channelId, messageId, emoji) =>\r\n this.channels.addReaction(channelId, messageId, emoji),\r\n removeOwnReaction: (channelId, messageId, emoji) =>\r\n this.channels.removeOwnReaction(channelId, messageId, emoji),\r\n removeReaction: (channelId, messageId, emoji, userId) =>\r\n this.channels.removeReaction(channelId, messageId, emoji, userId),\r\n removeAllReactions: (channelId, messageId) =>\r\n this.channels.removeAllReactions(channelId, messageId),\r\n pinMessage: (channelId, messageId) =>\r\n this.channels.pinMessage(channelId, messageId),\r\n unpinMessage: (channelId, messageId) =>\r\n this.channels.unpinMessage(channelId, messageId),\r\n };\r\n this.#gateway = new Gateway({\r\n token: options.token,\r\n intents: options.intents,\r\n ...options.gateway,\r\n });\r\n\r\n // ── Lifecycle ────────────────────────────────────────────────────────────\r\n this.#gateway.on(\"READY\", (data) => {\r\n const ready = data as APIReadyEvent;\r\n this.user = ready.user;\r\n this.users.set(this.user.id, new User(this.user));\r\n this.readyAt = new Date();\r\n this.state = \"ready\";\r\n const appId = ready.application?.id ?? this.user.id;\r\n (this.application as { commands: ApplicationCommandManager }).commands =\r\n new ApplicationCommandManager(this.rest, appId);\r\n this.emit(ClientEvent.Ready, this.user);\r\n });\r\n this.#gateway.on(\"open\", () => this.emit(ClientEvent.Open));\r\n this.#gateway.on(\"close\", (data) => {\r\n if (this.state !== \"destroyed\") this.state = \"idle\";\r\n this.emit(ClientEvent.Close, data as { code: number; action: string });\r\n });\r\n\r\n // ── Messages ─────────────────────────────────────────────────────────────\r\n this.#gateway.on(\"MESSAGE_CREATE\", (data) => {\r\n const message = new Message(\r\n data as import(\"@lunibee/types\").APIMessage,\r\n this.#resourceContext,\r\n );\r\n this.channels.set(message.channelId, message.channel);\r\n this.users.set(message.author.id, message.author);\r\n this.emit(ClientEvent.MessageCreate, message);\r\n });\r\n this.#gateway.on(\"MESSAGE_UPDATE\", (data) => {\r\n const message = new Message(\r\n data as import(\"@lunibee/types\").APIMessage,\r\n this.#resourceContext,\r\n );\r\n this.channels.set(message.channelId, message.channel);\r\n this.users.set(message.author.id, message.author);\r\n this.emit(ClientEvent.MessageUpdate, message);\r\n });\r\n this.#gateway.on(\"MESSAGE_DELETE\", (data) =>\r\n this.emit(ClientEvent.MessageDelete, data as APIMessageDeleteEvent),\r\n );\r\n this.#gateway.on(\"MESSAGE_DELETE_BULK\", (data) =>\r\n this.emit(\r\n ClientEvent.MessageDeleteBulk,\r\n data as APIMessageDeleteBulkEvent,\r\n ),\r\n );\r\n\r\n // ── Reactions ────────────────────────────────────────────────────────────\r\n this.#gateway.on(\"MESSAGE_REACTION_ADD\", (data) =>\r\n this.emit(\r\n ClientEvent.MessageReactionAdd,\r\n data as APIMessageReactionEvent,\r\n ),\r\n );\r\n this.#gateway.on(\"MESSAGE_REACTION_REMOVE\", (data) =>\r\n this.emit(\r\n ClientEvent.MessageReactionRemove,\r\n data as APIMessageReactionEvent,\r\n ),\r\n );\r\n this.#gateway.on(\"MESSAGE_REACTION_REMOVE_ALL\", (data) =>\r\n this.emit(\r\n ClientEvent.MessageReactionRemoveAll,\r\n data as APIMessageDeleteEvent,\r\n ),\r\n );\r\n this.#gateway.on(\"MESSAGE_REACTION_REMOVE_EMOJI\", (data) =>\r\n this.emit(\r\n ClientEvent.MessageReactionRemoveEmoji,\r\n data as APIMessageReactionRemoveEmojiEvent,\r\n ),\r\n );\r\n\r\n // ── Polls ────────────────────────────────────────────────────────────────\r\n this.#gateway.on(\"MESSAGE_POLL_VOTE_ADD\", (data) =>\r\n this.emit(\r\n ClientEvent.MessagePollVoteAdd,\r\n data as APIMessagePollVoteEvent,\r\n ),\r\n );\r\n this.#gateway.on(\"MESSAGE_POLL_VOTE_REMOVE\", (data) =>\r\n this.emit(\r\n ClientEvent.MessagePollVoteRemove,\r\n data as APIMessagePollVoteEvent,\r\n ),\r\n );\r\n\r\n // ── Guilds ───────────────────────────────────────────────────────────────\r\n this.#gateway.on(\"GUILD_CREATE\", (data) => {\r\n const payload = data as APIGuild & {\r\n members?: APIGuildMember[];\r\n channels?: APIChannel[];\r\n threads?: APIChannel[];\r\n unavailable?: boolean;\r\n };\r\n if (payload.unavailable) {\r\n this.emit(ClientEvent.GuildUnavailable, payload);\r\n return;\r\n }\r\n const guild = new Guild(payload);\r\n this.guilds.set(guild.id, guild);\r\n for (const member of payload.members ?? [])\r\n this.users.set(member.user.id, new User(member.user));\r\n for (const channelData of [\r\n ...(payload.channels ?? []),\r\n ...(payload.threads ?? []),\r\n ])\r\n this.channels.set(\r\n channelData.id,\r\n new Channel(channelData, this.#resourceContext),\r\n );\r\n this.emit(ClientEvent.GuildCreate, payload);\r\n });\r\n this.#gateway.on(\"GUILD_UPDATE\", (data) => {\r\n const guild = new Guild(data as APIGuild);\r\n this.guilds.update(guild);\r\n this.emit(ClientEvent.GuildUpdate, data as APIGuild);\r\n });\r\n this.#gateway.on(\"GUILD_DELETE\", (data) => {\r\n const payload = data as { id: string; unavailable?: boolean };\r\n if (payload.unavailable) {\r\n this.emit(ClientEvent.GuildUnavailable, payload);\r\n return;\r\n }\r\n this.guilds.delete(payload.id);\r\n this.emit(ClientEvent.GuildDelete, payload);\r\n });\r\n\r\n // ── Guild Members ────────────────────────────────────────────────────────\r\n this.#gateway.on(\"GUILD_MEMBER_ADD\", (data) => {\r\n const member = data as APIGuildMember;\r\n this.users.set(member.user.id, new User(member.user));\r\n this.emit(ClientEvent.GuildMemberAdd, member);\r\n });\r\n this.#gateway.on(\"GUILD_MEMBER_UPDATE\", (data) => {\r\n const member = data as APIGuildMember;\r\n this.users.set(member.user.id, new User(member.user));\r\n this.emit(ClientEvent.GuildMemberUpdate, member);\r\n });\r\n this.#gateway.on(\"GUILD_MEMBER_REMOVE\", (data) =>\r\n this.emit(ClientEvent.GuildMemberRemove, data as APIGuildMember),\r\n );\r\n this.#gateway.on(\"GUILD_MEMBERS_CHUNK\", (data) =>\r\n this.emit(ClientEvent.GuildMembersChunk, data as APIGuildMembersChunk),\r\n );\r\n\r\n // ── Guild Bans ───────────────────────────────────────────────────────────\r\n this.#gateway.on(\"GUILD_BAN_ADD\", (data) =>\r\n this.emit(ClientEvent.GuildBanAdd, data as APIGuildBanEvent),\r\n );\r\n this.#gateway.on(\"GUILD_BAN_REMOVE\", (data) =>\r\n this.emit(ClientEvent.GuildBanRemove, data as APIGuildBanEvent),\r\n );\r\n\r\n // ── Guild Roles ──────────────────────────────────────────────────────────\r\n this.#gateway.on(\"GUILD_ROLE_CREATE\", (data) =>\r\n this.emit(ClientEvent.GuildRoleCreate, data as APIGuildRoleEvent),\r\n );\r\n this.#gateway.on(\"GUILD_ROLE_UPDATE\", (data) =>\r\n this.emit(ClientEvent.GuildRoleUpdate, data as APIGuildRoleEvent),\r\n );\r\n this.#gateway.on(\"GUILD_ROLE_DELETE\", (data) =>\r\n this.emit(ClientEvent.GuildRoleDelete, data as APIGuildRoleDeleteEvent),\r\n );\r\n\r\n // ── Guild Emojis & Stickers ──────────────────────────────────────────────\r\n this.#gateway.on(\"GUILD_EMOJIS_UPDATE\", (data) =>\r\n this.emit(\r\n ClientEvent.GuildEmojisUpdate,\r\n data as APIGuildEmojisUpdateEvent,\r\n ),\r\n );\r\n this.#gateway.on(\"GUILD_STICKERS_UPDATE\", (data) =>\r\n this.emit(\r\n ClientEvent.GuildStickersUpdate,\r\n data as APIGuildStickersUpdateEvent,\r\n ),\r\n );\r\n\r\n // ── Guild Integrations ───────────────────────────────────────────────────\r\n this.#gateway.on(\"GUILD_INTEGRATIONS_UPDATE\", (data) =>\r\n this.emit(\r\n ClientEvent.GuildIntegrationsUpdate,\r\n data as { guild_id: string },\r\n ),\r\n );\r\n\r\n // ── Guild Scheduled Events ───────────────────────────────────────────────\r\n this.#gateway.on(\"GUILD_SCHEDULED_EVENT_CREATE\", (data) =>\r\n this.emit(\r\n ClientEvent.GuildScheduledEventCreate,\r\n data as APIGuildScheduledEvent,\r\n ),\r\n );\r\n this.#gateway.on(\"GUILD_SCHEDULED_EVENT_UPDATE\", (data) =>\r\n this.emit(\r\n ClientEvent.GuildScheduledEventUpdate,\r\n data as APIGuildScheduledEvent,\r\n ),\r\n );\r\n this.#gateway.on(\"GUILD_SCHEDULED_EVENT_DELETE\", (data) =>\r\n this.emit(\r\n ClientEvent.GuildScheduledEventDelete,\r\n data as APIGuildScheduledEvent,\r\n ),\r\n );\r\n this.#gateway.on(\"GUILD_SCHEDULED_EVENT_USER_ADD\", (data) =>\r\n this.emit(\r\n ClientEvent.GuildScheduledEventUserAdd,\r\n data as APIGuildScheduledEventUserEvent,\r\n ),\r\n );\r\n this.#gateway.on(\"GUILD_SCHEDULED_EVENT_USER_REMOVE\", (data) =>\r\n this.emit(\r\n ClientEvent.GuildScheduledEventUserRemove,\r\n data as APIGuildScheduledEventUserEvent,\r\n ),\r\n );\r\n\r\n // ── AutoMod ──────────────────────────────────────────────────────────────\r\n this.#gateway.on(\"AUTO_MODERATION_RULE_CREATE\", (data) =>\r\n this.emit(\r\n ClientEvent.AutoModerationRuleCreate,\r\n data as APIAutoModerationRule,\r\n ),\r\n );\r\n this.#gateway.on(\"AUTO_MODERATION_RULE_UPDATE\", (data) =>\r\n this.emit(\r\n ClientEvent.AutoModerationRuleUpdate,\r\n data as APIAutoModerationRule,\r\n ),\r\n );\r\n this.#gateway.on(\"AUTO_MODERATION_RULE_DELETE\", (data) =>\r\n this.emit(\r\n ClientEvent.AutoModerationRuleDelete,\r\n data as APIAutoModerationRule,\r\n ),\r\n );\r\n this.#gateway.on(\"AUTO_MODERATION_ACTION_EXECUTION\", (data) =>\r\n this.emit(\r\n ClientEvent.AutoModerationActionExecution,\r\n data as APIAutoModerationActionExecution,\r\n ),\r\n );\r\n\r\n // ── Channels ─────────────────────────────────────────────────────────────\r\n this.#gateway.on(\"CHANNEL_CREATE\", (data) => {\r\n const channel = new Channel(data as APIChannel, this.#resourceContext);\r\n this.channels.update(channel);\r\n this.emit(ClientEvent.ChannelCreate, channel);\r\n });\r\n this.#gateway.on(\"CHANNEL_UPDATE\", (data) => {\r\n const channel = new Channel(data as APIChannel, this.#resourceContext);\r\n this.channels.update(channel);\r\n this.emit(ClientEvent.ChannelUpdate, channel);\r\n });\r\n this.#gateway.on(\"CHANNEL_DELETE\", (data) => {\r\n const payload = data as APIChannel;\r\n this.channels.delete(payload.id);\r\n this.emit(ClientEvent.ChannelDelete, payload);\r\n });\r\n this.#gateway.on(\"CHANNEL_PINS_UPDATE\", (data) =>\r\n this.emit(ClientEvent.ChannelPinsUpdate, data as APIChannelPinsUpdate),\r\n );\r\n\r\n // ── Threads ──────────────────────────────────────────────────────────────\r\n this.#gateway.on(\"THREAD_CREATE\", (data) => {\r\n const channel = new Channel(\r\n data as APIThreadEvent,\r\n this.#resourceContext,\r\n );\r\n this.channels.update(channel);\r\n this.emit(ClientEvent.ThreadCreate, channel);\r\n });\r\n this.#gateway.on(\"THREAD_UPDATE\", (data) => {\r\n const channel = new Channel(\r\n data as APIThreadEvent,\r\n this.#resourceContext,\r\n );\r\n this.channels.update(channel);\r\n this.emit(ClientEvent.ThreadUpdate, channel);\r\n });\r\n this.#gateway.on(\"THREAD_DELETE\", (data) => {\r\n const payload = data as APIThreadEvent;\r\n this.channels.delete(payload.id);\r\n this.emit(ClientEvent.ThreadDelete, payload);\r\n });\r\n this.#gateway.on(\"THREAD_LIST_SYNC\", (data) =>\r\n this.emit(ClientEvent.ThreadListSync, data as APIThreadListSync),\r\n );\r\n this.#gateway.on(\"THREAD_MEMBERS_UPDATE\", (data) =>\r\n this.emit(\r\n ClientEvent.ThreadMembersUpdate,\r\n data as APIThreadMembersUpdate,\r\n ),\r\n );\r\n this.#gateway.on(\"THREAD_MEMBER_UPDATE\", (data) =>\r\n this.emit(\r\n ClientEvent.ThreadMemberUpdate,\r\n data as import(\"@lunibee/types\").APIThreadMember,\r\n ),\r\n );\r\n\r\n // ── Stage Instances ──────────────────────────────────────────────────────\r\n this.#gateway.on(\"STAGE_INSTANCE_CREATE\", (data) =>\r\n this.emit(ClientEvent.StageInstanceCreate, data as APIStageInstance),\r\n );\r\n this.#gateway.on(\"STAGE_INSTANCE_UPDATE\", (data) =>\r\n this.emit(ClientEvent.StageInstanceUpdate, data as APIStageInstance),\r\n );\r\n this.#gateway.on(\"STAGE_INSTANCE_DELETE\", (data) =>\r\n this.emit(ClientEvent.StageInstanceDelete, data as APIStageInstance),\r\n );\r\n\r\n // ── Invites ──────────────────────────────────────────────────────────────\r\n this.#gateway.on(\"INVITE_CREATE\", (data) =>\r\n this.emit(ClientEvent.InviteCreate, data as APIInviteCreate),\r\n );\r\n this.#gateway.on(\"INVITE_DELETE\", (data) =>\r\n this.emit(ClientEvent.InviteDelete, data as APIInviteDelete),\r\n );\r\n\r\n // ── Webhooks ─────────────────────────────────────────────────────────────\r\n this.#gateway.on(\"WEBHOOKS_UPDATE\", (data) =>\r\n this.emit(ClientEvent.WebhooksUpdate, data as APIWebhooksUpdate),\r\n );\r\n\r\n // ── Voice ────────────────────────────────────────────────────────────────\r\n this.#gateway.on(\"VOICE_STATE_UPDATE\", (data) =>\r\n this.emit(ClientEvent.VoiceStateUpdate, data as APIVoiceState),\r\n );\r\n this.#gateway.on(\"VOICE_SERVER_UPDATE\", (data) =>\r\n this.emit(ClientEvent.VoiceServerUpdate, data as APIVoiceServerUpdate),\r\n );\r\n\r\n // ── Presence & Typing ────────────────────────────────────────────────────\r\n this.#gateway.on(\"PRESENCE_UPDATE\", (data) =>\r\n this.emit(ClientEvent.PresenceUpdate, data as APIPresenceUpdate),\r\n );\r\n this.#gateway.on(\"TYPING_START\", (data) =>\r\n this.emit(ClientEvent.TypingStart, data as APITypingStart),\r\n );\r\n\r\n // ── Interactions ─────────────────────────────────────────────────────────\r\n this.#gateway.on(\"INTERACTION_CREATE\", (data) =>\r\n this.emit(\r\n ClientEvent.InteractionCreate,\r\n createInteraction(this, data as any),\r\n ),\r\n );\r\n\r\n // ── Raw / Error ───────────────────────────────────────────────────────────\r\n this.#gateway.on(\"RAW\", (data) =>\r\n this.emit(ClientEvent.Raw, data as { event: string; data: unknown }),\r\n );\r\n this.#gateway.on(\"error\", (error) =>\r\n this.emit(ClientEvent.Error, error as Error),\r\n );\r\n }\r\n\r\n /**\r\n * Convenience method to connect the bot to Discord.\r\n * Optionally overrides the configured token.\r\n * @param token Optional token override.\r\n * @returns The token used to log in.\r\n * @throws {TypeError} If the resulting token is empty.\r\n */\r\n public async login(token?: string): Promise<string> {\r\n if (this.state === \"destroyed\")\r\n throw new Error(\"Cannot login a destroyed client.\");\r\n if (token?.trim()) {\r\n this.rest.setToken(token);\r\n (this as any).options.token = token;\r\n }\r\n const usedToken = (this as any).options.token as string;\r\n if (!usedToken?.trim())\r\n throw new TypeError(\"A bot token is required to log in.\");\r\n this.state = \"connecting\";\r\n await this.#gateway.connect();\r\n return usedToken;\r\n }\r\n\r\n /**\r\n * Destroys the client, permanently closing the Gateway connection.\r\n */\r\n public destroy(): void {\r\n this.state = \"destroyed\";\r\n this.#gateway.close();\r\n }\r\n\r\n // ── InteractionClient implementation ─────────────────────────────────────\r\n\r\n public postInteractionResponse(\r\n id: string,\r\n token: string,\r\n response: import(\"@lunibee/structures\").InteractionResponse,\r\n ): Promise<unknown> {\r\n return this.rest.post(\r\n Routes.interactionCallback(id, token),\r\n response.toJSON(),\r\n );\r\n }\r\n public editInteractionReply(\r\n token: string,\r\n data: Record<string, unknown>,\r\n ): Promise<unknown> {\r\n if (!this.user) return Promise.reject(new Error(\"Client is unauthenticated.\"));\r\n return this.rest.patch(\r\n Routes.interactionOriginalResponse(this.user.id, token),\r\n data,\r\n );\r\n }\r\n public deleteInteractionReply(token: string): Promise<void> {\r\n if (!this.user) return Promise.reject(new Error(\"Client is unauthenticated.\"));\r\n return this.rest.delete(\r\n Routes.interactionOriginalResponse(this.user.id, token),\r\n );\r\n }\r\n public followUpInteraction(\r\n token: string,\r\n data: Record<string, unknown>,\r\n ): Promise<unknown> {\r\n if (!this.user) return Promise.reject(new Error(\"Client is unauthenticated.\"));\r\n return this.rest.post(`/webhooks/${this.user.id}/${token}`, data);\r\n }\r\n}\r\n\r\n// ─── ClientEvents type map ────────────────────────────────────────────────────\r\n// Uses string literal keys so client.on(\"ready\", ...) works without using\r\n// the ClientEvent enum explicitly.\r\n\r\nexport type ClientEvents = {\r\n // ── Lifecycle ──────────────────────────────────────────────────────────────\r\n ready: [user: ClientUser];\r\n raw: [data: { event: string; data: unknown }];\r\n error: [error: Error];\r\n open: [];\r\n close: [data: { code: number; action: string }];\r\n // ── Messages ───────────────────────────────────────────────────────────────\r\n messageCreate: [message: Message];\r\n messageUpdate: [message: Message];\r\n messageDelete: [data: APIMessageDeleteEvent];\r\n messageDeleteBulk: [data: APIMessageDeleteBulkEvent];\r\n // ── Reactions ─────────────────────────────────────────────────────────────\r\n messageReactionAdd: [data: APIMessageReactionEvent];\r\n messageReactionRemove: [data: APIMessageReactionEvent];\r\n messageReactionRemoveAll: [data: APIMessageDeleteEvent];\r\n messageReactionRemoveEmoji: [data: APIMessageReactionRemoveEmojiEvent];\r\n // ── Polls ─────────────────────────────────────────────────────────────────\r\n messagePollVoteAdd: [data: APIMessagePollVoteEvent];\r\n messagePollVoteRemove: [data: APIMessagePollVoteEvent];\r\n // ── Guilds ────────────────────────────────────────────────────────────────\r\n guildCreate: [data: APIGuild];\r\n guildUpdate: [data: APIGuild];\r\n guildDelete: [data: { id: string; unavailable?: boolean }];\r\n guildAvailable: [data: APIGuild & { unavailable?: boolean }];\r\n guildUnavailable: [data: { id: string; unavailable?: boolean }];\r\n // ── Guild Members ──────────────────────────────────────────────────────────\r\n guildMemberAdd: [member: APIGuildMember];\r\n guildMemberUpdate: [member: APIGuildMember];\r\n guildMemberRemove: [member: APIGuildMember];\r\n guildMembersChunk: [data: APIGuildMembersChunk];\r\n // ── Guild Bans ────────────────────────────────────────────────────────────\r\n guildBanAdd: [data: APIGuildBanEvent];\r\n guildBanRemove: [data: APIGuildBanEvent];\r\n // ── Guild Roles ───────────────────────────────────────────────────────────\r\n guildRoleCreate: [data: APIGuildRoleEvent];\r\n guildRoleUpdate: [data: APIGuildRoleEvent];\r\n guildRoleDelete: [data: APIGuildRoleDeleteEvent];\r\n // ── Guild Emojis & Stickers ───────────────────────────────────────────────\r\n guildEmojisUpdate: [data: APIGuildEmojisUpdateEvent];\r\n guildStickersUpdate: [data: APIGuildStickersUpdateEvent];\r\n // ── Guild Integrations ────────────────────────────────────────────────────\r\n guildIntegrationsUpdate: [data: { guild_id: string }];\r\n // ── Guild Scheduled Events ────────────────────────────────────────────────\r\n guildScheduledEventCreate: [data: APIGuildScheduledEvent];\r\n guildScheduledEventUpdate: [data: APIGuildScheduledEvent];\r\n guildScheduledEventDelete: [data: APIGuildScheduledEvent];\r\n guildScheduledEventUserAdd: [data: APIGuildScheduledEventUserEvent];\r\n guildScheduledEventUserRemove: [data: APIGuildScheduledEventUserEvent];\r\n // ── AutoMod ───────────────────────────────────────────────────────────────\r\n autoModerationRuleCreate: [data: APIAutoModerationRule];\r\n autoModerationRuleUpdate: [data: APIAutoModerationRule];\r\n autoModerationRuleDelete: [data: APIAutoModerationRule];\r\n autoModerationActionExecution: [data: APIAutoModerationActionExecution];\r\n // ── Channels ──────────────────────────────────────────────────────────────\r\n channelCreate: [channel: Channel];\r\n channelUpdate: [channel: Channel];\r\n channelDelete: [data: APIChannel];\r\n channelPinsUpdate: [data: APIChannelPinsUpdate];\r\n // ── Threads ───────────────────────────────────────────────────────────────\r\n threadCreate: [channel: Channel];\r\n threadUpdate: [channel: Channel];\r\n threadDelete: [data: APIThreadEvent];\r\n threadListSync: [data: APIThreadListSync];\r\n threadMembersUpdate: [data: APIThreadMembersUpdate];\r\n threadMemberUpdate: [data: APIThreadMember];\r\n // ── Stage Instances ───────────────────────────────────────────────────────\r\n stageInstanceCreate: [data: APIStageInstance];\r\n stageInstanceUpdate: [data: APIStageInstance];\r\n stageInstanceDelete: [data: APIStageInstance];\r\n // ── Invites ───────────────────────────────────────────────────────────────\r\n inviteCreate: [data: APIInviteCreate];\r\n inviteDelete: [data: APIInviteDelete];\r\n // ── Webhooks ──────────────────────────────────────────────────────────────\r\n webhooksUpdate: [data: APIWebhooksUpdate];\r\n // ── Voice ─────────────────────────────────────────────────────────────────\r\n voiceStateUpdate: [data: APIVoiceState];\r\n voiceServerUpdate: [data: APIVoiceServerUpdate];\r\n // ── Presence & Typing ─────────────────────────────────────────────────────\r\n presenceUpdate: [data: APIPresenceUpdate];\r\n typingStart: [data: APITypingStart];\r\n // ── Interactions ──────────────────────────────────────────────────────────\r\n interactionCreate: [interaction: Interaction];\r\n};\r\n"
|
|
25
24
|
],
|
|
26
|
-
"mappings": "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",
|
|
27
|
-
"debugId": "
|
|
25
|
+
"mappings": "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",
|
|
26
|
+
"debugId": "813519968046205864756E2164756E21",
|
|
28
27
|
"names": []
|
|
29
28
|
}
|