lunibee 0.3.3 → 0.4.0
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 +1 -1
- package/dist/builders/commands.d.ts +1 -1
- package/dist/builders/components.d.ts +9 -11
- package/dist/builders/embed.d.ts +1 -1
- package/dist/builders/index.d.ts +1 -1
- package/dist/builders/index.js +87 -1298
- package/dist/builders/index.js.map +3 -11
- package/dist/chunks/index-0wn81eng.js +2492 -0
- package/dist/chunks/index-0wn81eng.js.map +17 -0
- package/dist/chunks/index-2en489j6.js +40 -0
- package/dist/chunks/index-2en489j6.js.map +10 -0
- package/dist/chunks/index-3hyps48a.js +203 -0
- package/dist/chunks/index-3hyps48a.js.map +11 -0
- package/dist/chunks/index-57c5n3ms.js +2274 -0
- package/dist/chunks/index-57c5n3ms.js.map +19 -0
- package/dist/chunks/index-5yx92e36.js +1170 -0
- package/dist/chunks/index-5yx92e36.js.map +14 -0
- package/dist/chunks/index-690bp093.js +95 -0
- package/dist/chunks/index-690bp093.js.map +10 -0
- package/dist/chunks/index-7fp2hvmg.js +2155 -0
- package/dist/chunks/index-7fp2hvmg.js.map +24 -0
- package/dist/chunks/index-cnmsajvk.js +1119 -0
- package/dist/chunks/index-cnmsajvk.js.map +12 -0
- package/dist/chunks/index-fdvgk2sw.js +1310 -0
- package/dist/chunks/index-fdvgk2sw.js.map +21 -0
- package/dist/chunks/index-gyvps8b9.js +214 -0
- package/dist/chunks/index-gyvps8b9.js.map +12 -0
- package/dist/chunks/index-jzg4bh99.js +1533 -0
- package/dist/chunks/index-jzg4bh99.js.map +21 -0
- package/dist/chunks/index-mgw2yvrm.js +3547 -0
- package/dist/chunks/index-mgw2yvrm.js.map +25 -0
- package/dist/chunks/index-yh76b55h.js +3449 -0
- package/dist/chunks/index-yh76b55h.js.map +29 -0
- package/dist/collection/index.js +9 -1118
- package/dist/collection/index.js.map +3 -6
- package/dist/core/api.d.ts +3 -3
- package/dist/core/channel-create.d.ts +2 -2
- package/dist/core/commands.d.ts +3 -3
- package/dist/core/events.d.ts +4 -4
- package/dist/core/handles.d.ts +4 -4
- package/dist/core/index.d.ts +25 -20
- package/dist/core/index.js +68 -10130
- package/dist/core/index.js.map +3 -65
- package/dist/core/permissions.d.ts +1 -1
- package/dist/core/redis-cache.d.ts +1 -1
- package/dist/formatters/index.js +41 -110
- package/dist/formatters/index.js.map +3 -4
- package/dist/handlers/index.js +5 -37
- package/dist/handlers/index.js.map +3 -4
- package/dist/index.d.ts +21 -21
- package/dist/index.js +641 -16325
- package/dist/index.js.map +3 -92
- package/dist/managers/advanced.d.ts +3 -3
- package/dist/managers/application.d.ts +2 -2
- package/dist/managers/base.d.ts +1 -1
- package/dist/managers/emoji.d.ts +2 -2
- package/dist/managers/guild-resources.d.ts +6 -6
- package/dist/managers/guild.d.ts +3 -3
- package/dist/managers/index.d.ts +4 -8
- package/dist/managers/index.js +51 -4060
- package/dist/managers/index.js.map +3 -29
- package/dist/managers/member.d.ts +2 -2
- package/dist/managers/message.d.ts +14 -6
- package/dist/managers/role.d.ts +2 -2
- package/dist/managers/thread.d.ts +3 -3
- package/dist/managers/user.d.ts +7 -4
- package/dist/rest/index.d.ts +10 -35
- package/dist/rest/index.js +57 -2184
- package/dist/rest/index.js.map +3 -18
- package/dist/rest/limiter.d.ts +9 -1
- package/dist/rest/webhook.d.ts +2 -8
- package/dist/sharding/bus.d.ts +2 -2
- package/dist/sharding/cluster.d.ts +45 -5
- package/dist/sharding/context.d.ts +45 -3
- package/dist/sharding/gateway-bot.d.ts +2 -1
- package/dist/sharding/health.d.ts +1 -1
- package/dist/sharding/identify.d.ts +12 -0
- package/dist/sharding/index.d.ts +44 -11
- package/dist/sharding/index.js +60 -4620
- package/dist/sharding/index.js.map +3 -33
- package/dist/sharding/supervisor.d.ts +4 -2
- package/dist/structures/audit-log.d.ts +1 -1
- package/dist/structures/base.d.ts +6 -6
- package/dist/structures/channels.d.ts +1 -1
- package/dist/structures/embed.d.ts +1 -1
- package/dist/structures/index.d.ts +14 -14
- package/dist/structures/index.js +109 -2382
- package/dist/structures/index.js.map +3 -16
- package/dist/structures/interactions.d.ts +13 -9
- package/dist/structures/options.d.ts +1 -1
- package/dist/structures/permissions.d.ts +2 -2
- package/dist/structures/resources.d.ts +10 -10
- package/dist/structures/sticker.d.ts +1 -1
- package/dist/types/gateway.d.ts +2 -79
- package/dist/types/index.d.ts +0 -6
- package/dist/types/index.js +41 -272
- package/dist/types/index.js.map +3 -6
- package/dist/utils/index.js +23 -209
- package/dist/utils/index.js.map +3 -5
- package/dist/voice/connection.d.ts +200 -0
- package/dist/voice/crypto.d.ts +50 -0
- package/dist/voice/dave.d.ts +85 -0
- package/dist/voice/effects.d.ts +31 -0
- package/dist/voice/emitter.d.ts +14 -0
- package/dist/voice/gateway.d.ts +59 -0
- package/dist/voice/index.d.ts +25 -228
- package/dist/voice/index.js +111 -442
- package/dist/voice/index.js.map +3 -4
- package/dist/voice/libopus.d.ts +88 -0
- package/dist/voice/networking.d.ts +80 -0
- package/dist/voice/ogg.d.ts +24 -0
- package/dist/voice/opus.d.ts +18 -0
- package/dist/voice/player.d.ts +79 -0
- package/dist/voice/protocol.d.ts +76 -0
- package/dist/voice/receiver.d.ts +59 -0
- package/dist/voice/resource.d.ts +102 -0
- package/dist/voice/udp.d.ts +40 -0
- package/dist/ws/close-codes.d.ts +1 -1
- package/dist/ws/index.d.ts +25 -4
- package/dist/ws/index.js +47 -1336
- package/dist/ws/index.js.map +3 -17
- package/dist/ws/protocol.d.ts +1 -1
- package/dist/ws/send-budget.d.ts +0 -2
- package/dist/ws/state.d.ts +0 -10
- package/package.json +19 -16
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../packages/core/src/events.ts", "../packages/core/src/collector.ts", "../packages/core/src/redis-cache.ts", "../packages/core/src/api.ts", "../packages/core/src/commands.ts", "../packages/core/src/channel-create.ts", "../packages/core/src/handles.ts", "../packages/core/src/index.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import type {\n APIEntitlement,\n APISoundboardSound,\n APISticker,\n} from \"@lunibee/types\";\nimport type {\n APIAutoModerationActionExecution,\n APIAutoModerationRule,\n APIChannel,\n APIChannelPinsUpdate,\n APIGuild,\n APIGuildBanEvent,\n APIGuildEmojisUpdateEvent,\n APIGuildMember,\n APIGuildMembersChunk,\n APIGuildRoleDeleteEvent,\n APIGuildRoleEvent,\n APIGuildScheduledEvent,\n APIGuildScheduledEventUserEvent,\n APIGuildStickersUpdateEvent,\n APIInviteCreate,\n APIInviteDelete,\n APIMessageDeleteBulkEvent,\n APIMessageDeleteEvent,\n APIMessagePollVoteEvent,\n APIMessageReactionEvent,\n APIMessageReactionRemoveEmojiEvent,\n APIPresenceUpdate,\n APIStageInstance,\n APIThreadEvent,\n APIThreadListSync,\n APIThreadMember,\n APIThreadMembersUpdate,\n APITypingStart,\n APIVoiceServerUpdate,\n APIVoiceState,\n APIWebhooksUpdate,\n UserData,\n} from \"@lunibee/types\";\nimport type {\n Channel,\n Emoji,\n Guild,\n GuildMember,\n Interaction,\n Message,\n Role,\n} from \"@lunibee/structures\";\n/** Names of events emitted by a Lunibee client. */\nexport enum ClientEvent {\n // ── Lifecycle ──────────────────────────────────────────────────────────────\n Ready = \"ready\",\n Resumed = \"resumed\",\n InvalidSession = \"invalidSession\",\n Raw = \"raw\",\n Error = \"error\",\n Open = \"open\",\n Close = \"close\",\n // ── Messages ───────────────────────────────────────────────────────────────\n MessageCreate = \"messageCreate\",\n MessageUpdate = \"messageUpdate\",\n MessageDelete = \"messageDelete\",\n MessageDeleteBulk = \"messageDeleteBulk\",\n // ── Reactions ─────────────────────────────────────────────────────────────\n MessageReactionAdd = \"messageReactionAdd\",\n MessageReactionRemove = \"messageReactionRemove\",\n MessageReactionRemoveAll = \"messageReactionRemoveAll\",\n MessageReactionRemoveEmoji = \"messageReactionRemoveEmoji\",\n // ── Polls ─────────────────────────────────────────────────────────────────\n MessagePollVoteAdd = \"messagePollVoteAdd\",\n MessagePollVoteRemove = \"messagePollVoteRemove\",\n // ── Guilds ────────────────────────────────────────────────────────────────\n GuildCreate = \"guildCreate\",\n GuildUpdate = \"guildUpdate\",\n GuildDelete = \"guildDelete\",\n GuildAvailable = \"guildAvailable\",\n GuildUnavailable = \"guildUnavailable\",\n // ── Guild Members ──────────────────────────────────────────────────────────\n GuildMemberAdd = \"guildMemberAdd\",\n GuildMemberUpdate = \"guildMemberUpdate\",\n GuildMemberRemove = \"guildMemberRemove\",\n GuildMembersChunk = \"guildMembersChunk\",\n // ── Guild Bans ────────────────────────────────────────────────────────────\n GuildBanAdd = \"guildBanAdd\",\n GuildBanRemove = \"guildBanRemove\",\n // ── Guild Roles ───────────────────────────────────────────────────────────\n GuildRoleCreate = \"guildRoleCreate\",\n GuildRoleUpdate = \"guildRoleUpdate\",\n GuildRoleDelete = \"guildRoleDelete\",\n // ── Guild Emojis & Stickers ───────────────────────────────────────────────\n GuildEmojisUpdate = \"guildEmojisUpdate\",\n GuildStickersUpdate = \"guildStickersUpdate\",\n // ── Monetization ──────────────────────────────────────────────────────────\n EntitlementCreate = \"entitlementCreate\",\n EntitlementUpdate = \"entitlementUpdate\",\n EntitlementDelete = \"entitlementDelete\",\n // ── Soundboard ────────────────────────────────────────────────────────────\n SoundboardSoundCreate = \"soundboardSoundCreate\",\n SoundboardSoundUpdate = \"soundboardSoundUpdate\",\n SoundboardSoundDelete = \"soundboardSoundDelete\",\n SoundboardSoundsUpdate = \"soundboardSoundsUpdate\",\n // ── Guild Integrations ────────────────────────────────────────────────────\n GuildIntegrationsUpdate = \"guildIntegrationsUpdate\",\n // ── Guild Scheduled Events ────────────────────────────────────────────────\n GuildScheduledEventCreate = \"guildScheduledEventCreate\",\n GuildScheduledEventUpdate = \"guildScheduledEventUpdate\",\n GuildScheduledEventDelete = \"guildScheduledEventDelete\",\n GuildScheduledEventUserAdd = \"guildScheduledEventUserAdd\",\n GuildScheduledEventUserRemove = \"guildScheduledEventUserRemove\",\n // ── AutoMod ───────────────────────────────────────────────────────────────\n AutoModerationRuleCreate = \"autoModerationRuleCreate\",\n AutoModerationRuleUpdate = \"autoModerationRuleUpdate\",\n AutoModerationRuleDelete = \"autoModerationRuleDelete\",\n AutoModerationActionExecution = \"autoModerationActionExecution\",\n // ── Channels ──────────────────────────────────────────────────────────────\n ChannelCreate = \"channelCreate\",\n ChannelUpdate = \"channelUpdate\",\n ChannelDelete = \"channelDelete\",\n ChannelPinsUpdate = \"channelPinsUpdate\",\n // ── Threads ───────────────────────────────────────────────────────────────\n ThreadCreate = \"threadCreate\",\n ThreadUpdate = \"threadUpdate\",\n ThreadDelete = \"threadDelete\",\n ThreadListSync = \"threadListSync\",\n ThreadMembersUpdate = \"threadMembersUpdate\",\n ThreadMemberUpdate = \"threadMemberUpdate\",\n // ── Stage Instances ───────────────────────────────────────────────────────\n StageInstanceCreate = \"stageInstanceCreate\",\n StageInstanceUpdate = \"stageInstanceUpdate\",\n StageInstanceDelete = \"stageInstanceDelete\",\n // ── Invites ───────────────────────────────────────────────────────────────\n InviteCreate = \"inviteCreate\",\n InviteDelete = \"inviteDelete\",\n // ── Webhooks ──────────────────────────────────────────────────────────────\n WebhooksUpdate = \"webhooksUpdate\",\n // ── Voice ─────────────────────────────────────────────────────────────────\n VoiceStateUpdate = \"voiceStateUpdate\",\n VoiceServerUpdate = \"voiceServerUpdate\",\n // ── Presence & Typing ─────────────────────────────────────────────────────\n PresenceUpdate = \"presenceUpdate\",\n TypingStart = \"typingStart\",\n // ── Interactions ──────────────────────────────────────────────────────────\n InteractionCreate = \"interactionCreate\",\n}\n\n/** Names of events emitted by a Lunibee client. */\nexport type ClientEventName = keyof ClientEvents;\n\n/** Listener signature for a Lunibee client event. */\nexport type ClientListener<K extends ClientEventName> = (\n ...args: ClientEvents[K]\n) => unknown;\n\n// ─── ClientEvents type map ────────────────────────────────────────────────────\n// Uses string literal keys so client.on(\"ready\", ...) works without using\n// the ClientEvent enum explicitly.\n\n/** Every `Client` event name mapped to its listener arguments. */\nexport type ClientEvents = {\n // ── Lifecycle ──────────────────────────────────────────────────────────────\n ready: [user: UserData];\n resumed: [];\n invalidSession: [isRecoverable: boolean];\n raw: [data: { event: string; data: unknown }];\n error: [error: Error];\n open: [];\n close: [data: { code: number; action: string }];\n // ── Messages ───────────────────────────────────────────────────────────────\n messageCreate: [message: Message];\n /** `previous` is the cached version, or `null` unless `messageCache` is enabled and the message was cached. */\n messageUpdate: [message: Message, previous: Message | null];\n /** `message` is the cached message, available when `messageCache` is enabled. */\n messageDelete: [data: APIMessageDeleteEvent, message?: Message];\n /** `messages` are the cached messages that were deleted (empty without `messageCache`). */\n messageDeleteBulk: [data: APIMessageDeleteBulkEvent, messages: Message[]];\n // ── Reactions ─────────────────────────────────────────────────────────────\n messageReactionAdd: [data: APIMessageReactionEvent];\n messageReactionRemove: [data: APIMessageReactionEvent];\n messageReactionRemoveAll: [data: APIMessageDeleteEvent];\n messageReactionRemoveEmoji: [data: APIMessageReactionRemoveEmojiEvent];\n // ── Polls ─────────────────────────────────────────────────────────────────\n messagePollVoteAdd: [data: APIMessagePollVoteEvent];\n messagePollVoteRemove: [data: APIMessagePollVoteEvent];\n // ── Guilds ────────────────────────────────────────────────────────────────\n guildCreate: [data: APIGuild];\n /** `previous` is a copy of the cached guild before the update, or null when it was not cached. */\n guildUpdate: [data: APIGuild, previous: Guild | null];\n guildDelete: [data: { id: string; unavailable?: boolean }];\n guildAvailable: [data: APIGuild & { unavailable?: boolean }];\n guildUnavailable: [data: { id: string; unavailable?: boolean }];\n // ── Guild Members ──────────────────────────────────────────────────────────\n guildMemberAdd: [member: APIGuildMember];\n /** `previous` is a copy of the cached member before the update, or null when it was not cached. */\n guildMemberUpdate: [member: APIGuildMember, previous: GuildMember | null];\n guildMemberRemove: [member: APIGuildMember];\n guildMembersChunk: [data: APIGuildMembersChunk];\n // ── Guild Bans ────────────────────────────────────────────────────────────\n guildBanAdd: [data: APIGuildBanEvent];\n guildBanRemove: [data: APIGuildBanEvent];\n // ── Guild Roles ───────────────────────────────────────────────────────────\n guildRoleCreate: [data: APIGuildRoleEvent];\n /** `previous` is a copy of the cached role before the update, or null when it was not cached. */\n guildRoleUpdate: [data: APIGuildRoleEvent, previous: Role | null];\n /** `removed` is the role that was cached, or null. */\n guildRoleDelete: [data: APIGuildRoleDeleteEvent, removed: Role | null];\n // ── Guild Emojis & Stickers ───────────────────────────────────────────────\n /** `previous` is the cached emoji list before the update, or null without the emoji cache. */\n guildEmojisUpdate: [\n data: APIGuildEmojisUpdateEvent,\n previous: Emoji[] | null,\n ];\n /** `previous` is the cached sticker list before the update (empty when none were cached). */\n guildStickersUpdate: [\n data: APIGuildStickersUpdateEvent,\n previous: APISticker[],\n ];\n // ── Monetization ──────────────────────────────────────────────────────────\n entitlementCreate: [entitlement: APIEntitlement];\n entitlementUpdate: [entitlement: APIEntitlement];\n entitlementDelete: [entitlement: APIEntitlement];\n // ── Soundboard ────────────────────────────────────────────────────────────\n soundboardSoundCreate: [sound: APISoundboardSound];\n soundboardSoundUpdate: [sound: APISoundboardSound];\n soundboardSoundDelete: [data: { sound_id: string; guild_id: string }];\n soundboardSoundsUpdate: [\n data: { guild_id: string; soundboard_sounds: APISoundboardSound[] },\n ];\n // ── Guild Integrations ────────────────────────────────────────────────────\n guildIntegrationsUpdate: [data: { guild_id: string }];\n // ── Guild Scheduled Events ────────────────────────────────────────────────\n guildScheduledEventCreate: [data: APIGuildScheduledEvent];\n /** `previous` is the cached event, or `null` if it was not cached. */\n guildScheduledEventUpdate: [\n data: APIGuildScheduledEvent,\n previous: APIGuildScheduledEvent | null,\n ];\n guildScheduledEventDelete: [data: APIGuildScheduledEvent];\n guildScheduledEventUserAdd: [data: APIGuildScheduledEventUserEvent];\n guildScheduledEventUserRemove: [data: APIGuildScheduledEventUserEvent];\n // ── AutoMod ───────────────────────────────────────────────────────────────\n autoModerationRuleCreate: [data: APIAutoModerationRule];\n /** `previous` is the cached rule, or `null` if it was not cached. */\n autoModerationRuleUpdate: [\n data: APIAutoModerationRule,\n previous: APIAutoModerationRule | null,\n ];\n autoModerationRuleDelete: [data: APIAutoModerationRule];\n autoModerationActionExecution: [data: APIAutoModerationActionExecution];\n // ── Channels ──────────────────────────────────────────────────────────────\n channelCreate: [channel: Channel];\n /** `previous` is a copy of the cached channel before the update, or null when it was not cached. */\n channelUpdate: [channel: Channel, previous: Channel | null];\n /** `removed` is the channel that was cached, or null. */\n channelDelete: [data: APIChannel, removed: Channel | null];\n channelPinsUpdate: [data: APIChannelPinsUpdate];\n // ── Threads ───────────────────────────────────────────────────────────────\n threadCreate: [channel: Channel];\n /** `previous` is a copy of the cached thread before the update, or null when it was not cached. */\n threadUpdate: [channel: Channel, previous: Channel | null];\n /** `removed` is the thread that was cached, or null. */\n threadDelete: [data: APIThreadEvent, removed: Channel | null];\n threadListSync: [data: APIThreadListSync];\n threadMembersUpdate: [data: APIThreadMembersUpdate];\n threadMemberUpdate: [data: APIThreadMember];\n // ── Stage Instances ───────────────────────────────────────────────────────\n stageInstanceCreate: [data: APIStageInstance];\n /** `previous` is the cached stage instance, or `null` if it was not cached. */\n stageInstanceUpdate: [\n data: APIStageInstance,\n previous: APIStageInstance | null,\n ];\n stageInstanceDelete: [data: APIStageInstance];\n // ── Invites ───────────────────────────────────────────────────────────────\n inviteCreate: [data: APIInviteCreate];\n inviteDelete: [data: APIInviteDelete];\n // ── Webhooks ──────────────────────────────────────────────────────────────\n webhooksUpdate: [data: APIWebhooksUpdate];\n // ── Voice ─────────────────────────────────────────────────────────────────\n /** `previous` is the user's last known voice state in that guild, or `null` (first sighting, or not in a guild). */\n voiceStateUpdate: [data: APIVoiceState, previous: APIVoiceState | null];\n voiceServerUpdate: [data: APIVoiceServerUpdate];\n // ── Presence & Typing ─────────────────────────────────────────────────────\n /** `previous` is the last presence seen, available with `cache: { presences: true }`; otherwise `null`. */\n presenceUpdate: [\n data: APIPresenceUpdate,\n previous: APIPresenceUpdate | null,\n ];\n typingStart: [data: APITypingStart];\n // ── Interactions ──────────────────────────────────────────────────────────\n interactionCreate: [interaction: Interaction];\n};\n",
|
|
6
|
+
"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 /** Stop after this many milliseconds without a collected item. */\n idle?: number;\n /** Stop (reason `\"abort\"`) when this signal aborts. */\n signal?: AbortSignal;\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 #idleTimer?: ReturnType<typeof setTimeout>;\n readonly #onAbort = (): void => this.stop(\"abort\");\n /** Cleanup hooks run once when the collector ends (e.g. event unsubscription). */\n readonly #cleanup: (() => void)[] = [];\n\n /** `collect` receives each collected item; `end` the collected map and the reason. */\n public override on(event: \"collect\", listener: (item: V) => void): this;\n public override on(\n event: \"end\",\n listener: (collected: Map<K, V>, reason: string) => void,\n ): this;\n public override on(\n event: string | symbol,\n listener: (...args: never[]) => void,\n ): this;\n public override on(\n event: string | symbol,\n listener: (...args: never[]) => void,\n ): this {\n return super.on(event, listener as (...args: unknown[]) => void);\n }\n /** Like {@link Collector.on}, for one call. */\n public override once(event: \"collect\", listener: (item: V) => void): this;\n public override once(\n event: \"end\",\n listener: (collected: Map<K, V>, reason: string) => void,\n ): this;\n public override once(\n event: string | symbol,\n listener: (...args: never[]) => void,\n ): this;\n public override once(\n event: string | symbol,\n listener: (...args: never[]) => void,\n ): this {\n return super.once(event, listener as (...args: unknown[]) => void);\n }\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 this.#resetIdle();\n if (options.signal?.aborted) this.stop(\"abort\");\n else\n options.signal?.addEventListener(\"abort\", this.#onAbort, {\n once: true,\n });\n }\n\n /** Registers a function to run once when the collector ends. Runs immediately if it already has. */\n public onDispose(cleanup: () => void): this {\n if (this.ended) cleanup();\n else this.#cleanup.push(cleanup);\n return this;\n }\n\n #resetIdle(): void {\n if (!this.options.idle || this.options.idle <= 0) return;\n if (this.#idleTimer) clearTimeout(this.#idleTimer);\n this.#idleTimer = setTimeout(\n () => this.stop(\"idle\"),\n this.options.idle,\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 // `maxProcessed` counts every item the collector *sees*, so it has to be\n // evaluated whether or not the filter accepts this one — checking it only\n // on the accepted path means a collector whose filter rejects everything\n // never reaches its processed limit and runs until `time`/`stop()`.\n const reachedProcessed =\n !!this.options.maxProcessed &&\n this.totalProcessed >= this.options.maxProcessed;\n\n let passed = true;\n if (this.options.filter) passed = !!(await this.options.filter(item));\n\n // The filter may be async, so the collector can have been stopped while\n // it was pending. Anything decided before that stop is discarded rather\n // than collected (and emitted) after \"end\".\n if (this.ended) return false;\n\n if (!passed) {\n if (reachedProcessed) this.stop(\"processedLimit\");\n return false;\n }\n\n this.collected.set(key, item);\n this.#resetIdle();\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 (reachedProcessed) {\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 if (this.#idleTimer) clearTimeout(this.#idleTimer);\n this.options.signal?.removeEventListener(\"abort\", this.#onAbort);\n for (const cleanup of this.#cleanup.splice(0)) {\n try {\n cleanup();\n } catch {\n // A failing cleanup must not stop the others or the \"end\" event.\n }\n }\n this.emit(\"end\", this.collected, reason);\n this.removeAllListeners();\n }\n\n /** Resolves with everything collected once the collector ends. */\n public wait(): Promise<Map<K, V>> {\n if (this.ended) return Promise.resolve(this.collected);\n return new Promise((resolve) =>\n this.once(\"end\", (collected: Map<K, V>) => resolve(collected)),\n );\n }\n\n /** Yields items as they are collected until the collector ends. Items\n * collected between iterations are buffered, not dropped. */\n public async *[Symbol.asyncIterator](): AsyncGenerator<V, void, undefined> {\n const queue: V[] = [];\n let wake: (() => void) | undefined;\n const onCollect = (item: V): void => {\n queue.push(item);\n wake?.();\n };\n const onEnd = (): void => wake?.();\n if (!this.ended) {\n this.on(\"collect\", onCollect);\n this.on(\"end\", onEnd);\n }\n try {\n for (;;) {\n if (queue.length > 0) {\n yield queue.shift()!;\n continue;\n }\n if (this.ended) return;\n await new Promise<void>((resolve) => (wake = resolve));\n wake = undefined;\n }\n } finally {\n this.off(\"collect\", onCollect);\n this.off(\"end\", onEnd);\n }\n }\n\n /** Stops the collector (reason `\"disposed\"`); enables `using collector = ...`. */\n public [Symbol.dispose](): void {\n this.stop(\"disposed\");\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(\n `Collector already ended: ${this.endReason ?? \"unknown\"}`,\n ),\n );\n }\n\n // Each settled next() must drop its counterpart listener. Polling\n // a long-lived collector in a loop otherwise leaves one dangling\n // \"end\" listener per call, which grows without bound and trips the\n // EventEmitter max-listener warning.\n const onCollect = (item: V): void => {\n this.off(\"end\", onEnd);\n resolve(item);\n };\n const onEnd = (_collected: Map<K, V>, reason: string): void => {\n this.off(\"collect\", onCollect);\n reject(\n new Error(\n `Collector ended before item was collected: ${reason}`,\n ),\n );\n };\n\n this.once(\"collect\", onCollect);\n this.once(\"end\", onEnd);\n });\n }\n}\n",
|
|
7
|
+
"/**\n * A shared cache in Redis, beside the in-memory one.\n *\n * The in-memory cache of each process holds the guilds its shards receive.\n * `RedisCache` mirrors the same Gateway events into Redis as raw Discord\n * payloads, so any process — another cluster, a dashboard, a worker without\n * a Gateway — can read any guild. It never replaces the synchronous cache.\n */\n\nimport type { RedisCommandClient } from \"@lunibee/collection\";\n\nexport type { RedisCommandClient };\n\n/** What `attach()` listens to: a `Client` (its `raw` event) or a `Gateway` (`RAW`). */\nexport interface RawDispatchSource {\n // Loose on purpose: Client and Gateway type their events differently.\n // biome-ignore lint/suspicious/noExplicitAny: structural emitter shape\n on(event: any, listener: any): unknown;\n // biome-ignore lint/suspicious/noExplicitAny: structural emitter shape\n off(event: any, listener: any): unknown;\n}\n\n/** Options for {@link RedisCache}. */\nexport interface RedisCacheOptions {\n /** The Redis client. `Bun.RedisClient` works as it is; for ioredis pass `{ send: (c, a) => redis.call(c, ...a) }`. */\n client: RedisCommandClient;\n /** Key prefix. Default `\"lunibee:cache:\"`; keys are versioned under it (`…v1:…`). */\n prefix?: string;\n /** Store members and their users. Default `true`. */\n members?: boolean;\n /** Expire every key this many seconds after its last write. Default: never. */\n ttlSeconds?: number;\n /** Called when a write fails. Writes never throw into the Gateway. */\n onError?: (operation: string, error: unknown) => void;\n}\n\n/** Health of a {@link RedisCache}. */\nexport interface RedisCacheDiagnostics {\n /** Events written. */\n writes: number;\n /** Writes that failed. */\n failures: number;\n /** Events waiting to be written. */\n pending: number;\n}\n\ntype Payload = Record<string, unknown>;\n\n/** Guild fields kept in their own hashes, not in the guild document. */\nconst GUILD_LISTS = [\n \"members\",\n \"channels\",\n \"threads\",\n \"roles\",\n \"presences\",\n \"voice_states\",\n \"stage_instances\",\n \"guild_scheduled_events\",\n \"soundboard_sounds\",\n];\n/** Fields per HSET, so a 100,000-member guild is not one giant command. */\nconst CHUNK = 1000;\n\nconst id = (value: unknown): string | undefined =>\n typeof value === \"string\" && /^\\d{1,20}$/.test(value) ? value : undefined;\n\n/**\n * A Redis mirror of guilds, channels, roles, members and users.\n *\n * ```ts\n * const shared = new RedisCache({ client: new Bun.RedisClient(process.env.REDIS_URL) });\n * shared.attach(client); // or each shard's Gateway\n * const guild = await shared.guild(id); // from any process\n * ```\n *\n * Writes for one guild are applied in Gateway order; a failed write is\n * reported through `onError` and never reaches the Gateway. Reads throw on a\n * Redis error. Values are raw Discord payloads (`APIGuild`-shaped JSON).\n */\nexport class RedisCache {\n readonly #redis: RedisCommandClient;\n readonly #prefix: string;\n readonly #members: boolean;\n readonly #ttl?: number;\n readonly #onError?: RedisCacheOptions[\"onError\"];\n /** Per-guild write chains, so one guild's events land in order. */\n readonly #chains = new Map<string, Promise<void>>();\n readonly #attached = new Map<\n RawDispatchSource,\n { event: string; listener: (payload: never) => void }\n >();\n #writes = 0;\n #failures = 0;\n #pending = 0;\n\n public constructor(options: RedisCacheOptions) {\n this.#redis = options.client;\n this.#prefix = `${options.prefix ?? \"lunibee:cache:\"}v1:`;\n this.#members = options.members ?? true;\n if (\n options.ttlSeconds !== undefined &&\n !(Number.isInteger(options.ttlSeconds) && options.ttlSeconds > 0)\n )\n throw new RangeError(\"ttlSeconds must be a positive integer.\");\n this.#ttl = options.ttlSeconds;\n this.#onError = options.onError;\n }\n\n // ── Wiring ────────────────────────────────────────────────────────────────\n\n /**\n * Mirrors the dispatches of a `Client` (its `raw` event) or of one\n * `Gateway` (`RAW`). Attach each shard's Gateway, or the client once.\n */\n public attach(source: RawDispatchSource): this {\n if (this.#attached.has(source)) return this;\n const event = \"gateway\" in (source as object) ? \"raw\" : \"RAW\";\n const listener = (payload: never): void => {\n const { event: name, data } = payload as {\n event?: string;\n data?: unknown;\n };\n if (typeof name === \"string\") this.handle(name, data);\n };\n source.on(event, listener);\n this.#attached.set(source, { event, listener });\n return this;\n }\n\n /** Stops mirroring `source` (or every source). */\n public detach(source?: RawDispatchSource): this {\n for (const [s, { event, listener }] of this.#attached)\n if (!source || s === source) {\n s.off(event, listener);\n this.#attached.delete(s);\n }\n return this;\n }\n\n /** Resolves when every write queued so far has been applied (or failed). */\n public async flush(): Promise<void> {\n while (this.#chains.size > 0)\n await Promise.all([...this.#chains.values()]);\n }\n\n public diagnostics(): RedisCacheDiagnostics {\n return {\n writes: this.#writes,\n failures: this.#failures,\n pending: this.#pending,\n };\n }\n\n /**\n * Applies one Gateway dispatch. `attach()` calls it; call it yourself to\n * feed events from elsewhere (an IPC relay, a replay).\n */\n public handle(event: string, data: unknown): void {\n if (!data || typeof data !== \"object\") return;\n const d = data as Payload;\n // Users are shared by every guild: their writes go on one chain, in\n // Gateway order, so a member event of one guild cannot overwrite a\n // newer user written from another.\n const users = this.#usersOf(event, d);\n if (users.length)\n this.#enqueue(\"users\", event, async () => {\n for (const user of users)\n await this.#setJSON(\n this.#k(\"user\", user.id as string),\n user,\n );\n });\n const write = this.#writer(event, d);\n if (!write) return;\n const guild = id(d.guild_id) ?? id(d.id) ?? \"-\";\n // USER_UPDATE and the like have no guild; they share one chain.\n const key = event.startsWith(\"GUILD_\") || d.guild_id ? guild : \"-\";\n this.#enqueue(key, event, write);\n }\n\n #usersOf(event: string, d: Payload): Payload[] {\n const list: unknown[] =\n event === \"USER_UPDATE\"\n ? [d]\n : !this.#members\n ? []\n : event === \"GUILD_CREATE\" || event === \"GUILD_MEMBERS_CHUNK\"\n ? ((d.members as Payload[] | undefined) ?? []).map(\n (m) => m?.user,\n )\n : event === \"GUILD_MEMBER_ADD\" ||\n event === \"GUILD_MEMBER_UPDATE\"\n ? [d.user]\n : [];\n return list.filter(\n (u): u is Payload =>\n !!u && typeof u === \"object\" && !!id((u as Payload).id),\n );\n }\n\n #enqueue(key: string, event: string, write: () => Promise<void>): void {\n this.#pending++;\n const previous = this.#chains.get(key) ?? Promise.resolve();\n const next = previous.then(async () => {\n try {\n await write();\n this.#writes++;\n } catch (error) {\n this.#failures++;\n try {\n this.#onError?.(event, error);\n } catch {\n // Diagnostics never break the Gateway.\n }\n } finally {\n this.#pending--;\n }\n });\n this.#chains.set(key, next);\n void next.then(() => {\n if (this.#chains.get(key) === next) this.#chains.delete(key);\n });\n }\n\n // ── Keys and commands ─────────────────────────────────────────────────────\n\n #k(...parts: string[]): string {\n return this.#prefix + parts.join(\":\");\n }\n\n async #cmd(command: string, ...args: string[]): Promise<unknown> {\n return this.#redis.send(command, args);\n }\n\n async #setJSON(key: string, value: unknown): Promise<void> {\n const args = [key, JSON.stringify(value)];\n if (this.#ttl) args.push(\"EX\", String(this.#ttl));\n await this.#redis.send(\"SET\", args);\n }\n\n async #touch(key: string): Promise<void> {\n if (this.#ttl) await this.#cmd(\"EXPIRE\", key, String(this.#ttl));\n }\n\n async #hset(key: string, entries: Array<[string, unknown]>): Promise<void> {\n for (let i = 0; i < entries.length; i += CHUNK) {\n const args: string[] = [key];\n for (const [field, value] of entries.slice(i, i + CHUNK))\n args.push(field, JSON.stringify(value));\n await this.#redis.send(\"HSET\", args);\n }\n if (entries.length) await this.#touch(key);\n }\n\n async #channel(channel: Payload, guildId?: string): Promise<void> {\n const channelId = id(channel.id);\n if (!channelId) return;\n const value = guildId ? { ...channel, guild_id: guildId } : channel;\n await this.#setJSON(this.#k(\"channel\", channelId), value);\n if (guildId)\n await this.#hset(this.#k(\"guild\", guildId, \"channels\"), [\n [channelId, value],\n ]);\n }\n\n async #member(guildId: string, member: Payload): Promise<void> {\n if (!this.#members) return;\n const userId = id((member.user as Payload | undefined)?.id);\n if (!userId) return;\n const { user: _user, ...rest } = member;\n await this.#hset(this.#k(\"guild\", guildId, \"members\"), [\n [userId, { ...rest, user_id: userId }],\n ]);\n }\n\n async #dropGuild(guildId: string): Promise<void> {\n const channels = (await this.#cmd(\n \"HKEYS\",\n this.#k(\"guild\", guildId, \"channels\"),\n )) as string[] | null;\n const keys = [\n this.#k(\"guild\", guildId),\n this.#k(\"guild\", guildId, \"channels\"),\n this.#k(\"guild\", guildId, \"roles\"),\n this.#k(\"guild\", guildId, \"members\"),\n ...(channels ?? []).map((c) => this.#k(\"channel\", c)),\n ];\n await this.#redis.send(\"DEL\", keys);\n await this.#cmd(\"SREM\", this.#k(\"guilds\"), guildId);\n }\n\n async #patchGuild(guildId: string, patch: Payload): Promise<void> {\n const current = await this.guild(guildId);\n if (!current) return;\n await this.#setJSON(this.#k(\"guild\", guildId), {\n ...current,\n ...patch,\n });\n }\n\n // ── Event handlers ────────────────────────────────────────────────────────\n\n #writer(event: string, d: Payload): (() => Promise<void>) | undefined {\n const guildId = id(d.guild_id);\n switch (event) {\n case \"GUILD_CREATE\":\n case \"GUILD_UPDATE\":\n return async () => {\n const gid = id(d.id);\n if (!gid) return;\n const doc: Payload = {};\n for (const [k, v] of Object.entries(d))\n if (!GUILD_LISTS.includes(k)) doc[k] = v;\n if (event === \"GUILD_CREATE\") {\n // A fresh snapshot replaces whatever was stored.\n await this.#dropGuild(gid);\n await this.#hset(\n this.#k(\"guild\", gid, \"roles\"),\n ((d.roles as Payload[]) ?? [])\n .filter((r) => id(r.id))\n .map((r) => [r.id as string, r]),\n );\n for (const c of [\n ...((d.channels as Payload[]) ?? []),\n ...((d.threads as Payload[]) ?? []),\n ])\n await this.#channel(c, gid);\n if (this.#members) {\n const members = (\n (d.members as Payload[]) ?? []\n ).filter((m) =>\n id((m.user as Payload | undefined)?.id),\n );\n await this.#hset(\n this.#k(\"guild\", gid, \"members\"),\n members.map((m) => {\n const { user, ...rest } = m;\n const uid = (user as Payload).id as string;\n return [uid, { ...rest, user_id: uid }];\n }),\n );\n }\n await this.#setJSON(this.#k(\"guild\", gid), doc);\n } else {\n if (Array.isArray(d.roles))\n await this.#hset(\n this.#k(\"guild\", gid, \"roles\"),\n (d.roles as Payload[])\n .filter((r) => id(r.id))\n .map((r) => [r.id as string, r]),\n );\n const current = await this.guild(gid);\n await this.#setJSON(this.#k(\"guild\", gid), {\n ...current,\n ...doc,\n });\n }\n await this.#cmd(\"SADD\", this.#k(\"guilds\"), gid);\n };\n case \"GUILD_DELETE\":\n return async () => {\n const gid = id(d.id);\n if (!gid) return;\n // An outage keeps the data; leaving or a kick drops it.\n if (d.unavailable === true)\n await this.#patchGuild(gid, { unavailable: true });\n else await this.#dropGuild(gid);\n };\n case \"CHANNEL_CREATE\":\n case \"CHANNEL_UPDATE\":\n case \"THREAD_CREATE\":\n case \"THREAD_UPDATE\":\n return () => this.#channel(d, guildId);\n case \"CHANNEL_DELETE\":\n case \"THREAD_DELETE\":\n return async () => {\n const channelId = id(d.id);\n if (!channelId) return;\n await this.#cmd(\"DEL\", this.#k(\"channel\", channelId));\n if (guildId)\n await this.#cmd(\n \"HDEL\",\n this.#k(\"guild\", guildId, \"channels\"),\n channelId,\n );\n };\n case \"GUILD_ROLE_CREATE\":\n case \"GUILD_ROLE_UPDATE\":\n return async () => {\n const role = d.role as Payload | undefined;\n if (!guildId || !role || !id(role.id)) return;\n await this.#hset(this.#k(\"guild\", guildId, \"roles\"), [\n [role.id as string, role],\n ]);\n };\n case \"GUILD_ROLE_DELETE\":\n return async () => {\n const roleId = id(d.role_id);\n if (!guildId || !roleId) return;\n await this.#cmd(\n \"HDEL\",\n this.#k(\"guild\", guildId, \"roles\"),\n roleId,\n );\n };\n case \"GUILD_MEMBER_ADD\":\n case \"GUILD_MEMBER_UPDATE\":\n return async () => {\n if (!guildId) return;\n if (event === \"GUILD_MEMBER_UPDATE\" && this.#members) {\n // An update carries a partial member: merge it.\n const userId = id((d.user as Payload | undefined)?.id);\n const current = userId\n ? await this.#hget<Payload>(\n this.#k(\"guild\", guildId, \"members\"),\n userId,\n )\n : undefined;\n await this.#member(guildId, { ...current, ...d });\n } else await this.#member(guildId, d);\n };\n case \"GUILD_MEMBER_REMOVE\":\n return async () => {\n const userId = id((d.user as Payload | undefined)?.id);\n if (!guildId || !userId || !this.#members) return;\n await this.#cmd(\n \"HDEL\",\n this.#k(\"guild\", guildId, \"members\"),\n userId,\n );\n };\n case \"GUILD_MEMBERS_CHUNK\":\n return async () => {\n if (!guildId) return;\n for (const m of (d.members as Payload[]) ?? [])\n await this.#member(guildId, m);\n };\n case \"GUILD_EMOJIS_UPDATE\":\n return async () => {\n if (guildId)\n await this.#patchGuild(guildId, { emojis: d.emojis });\n };\n case \"GUILD_STICKERS_UPDATE\":\n return async () => {\n if (guildId)\n await this.#patchGuild(guildId, {\n stickers: d.stickers,\n });\n };\n default:\n return undefined;\n }\n }\n\n // ── Reads ─────────────────────────────────────────────────────────────────\n\n async #get<T>(key: string): Promise<T | undefined> {\n const raw = (await this.#cmd(\"GET\", key)) as string | null;\n return raw ? (JSON.parse(raw) as T) : undefined;\n }\n\n async #hget<T>(key: string, field: string): Promise<T | undefined> {\n const raw = (await this.#cmd(\"HGET\", key, field)) as string | null;\n return raw ? (JSON.parse(raw) as T) : undefined;\n }\n\n async #hvals<T>(key: string): Promise<T[]> {\n const raw = ((await this.#cmd(\"HVALS\", key)) as string[] | null) ?? [];\n return raw.map((v) => JSON.parse(v) as T);\n }\n\n /** The guild document (without its channels, roles and members). */\n public guild<T extends object = Payload>(\n guildId: string,\n ): Promise<T | undefined> {\n return this.#get<T>(this.#k(\"guild\", guildId));\n }\n\n /** Ids of every guild in the cache. */\n public async guildIds(): Promise<string[]> {\n return (\n ((await this.#cmd(\"SMEMBERS\", this.#k(\"guilds\"))) as\n string[] | null) ?? []\n );\n }\n\n /** A channel or thread, with its `guild_id`. */\n public channel<T extends object = Payload>(\n channelId: string,\n ): Promise<T | undefined> {\n return this.#get<T>(this.#k(\"channel\", channelId));\n }\n\n /** Every channel and thread of a guild. */\n public channels<T extends object = Payload>(guildId: string): Promise<T[]> {\n return this.#hvals<T>(this.#k(\"guild\", guildId, \"channels\"));\n }\n\n public role<T extends object = Payload>(\n guildId: string,\n roleId: string,\n ): Promise<T | undefined> {\n return this.#hget<T>(this.#k(\"guild\", guildId, \"roles\"), roleId);\n }\n\n public roles<T extends object = Payload>(guildId: string): Promise<T[]> {\n return this.#hvals<T>(this.#k(\"guild\", guildId, \"roles\"));\n }\n\n public user<T extends object = Payload>(\n userId: string,\n ): Promise<T | undefined> {\n return this.#get<T>(this.#k(\"user\", userId));\n }\n\n /** A member, with its `user` attached. */\n public async member<T extends object = Payload>(\n guildId: string,\n userId: string,\n ): Promise<T | undefined> {\n const member = await this.#hget<Payload>(\n this.#k(\"guild\", guildId, \"members\"),\n userId,\n );\n if (!member) return undefined;\n return { ...member, user: await this.user(userId) } as T;\n }\n\n /** Every cached member of a guild, with users. Large guilds: mind the size. */\n public async members<T extends object = Payload>(\n guildId: string,\n ): Promise<T[]> {\n const members = await this.#hvals<Payload>(\n this.#k(\"guild\", guildId, \"members\"),\n );\n if (members.length === 0) return [];\n const users = (await this.#redis.send(\n \"MGET\",\n members.map((m) => this.#k(\"user\", String(m.user_id))),\n )) as Array<string | null>;\n return members.map((m, i) => ({\n ...m,\n user: users[i] ? JSON.parse(users[i]!) : undefined,\n })) as T[];\n }\n}\n",
|
|
8
|
+
"import type { APIBan } from \"@lunibee/managers\";\nimport type { REST, RESTFileAttachment } from \"@lunibee/rest\";\nimport type {\n APIApplicationCommand,\n APIAuditLog,\n APIChannel,\n APIEmoji,\n APIGuild,\n APIGuildMember,\n APIInvite,\n APIMessage,\n APIOverwrite,\n APIRole,\n APIThreadMember,\n APIWebhook,\n UserData,\n} from \"@lunibee/types\";\n\n/** What goes in a path where Discord wants an id: a snowflake, `\"@me\"`, an invite code, an emoji. */\nexport type RouteId = string | number | bigint;\n\n/** Extra settings for one request. */\nexport interface RouteOptions {\n /** Appended to the URL: `{ limit: 50 }`. Undefined values are left out. */\n query?: Record<string, string | number | boolean | undefined>;\n /** The audit-log reason, sent as `X-Audit-Log-Reason`. */\n reason?: string;\n /** Cancels the request, and any wait for a rate limit. */\n signal?: AbortSignal;\n /** Files to upload; the body is sent as multipart. */\n files?: RESTFileAttachment[];\n}\n\n/** How a list is paged. Each route has its own defaults; set only what you need to change. */\nexport interface PageOptions<Item = unknown> extends Pick<\n RouteOptions,\n \"signal\"\n> {\n /** Items per request. */\n limit?: number;\n /** Which end the next page starts from: after the last id, or before it. */\n cursor?: \"after\" | \"before\";\n /** Where to start: an id. */\n start?: string;\n /** Other query parameters sent with every page. */\n query?: RouteOptions[\"query\"];\n /** How to read an item's id, when it is not `id` or `user.id`. */\n idOf?: (item: Item) => string;\n}\n\n/**\n * A place in Discord's REST API. Send a request with `get`, `post`, `put`,\n * `patch` or `delete`. `Read` is what `get` returns; `Write` is what `post`\n * and `patch` return (the same, except on a list, where posting makes one item).\n */\nexport interface Route<Read = unknown, Write = Read> {\n /** The path this route stands for, such as `/guilds/123/members`. */\n readonly path: string;\n get<R = Read>(options?: RouteOptions): Promise<R>;\n post<R = Write>(body?: unknown, options?: RouteOptions): Promise<R>;\n put<R = void>(body?: unknown, options?: RouteOptions): Promise<R>;\n patch<R = Write>(body?: unknown, options?: RouteOptions): Promise<R>;\n delete<R = void>(options?: RouteOptions): Promise<R>;\n}\n\n/** A route that lists things and can follow its pages. */\nexport interface ListRoute<Item> extends Route<Item[], Item> {\n /** Yields one page at a time, following the cursor until the list ends. */\n pages(options?: PageOptions<Item>): AsyncGenerator<Item[], void>;\n /**\n * Collects pages into one array.\n * @param options.max Stop after this many items (10,000 by default).\n */\n all(options?: PageOptions<Item> & { max?: number }): Promise<Item[]>;\n}\n\ntype Pick1<N> = (id: RouteId) => N;\n\nexport interface MessageNode extends Route<APIMessage> {\n crosspost: Route<APIMessage>;\n /** `reactions(emoji)` lists who reacted; `reactions(emoji)(\"@me\")` is the bot's own reaction. */\n reactions: ListRoute<UserData> &\n ((emoji: string) => ListRoute<UserData> & Pick1<Route>);\n}\nexport interface MessagesRoute extends ListRoute<APIMessage> {\n (id: RouteId): MessageNode;\n bulkDelete: Route;\n}\nexport interface ChannelNode extends Route<APIChannel> {\n messages: MessagesRoute;\n typing: Route;\n invites: ListRoute<APIInvite>;\n webhooks: ListRoute<APIWebhook>;\n /** Permission overwrites, by role or user id. */\n permissions: Pick1<Route<APIOverwrite>>;\n threadMembers: ListRoute<APIThreadMember> & Pick1<Route<APIThreadMember>>;\n}\nexport interface MemberNode extends Route<APIGuildMember> {\n /** `roles(roleId).put()` adds the role; `.delete()` takes it away. */\n roles: Pick1<Route>;\n}\nexport interface MembersRoute extends ListRoute<APIGuildMember> {\n (userId: RouteId): MemberNode;\n search: Route<APIGuildMember[]>;\n}\nexport interface GuildNode extends Route<APIGuild> {\n channels: Route<APIChannel[], APIChannel>;\n members: MembersRoute;\n roles: ListRoute<APIRole> & Pick1<Route<APIRole>>;\n bans: ListRoute<APIBan> & Pick1<Route<APIBan>>;\n emojis: ListRoute<APIEmoji> & Pick1<Route<APIEmoji>>;\n invites: ListRoute<APIInvite>;\n webhooks: ListRoute<APIWebhook>;\n auditLogs: Route<APIAuditLog>;\n preview: Route;\n}\nexport interface UserNode extends Route<UserData> {\n /** The guilds a user is in (`users(\"@me\").guilds`); `guilds(id).delete()` leaves one. */\n guilds: ListRoute<APIGuild> & Pick1<Route>;\n /** `channels.post({ recipient_id })` opens a direct message. */\n channels: Route<APIChannel>;\n}\nexport interface ApplicationNode extends Route {\n commands: ListRoute<APIApplicationCommand> &\n Pick1<Route<APIApplicationCommand>>;\n /** Commands of one guild. */\n guilds: Pick1<{\n commands: ListRoute<APIApplicationCommand> &\n Pick1<Route<APIApplicationCommand>>;\n }>;\n}\n/** `webhooks(id)` is the webhook; `webhooks(id)(token)` is its execute route, with `messages(id)` inside. */\nexport type WebhookNode = Route<APIWebhook> &\n ((token: string) => Route<APIMessage> & {\n messages: Pick1<Route<APIMessage>>;\n });\n\n/**\n * Discord's REST API as a path you build by chaining: a name goes one level\n * down, a call with an id goes into that item, and a method sends. Names are\n * the route words in camelCase (`auditLogs` is `/audit-logs`).\n * @example await bot.api.guilds(guildId).members(userId).patch({ nick: \"x\" }, { reason: \"rename\" });\n * @example for await (const page of bot.api.guilds(guildId).members.pages()) { … }\n */\nexport interface Api {\n guilds: Pick1<GuildNode>;\n channels: Pick1<ChannelNode>;\n users: Pick1<UserNode>;\n applications: Pick1<ApplicationNode>;\n webhooks: Pick1<WebhookNode>;\n invites: Pick1<Route<APIInvite>>;\n /** Any route not listed above: `bot.api.to(\"stage-instances\", id)`. */\n to(...segments: RouteId[]): Route;\n}\n\n// ─── Runtime ─────────────────────────────────────────────────────────────────\n\nconst SAFE_WORD = /^[a-z][a-zA-Z0-9]*$/;\nconst SAFE_SEGMENT = /^[A-Za-z0-9_@.%-]+$/;\n\n/** Page defaults of the routes whose lists Discord pages in its own way. */\nconst PAGING: Record<\n string,\n {\n limit: number;\n cursor: \"after\" | \"before\";\n idOf?: (item: never) => string;\n }\n> = {\n members: {\n limit: 1000,\n cursor: \"after\",\n idOf: (member: APIGuildMember) => member.user.id,\n },\n bans: {\n limit: 1000,\n cursor: \"after\",\n idOf: (ban: APIBan) => ban.user.id,\n },\n messages: { limit: 100, cursor: \"before\" },\n guilds: { limit: 200, cursor: \"after\" },\n};\nconst DEFAULT_PAGING = { limit: 100, cursor: \"after\" as const };\nconst DEFAULT_MAX = 10_000;\n\nfunction kebab(word: string): string {\n return word.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`);\n}\n\nfunction idSegment(id: unknown): string {\n if (\n typeof id !== \"string\" &&\n typeof id !== \"number\" &&\n typeof id !== \"bigint\"\n )\n throw new TypeError(\"A route id must be a string, number or bigint.\");\n const text = String(id);\n if (text === \"\") throw new TypeError(\"A route id cannot be empty.\");\n return encodeURIComponent(text).replace(/%40/g, \"@\");\n}\n\nfunction defaultId(item: unknown): string {\n const record = item as { id?: unknown; user?: { id?: unknown } };\n const id = record?.id ?? record?.user?.id;\n if (typeof id !== \"string\")\n throw new TypeError(\n \"Cannot find an id on a page item; pass idOf to pages().\",\n );\n return id;\n}\n\nfunction node(rest: REST, segments: readonly string[]): unknown {\n const path = `/${segments.join(\"/\")}`;\n const send =\n (method: string, hasBody: boolean) =>\n (first?: unknown, second?: RouteOptions) =>\n rest.request(\n method,\n path,\n hasBody ? first : undefined,\n (hasBody ? second : (first as RouteOptions | undefined)) ?? {},\n );\n const last = segments[segments.length - 1] ?? \"\";\n const pages = async function* (\n options: PageOptions<unknown> = {},\n ): AsyncGenerator<unknown[], void> {\n const paging = { ...DEFAULT_PAGING, ...PAGING[last] };\n const cursorName = options.cursor ?? paging.cursor;\n const limit = options.limit ?? paging.limit;\n const idOf =\n options.idOf ??\n (paging.idOf as ((item: unknown) => string) | undefined) ??\n defaultId;\n let cursor = options.start;\n for (;;) {\n const batch = await rest.request<unknown[]>(\n \"GET\",\n path,\n undefined,\n {\n signal: options.signal,\n query: {\n ...options.query,\n limit,\n ...(cursor === undefined\n ? {}\n : { [cursorName]: cursor }),\n },\n },\n );\n if (!Array.isArray(batch) || batch.length === 0) return;\n yield batch;\n if (batch.length < limit) return;\n cursor = idOf(batch[batch.length - 1]);\n }\n };\n const all = async (\n options: PageOptions<unknown> & { max?: number } = {},\n ): Promise<unknown[]> => {\n const max = options.max ?? DEFAULT_MAX;\n const paging = { ...DEFAULT_PAGING, ...PAGING[last] };\n const items: unknown[] = [];\n if (max <= 0) return items;\n for await (const page of pages({\n ...options,\n limit: Math.min(options.limit ?? paging.limit, max),\n })) {\n items.push(...page);\n if (items.length >= max) break;\n }\n return items.slice(0, max);\n };\n const members: Record<string, unknown> = {\n path,\n get: send(\"GET\", false),\n post: send(\"POST\", true),\n put: send(\"PUT\", true),\n patch: send(\"PATCH\", true),\n delete: send(\"DELETE\", false),\n pages,\n all,\n toString: () => path,\n };\n return new Proxy(function route() {}, {\n get(_target, property) {\n if (typeof property !== \"string\") return undefined;\n if (property in members) return members[property];\n // `then` stays undefined so awaiting a route cannot hang.\n if (property === \"then\" || !SAFE_WORD.test(property))\n return undefined;\n return node(rest, [...segments, kebab(property)]);\n },\n apply(_target, _this, args: unknown[]) {\n if (args.length !== 1)\n throw new TypeError(\n `Call a route with exactly one id, e.g. ${path}(id).`,\n );\n return node(rest, [...segments, idSegment(args[0])]);\n },\n });\n}\n\n/** Builds `bot.api` over a REST client. */\nexport function createApi(rest: REST): Api {\n const root = node(rest, []) as Record<string, unknown>;\n return new Proxy(root, {\n get(target, property, receiver) {\n if (property === \"to\")\n return (...segments: RouteId[]): Route => {\n if (segments.length === 0)\n throw new TypeError(\"to() needs at least one segment.\");\n const cleaned = segments.map((segment) => {\n const text = String(segment);\n if (!SAFE_SEGMENT.test(text))\n throw new TypeError(\n `Invalid route segment: ${JSON.stringify(text)}.`,\n );\n return text;\n });\n return node(rest, cleaned) as Route;\n };\n return Reflect.get(target, property, receiver);\n },\n }) as unknown as Api;\n}\n",
|
|
9
|
+
"import {\n CreateAttachmentOption,\n CreateBooleanOption,\n CreateChannelOption,\n CreateIntegerOption,\n CreateMentionableOption,\n CreateNumberOption,\n CreateRoleOption,\n CreateSlashCommand,\n CreateStringOption,\n CreateUserOption,\n type CreateCommandOption,\n} from \"@lunibee/builders\";\nimport type { InteractionReplyOptions } from \"@lunibee/structures\";\nimport type {\n CommandInteraction,\n GuildMember,\n Message,\n} from \"@lunibee/structures\";\nimport {\n ChannelKinds,\n resolveGatewayIntents,\n type APIAttachment,\n type ChannelKind,\n} from \"@lunibee/types\";\nimport {\n parsePrefixArgs,\n type PrefixArgSpec,\n type PrefixArgType,\n type PrefixArgValue,\n} from \"@lunibee/utils\";\nimport { PermissionSet, type PermissionName } from \"./permissions.js\";\nimport type { Client } from \"./index.js\";\n\n// ─── Options ─────────────────────────────────────────────────────────────────\n\n/** What every option takes. */\ninterface OptionConfig {\n /** Shown in Discord's command picker (1-100 characters). Defaults to the option's name. */\n description?: string;\n /** Whether the command cannot run without it. */\n required?: boolean;\n}\n\n/** A string option. */\nexport interface StringConfig extends OptionConfig {\n default?: string;\n /** Shortest and longest accepted text. */\n min?: number;\n max?: number;\n /** Allowed values, as plain text or `{ name, value }` pairs. */\n choices?: readonly (string | { name: string; value: string })[];\n}\n\n/** An integer or number option. */\nexport interface NumberConfig extends OptionConfig {\n default?: number;\n /** Smallest and largest accepted value. */\n min?: number;\n max?: number;\n choices?: readonly (number | { name: string; value: number })[];\n}\n\n/** A true/false option. */\nexport interface BooleanConfig extends OptionConfig {\n default?: boolean;\n}\n\n/** A channel option. */\nexport interface ChannelConfig extends OptionConfig {\n /** Only these kinds of channel are accepted (all by default). */\n kinds?: readonly ChannelKind[];\n}\n\n/** A choice between fixed words. */\nexport interface ChoiceConfig<V extends string> extends OptionConfig {\n default?: V;\n}\n\n/** Which option kind a definition is. */\ntype OptionKind =\n | \"string\"\n | \"integer\"\n | \"number\"\n | \"boolean\"\n | \"user\"\n | \"channel\"\n | \"role\"\n | \"mentionable\"\n | \"attachment\";\n\n/** A mention or id that can be either a user or a role. */\nexport interface MentionableValue {\n id: string;\n type: \"user\" | \"role\";\n}\n\n/**\n * One option of a command. `T` is the type the handler receives and `C` the\n * configuration it was made with, which decides whether it can be missing.\n * Make one with {@link option}.\n */\nexport interface OptionDef<T, C> {\n readonly kind: OptionKind;\n readonly config: C;\n /** Choices for {@link option.choice}; undefined for the other kinds. */\n readonly words?: readonly string[];\n /** Type only: the type the handler receives. Never present at runtime. */\n readonly __type: T;\n}\n\ntype AnyOption = OptionDef<unknown, object>;\n\n/** The settings every option kind shares, whatever its own configuration adds. */\nfunction settings(def: AnyOption): OptionConfig & { default?: unknown } {\n return def.config as OptionConfig & { default?: unknown };\n}\n/** The options of a command, by name. */\nexport type OptionMap = Record<string, AnyOption>;\n\nfunction define<T, C extends object>(\n kind: OptionKind,\n config: C | undefined,\n words?: readonly string[],\n): OptionDef<T, C> {\n return { kind, config: config ?? ({} as C), words } as OptionDef<T, C>;\n}\n\n/**\n * Describes the options of a command. The key you give each one in\n * `command({ options })` is its name; the handler gets them typed.\n *\n * - An option is required when `required: true`, and also never missing when it has a `default`.\n * - `user`, `role` and `channel` give the id; `mentionable` gives `{ id, type }`;\n * `attachment` gives the attachment.\n */\nexport const option = {\n string: <const C extends StringConfig>(config?: C) =>\n define<string, C>(\"string\", config),\n integer: <const C extends NumberConfig>(config?: C) =>\n define<number, C>(\"integer\", config),\n number: <const C extends NumberConfig>(config?: C) =>\n define<number, C>(\"number\", config),\n boolean: <const C extends BooleanConfig>(config?: C) =>\n define<boolean, C>(\"boolean\", config),\n user: <const C extends OptionConfig>(config?: C) =>\n define<string, C>(\"user\", config),\n role: <const C extends OptionConfig>(config?: C) =>\n define<string, C>(\"role\", config),\n channel: <const C extends ChannelConfig>(config?: C) =>\n define<string, C>(\"channel\", config),\n mentionable: <const C extends OptionConfig>(config?: C) =>\n define<MentionableValue, C>(\"mentionable\", config),\n attachment: <const C extends OptionConfig>(config?: C) =>\n define<APIAttachment, C>(\"attachment\", config),\n /** A choice between fixed words; the handler gets the word, typed as the union. */\n choice: <\n const W extends readonly string[],\n const C extends ChoiceConfig<W[number]>,\n >(\n words: W,\n config?: C,\n ) => define<W[number], C>(\"string\", config, words),\n};\n\ntype IsNeeded<C> = C extends { required: true }\n ? true\n : C extends { default: string | number | boolean }\n ? true\n : false;\n\ntype ValueOf<D> = D extends OptionDef<infer T, unknown> ? T : never;\ntype ConfigOf<D> = D extends OptionDef<unknown, infer C> ? C : never;\ntype RequiredKeys<M extends OptionMap> = {\n [K in keyof M]: IsNeeded<ConfigOf<M[K]>> extends true ? K : never;\n}[keyof M];\n\n/** The values a handler receives: required (or defaulted) options always, the rest possibly missing. */\nexport type OptionValues<M extends OptionMap> = {\n [K in RequiredKeys<M>]: ValueOf<M[K]>;\n} & {\n [K in Exclude<keyof M, RequiredKeys<M>>]?: ValueOf<M[K]>;\n};\n\n// ─── Commands ────────────────────────────────────────────────────────────────\n\n/** What a command handler gets, whether it was run as `/name` or as `!name`. */\nexport interface CommandContext<M extends OptionMap = OptionMap> {\n bot: Client;\n /** The command's options, typed from its definition. */\n options: OptionValues<M>;\n /** How it was run. */\n source: \"slash\" | \"prefix\";\n guildId: string | undefined;\n channelId: string | undefined;\n /** The id of whoever ran it. */\n userId: string;\n /** The person who ran it as a guild member, when it ran in a guild. */\n member: GuildMember | null;\n /** The slash interaction, when `source` is `\"slash\"`. */\n interaction: CommandInteraction | undefined;\n /** The message, when `source` is `\"prefix\"`. */\n message: Message | undefined;\n /**\n * Answers the command: an interaction reply for a slash command (a first\n * reply, an edit after `defer()`, then follow-ups), a message reply for a\n * prefix command. `ephemeral` only means something for slash commands.\n */\n reply(content: string | InteractionReplyOptions): Promise<void>;\n /** Tells Discord the answer will take a while (slash commands only; a no-op for prefix commands). */\n defer(options?: { ephemeral?: boolean }): Promise<void>;\n}\n\n/** The definition `command()` takes. */\nexport interface CommandDefinition<M extends OptionMap> {\n /** 1-32 lowercase letters, digits, `-` or `_`. */\n name: string;\n /** 1-100 characters. */\n description: string;\n options?: M;\n /** Permissions the person needs; checked by Discord for slash commands and by Lunibee for prefix commands. Implies `guildOnly`. */\n permissions?: readonly PermissionName[];\n /** Only allow it in servers. */\n guildOnly?: boolean;\n nsfw?: boolean;\n /** Answer `!name args` too, with the same options; `{ aliases }` adds other names. */\n prefix?: boolean | { aliases?: readonly string[] };\n /** Register it as a slash command (default `true`); `false` makes a prefix-only command. */\n slash?: boolean;\n run(context: CommandContext<M>): unknown;\n}\n\n/** A command made by {@link command}. */\nexport interface Command<M extends OptionMap = OptionMap> {\n readonly name: string;\n readonly description: string;\n readonly options: M;\n readonly permissions: readonly PermissionName[];\n readonly guildOnly: boolean;\n readonly nsfw: boolean;\n /** Whether it is registered as a slash command. */\n readonly slash: boolean;\n /** Whether it answers a prefix, and under which other names. */\n readonly prefix: false | { aliases: readonly string[] };\n run(context: CommandContext<M>): unknown;\n /** The slash command as Discord expects it. */\n toJSON(): Record<string, unknown>;\n /** The usage line of the prefix form, such as `!timeout <user> [minutes] [reason…]`. */\n usage(prefix: string): string;\n}\n\nconst COMMAND_NAME = /^[-_\\p{Ll}\\p{Lo}\\p{N}\\p{sc=Deva}\\p{sc=Thai}]{1,32}$/u;\n\nconst channelTypes = (kinds: readonly ChannelKind[]): number[] => [\n ...new Set(kinds.flatMap((kind) => ChannelKinds[kind])),\n];\n\n/** Names an option builder and applies what every option shares. */\nfunction named<B extends CreateCommandOption>(\n builder: B,\n name: string,\n def: AnyOption,\n): B {\n const config = settings(def);\n return builder\n .setName(name)\n .setDescription(config.description ?? name)\n .setRequired(config.required === true);\n}\n\n/** Adds one option definition to a slash command builder. */\nfunction addOptionTo(\n slash: CreateSlashCommand,\n name: string,\n def: AnyOption,\n): void {\n switch (def.kind) {\n case \"string\": {\n const config = def.config as StringConfig;\n const text = named(new CreateStringOption(), name, def);\n if (config.min !== undefined) text.setMinLength(config.min);\n if (config.max !== undefined) text.setMaxLength(config.max);\n const choices = def.words ?? config.choices;\n if (choices?.length)\n text.addChoices(\n ...choices.map((choice) =>\n typeof choice === \"string\"\n ? { name: choice, value: choice }\n : choice,\n ),\n );\n slash.addStringOption(() => text);\n break;\n }\n case \"integer\":\n case \"number\": {\n const config = def.config as NumberConfig;\n const numeric = named(\n def.kind === \"integer\"\n ? new CreateIntegerOption()\n : new CreateNumberOption(),\n name,\n def,\n );\n if (config.min !== undefined) numeric.setMinValue(config.min);\n if (config.max !== undefined) numeric.setMaxValue(config.max);\n if (config.choices?.length)\n numeric.addChoices(\n ...config.choices.map((choice) =>\n typeof choice === \"number\"\n ? { name: String(choice), value: choice }\n : choice,\n ),\n );\n if (def.kind === \"integer\")\n slash.addIntegerOption(() => numeric as CreateIntegerOption);\n else slash.addNumberOption(() => numeric as CreateNumberOption);\n break;\n }\n case \"boolean\":\n slash.addBooleanOption(() =>\n named(new CreateBooleanOption(), name, def),\n );\n break;\n case \"user\":\n slash.addUserOption(() => named(new CreateUserOption(), name, def));\n break;\n case \"role\":\n slash.addRoleOption(() => named(new CreateRoleOption(), name, def));\n break;\n case \"mentionable\":\n slash.addMentionableOption(() =>\n named(new CreateMentionableOption(), name, def),\n );\n break;\n case \"attachment\":\n slash.addAttachmentOption(() =>\n named(new CreateAttachmentOption(), name, def),\n );\n break;\n case \"channel\": {\n const config = def.config as ChannelConfig;\n const channel = named(new CreateChannelOption(), name, def);\n if (config.kinds?.length)\n channel.addChannelTypes(...channelTypes(config.kinds));\n slash.addChannelOption(() => channel);\n break;\n }\n }\n}\n\nconst PREFIX_TYPES: Record<OptionKind, PrefixArgType | null> = {\n string: \"string\",\n integer: \"integer\",\n number: \"number\",\n boolean: \"boolean\",\n user: \"user\",\n role: \"role\",\n channel: \"channel\",\n mentionable: \"mentionable\",\n attachment: null,\n};\n\n/** The argument specs of a command's prefix form; the last text option takes the rest of the message. */\nfunction prefixSpecs(options: OptionMap): PrefixArgSpec[] {\n const entries = Object.entries(options);\n const specs: PrefixArgSpec[] = [];\n for (const [index, [name, def]] of entries.entries()) {\n const type = PREFIX_TYPES[def.kind];\n if (type === null) continue;\n const config = def.config as StringConfig & NumberConfig;\n const choices = (def.words ?? config.choices)?.map((choice) =>\n typeof choice === \"object\" ? choice.value : choice,\n );\n specs.push({\n name,\n type:\n type === \"string\" && index === entries.length - 1\n ? \"rest\"\n : type,\n required:\n settings(def).required === true && config.default === undefined,\n min: config.min,\n max: config.max,\n maxLength: def.kind === \"string\" ? config.max : undefined,\n choices,\n });\n }\n return specs;\n}\n\n/**\n * Defines a command once; it can be a slash command, a prefix command, or both.\n * @example\n * export default command({\n * name: \"timeout\",\n * description: \"Time a member out\",\n * permissions: [\"ModerateMembers\"],\n * options: {\n * user: option.user({ required: true }),\n * minutes: option.integer({ min: 1, max: 40_320, default: 10 }),\n * reason: option.string({ max: 500 }),\n * },\n * prefix: true,\n * async run({ bot, options, guildId, reply }) {\n * await bot.member(guildId!, options.user).timeout(`${options.minutes}m`, options.reason);\n * await reply(`Timed out <@${options.user}>.`);\n * },\n * });\n * @throws {RangeError} For a name, description or option Discord would refuse.\n * @throws {TypeError} If it is neither a slash nor a prefix command, or a required option follows an optional one.\n */\nexport function command<const M extends OptionMap = Record<never, never>>(\n definition: CommandDefinition<M>,\n): Command<M> {\n const slash = definition.slash ?? true;\n const prefix = definition.prefix\n ? {\n aliases:\n typeof definition.prefix === \"object\"\n ? [...(definition.prefix.aliases ?? [])]\n : [],\n }\n : (false as const);\n if (!COMMAND_NAME.test(definition.name))\n throw new RangeError(\n `Invalid command name: ${definition.name}. Use 1-32 lowercase letters, digits, - or _.`,\n );\n if (\n definition.description.length < 1 ||\n definition.description.length > 100\n )\n throw new RangeError(\"A command description must be 1-100 characters.\");\n if (!slash && !prefix)\n throw new TypeError(\n `Command ${definition.name} is neither a slash nor a prefix command.`,\n );\n for (const alias of prefix ? prefix.aliases : [])\n if (!COMMAND_NAME.test(alias))\n throw new RangeError(\n `Invalid alias for ${definition.name}: ${alias}.`,\n );\n const options = (definition.options ?? {}) as M;\n let optionalSeen: string | undefined;\n for (const [name, def] of Object.entries(options)) {\n const needed = settings(def).required === true;\n if (needed && optionalSeen !== undefined)\n throw new TypeError(\n `Option ${name} is required but follows the optional option ${optionalSeen}; put required options first.`,\n );\n if (!needed) optionalSeen ??= name;\n }\n const permissions = definition.permissions ?? [];\n const guildOnly = definition.guildOnly ?? permissions.length > 0;\n\n // Fail now, not on first use: this builds every option once.\n const toJSON = (): Record<string, unknown> => {\n const builder = new CreateSlashCommand()\n .setName(definition.name)\n .setDescription(definition.description);\n for (const [name, def] of Object.entries(options))\n addOptionTo(builder, name, def);\n if (permissions.length)\n builder.setDefaultMemberPermissions(\n new PermissionSet([...permissions]).bitfield,\n );\n if (guildOnly) builder.setContexts(0);\n if (definition.nsfw) builder.setNSFW(true);\n return builder.toJSON();\n };\n if (slash) toJSON();\n\n return Object.freeze({\n name: definition.name,\n description: definition.description,\n options,\n permissions,\n guildOnly,\n nsfw: definition.nsfw ?? false,\n slash,\n prefix,\n run: definition.run,\n toJSON,\n usage(prefixText: string): string {\n const parts = Object.entries(options).map(([name, def]) => {\n const required =\n settings(def).required === true &&\n settings(def).default === undefined;\n const label = def.kind === \"attachment\" ? `${name}📎` : name;\n return required ? `<${label}>` : `[${label}]`;\n });\n return [`${prefixText}${definition.name}`, ...parts].join(\" \");\n },\n });\n}\n\n// ─── Running commands ────────────────────────────────────────────────────────\n\nfunction applyDefault(\n def: AnyOption,\n value: PrefixArgValue | APIAttachment | MentionableValue | null | undefined,\n): unknown {\n if (value !== null && value !== undefined) return value;\n return settings(def).default;\n}\n\n/** Reads a slash command's options as the definition describes them. */\nfunction readSlashOptions(\n options: OptionMap,\n interaction: CommandInteraction,\n): Record<string, unknown> {\n const values: Record<string, unknown> = {};\n for (const [name, def] of Object.entries(options)) {\n const source = interaction.options;\n let value: PrefixArgValue | APIAttachment | MentionableValue | null;\n switch (def.kind) {\n case \"string\":\n value = source.getString(name);\n break;\n case \"integer\":\n value = source.getInteger(name);\n break;\n case \"number\":\n value = source.getNumber(name);\n break;\n case \"boolean\":\n value = source.getBoolean(name);\n break;\n case \"user\":\n value = idOf(source.getUser(name));\n break;\n case \"role\":\n value = idOf(source.getRole(name));\n break;\n case \"channel\":\n value = idOf(source.getChannel(name));\n break;\n case \"mentionable\": {\n const id = idOf(source.getMentionable(name));\n value = id\n ? { id, type: source.getMentionableType(name) ?? \"user\" }\n : null;\n break;\n }\n case \"attachment\":\n value = source.getAttachment(name) as APIAttachment | null;\n break;\n }\n values[name] = applyDefault(def, value);\n }\n return values;\n}\n\nfunction idOf(record: Record<string, unknown> | null): string | null {\n return record === null ? null : String(record.id);\n}\n\nfunction words(name: string): string {\n return name.replace(/([a-z])([A-Z])/g, \"$1 $2\");\n}\n\n/** Adds slash and prefix commands and runs them. Reached as `bot.commands`. */\nexport class CommandRegistry {\n readonly #bot: Client;\n readonly #commands = new Map<string, Command<OptionMap>>();\n readonly #names = new Map<string, Command<OptionMap>>();\n #listening = false;\n\n public constructor(bot: Client) {\n this.#bot = bot;\n }\n\n /**\n * Adds commands, replacing one with the same name.\n * @throws {TypeError} If a prefix name or alias is already taken by another command.\n */\n public add(...commands: Command<OptionMap>[]): this {\n for (const added of commands) {\n const taken = [\n added.name,\n ...(added.prefix ? added.prefix.aliases : []),\n ];\n for (const name of taken) {\n const owner = this.#names.get(name);\n if (owner && owner.name !== added.name)\n throw new TypeError(\n `The name \"${name}\" is already used by the ${owner.name} command.`,\n );\n }\n const previous = this.#commands.get(added.name);\n if (previous)\n for (const name of [\n previous.name,\n ...(previous.prefix ? previous.prefix.aliases : []),\n ])\n this.#names.delete(name);\n this.#commands.set(added.name, added);\n if (added.slash || added.prefix)\n for (const name of taken) this.#names.set(name, added);\n }\n return this;\n }\n\n /** The command named `name` (or one of its prefix aliases). */\n public get(name: string): Command<OptionMap> | undefined {\n return this.#names.get(name.toLowerCase());\n }\n\n /** Every command, in the order they were added. */\n public list(): Command<OptionMap>[] {\n return [...this.#commands.values()];\n }\n\n /**\n * Registers the slash commands with Discord, replacing the ones already\n * registered. Call it once the client is ready.\n * @param options `guildId` registers them in one guild (instant) instead of globally.\n * @returns How many were registered.\n * @throws {Error} If the client is not ready.\n */\n public async deploy(options: { guildId?: string } = {}): Promise<number> {\n if (!this.#bot.isReady())\n throw new Error(\n 'Deploy commands after the client is ready: bot.once(\"ready\", () => bot.commands.deploy()).',\n );\n const payloads = this.list()\n .filter((entry) => entry.slash)\n .map((entry) => entry.toJSON()) as unknown as Parameters<\n Client[\"application\"][\"commands\"][\"set\"]\n >[0];\n await (options.guildId === undefined\n ? this.#bot.application.commands.set(payloads)\n : this.#bot.application.commands.setGuild(\n options.guildId,\n payloads,\n ));\n return payloads.length;\n }\n\n /**\n * Starts answering: slash commands from interactions and, when `prefix`\n * is given, prefix commands from messages.\n * @param options.prefix The text a message starts with, or several.\n * @throws {TypeError} If called twice.\n */\n public listen(options: { prefix?: string | readonly string[] } = {}): this {\n if (this.#listening)\n throw new TypeError(\"bot.commands.listen() was already called.\");\n this.#listening = true;\n const prefixes =\n options.prefix === undefined\n ? []\n : typeof options.prefix === \"string\"\n ? [options.prefix]\n : [...options.prefix];\n if (prefixes.some((prefix) => prefix === \"\"))\n throw new TypeError(\"A command prefix cannot be empty.\");\n\n this.#bot.on(\"interactionCreate\", async (interaction) => {\n if (!interaction.isChatInputCommand()) return;\n const found = this.#commands.get(interaction.commandName);\n if (found?.slash) await this.#runSlash(found, interaction);\n });\n\n if (prefixes.length) {\n this.#warnAboutIntents();\n this.#bot.on(\"messageCreate\", async (message) => {\n if (message.author.bot) return;\n const prefix = prefixes.find((p) =>\n message.content.startsWith(p),\n );\n if (prefix !== undefined)\n await this.#runPrefix(message, prefix);\n });\n }\n return this;\n }\n\n #warnAboutIntents(): void {\n const intents = resolveGatewayIntents(this.#bot.options.intents);\n const missing: string[] = [];\n if ((intents & (1 << 15)) === 0) missing.push(\"MessageContent\");\n if ((intents & ((1 << 9) | (1 << 12))) === 0)\n missing.push(\"GuildMessages or DirectMessages\");\n if (missing.length === 0) return;\n process.emitWarning(\n `Prefix commands need the ${missing.join(\" and \")} intent${missing.length > 1 ? \"s\" : \"\"}; without ${missing.length > 1 ? \"them\" : \"it\"} Discord sends empty message content and no prefix command will match.`,\n { type: \"LunibeeWarning\", code: \"LUNIBEE_MESSAGE_CONTENT_INTENT\" },\n );\n }\n\n async #runSlash(\n found: Command<OptionMap>,\n interaction: CommandInteraction,\n ): Promise<void> {\n let answered = false;\n const reply = async (\n content: string | InteractionReplyOptions,\n ): Promise<void> => {\n const body = typeof content === \"string\" ? { content } : content;\n if (answered) await interaction.followUp(body);\n else if (interaction.deferred) await interaction.editReply(body);\n else await interaction.reply(body);\n answered = true;\n };\n await found.run({\n bot: this.#bot,\n options: readSlashOptions(found.options, interaction),\n source: \"slash\",\n guildId: interaction.guildId,\n channelId: interaction.channelId,\n userId: interaction.user?.id ?? \"\",\n member: interaction.member,\n interaction,\n message: undefined,\n reply,\n defer: async (deferOptions) => {\n await interaction.deferReply({\n ephemeral: deferOptions?.ephemeral ?? false,\n });\n },\n } as CommandContext<OptionMap>);\n }\n\n /**\n * The first channel or role argument that is not in the message's server\n * (or, for a channel, not one of the option's `kinds`). In a DM a channel\n * argument may only name the DM itself, and roles are refused.\n */\n async #outOfScope(\n options: OptionMap,\n values: Record<string, unknown>,\n message: Message,\n ): Promise<{ key: string; error: string } | undefined> {\n const guildId = message.guildId ?? undefined;\n for (const [key, def] of Object.entries(options)) {\n const value = values[key];\n if (value === undefined || value === null) continue;\n if (def.kind === \"channel\") {\n const id = String(value);\n const channel = await this.#channel(id);\n const inScope = guildId\n ? channel?.guildId === guildId\n : id === message.channelId;\n if (!channel || !inScope)\n return {\n key,\n error: guildId\n ? \"must be a channel in this server\"\n : \"must be this channel\",\n };\n const kinds = (def.config as ChannelConfig).kinds;\n if (\n kinds?.length &&\n !channelTypes(kinds).includes(channel.type)\n )\n return {\n key,\n error: `must be a ${kinds.join(\" or \")} channel`,\n };\n }\n const roleId =\n def.kind === \"role\"\n ? String(value)\n : def.kind === \"mentionable\" &&\n (value as { type?: string }).type === \"role\"\n ? (value as { id: string }).id\n : undefined;\n if (\n roleId !== undefined &&\n !(guildId && (await this.#hasRole(guildId, roleId)))\n )\n return { key, error: \"must be a role in this server\" };\n }\n return undefined;\n }\n\n /** A complete channel from the cache, else from Discord; undefined when there is none the bot can see. */\n async #channel(id: string) {\n const cached = this.#bot.channels.get(id);\n if (cached && !cached.partial) return cached;\n try {\n return await this.#bot.channels.fetch(id);\n } catch {\n return undefined;\n }\n }\n\n async #hasRole(guildId: string, roleId: string): Promise<boolean> {\n if (roleId === guildId) return true; // @everyone\n const roles = this.#bot.guilds.roles(guildId);\n if (roles.get(roleId)) return true;\n try {\n return (await roles.fetchAll()).some((role) => role.id === roleId);\n } catch {\n return false;\n }\n }\n\n async #runPrefix(message: Message, prefix: string): Promise<void> {\n const text = message.content.slice(prefix.length).trim();\n const [name = \"\", ...rest] = text.split(/\\s+/);\n const found = this.get(name);\n if (!found?.prefix) return;\n const reply = async (\n content: string | InteractionReplyOptions,\n ): Promise<void> => {\n const { ephemeral: _ephemeral, ...body } =\n typeof content === \"string\" ? { content } : content;\n await message.reply(body);\n };\n if (found.guildOnly && !message.guildId) {\n await reply(\"This command only works in servers.\");\n return;\n }\n if (found.permissions.length) {\n const lacking = found.permissions.filter(\n (permission) => !message.member?.permissions.has(permission),\n );\n if (lacking.length) {\n await reply(\n `You need ${lacking.map((p) => `**${words(p)}**`).join(\", \")}.`,\n );\n return;\n }\n }\n const parsed = parsePrefixArgs(\n rest.join(\" \"),\n prefixSpecs(found.options),\n );\n const attachments = [...message.attachments];\n const values: Record<string, unknown> = {};\n if (parsed.ok)\n for (const [key, def] of Object.entries(found.options)) {\n if (def.kind === \"attachment\") {\n const attachment = attachments.shift();\n if (!attachment && settings(def).required === true) {\n await reply(\n `\\`${key}\\` is required. Usage: \\`${found.usage(prefix)}\\``,\n );\n return;\n }\n values[key] = applyDefault(def, attachment);\n } else values[key] = applyDefault(def, parsed.values[key]);\n }\n else {\n await reply(\n `\\`${parsed.arg}\\` ${parsed.error}. Usage: \\`${found.usage(prefix)}\\``,\n );\n return;\n }\n // Discord resolves a slash command's channel and role options in the\n // server it runs in; a prefix argument is only an ID, so hold it to\n // the same rules here.\n const outOfScope = await this.#outOfScope(\n found.options,\n values,\n message,\n );\n if (outOfScope) {\n await reply(\n `\\`${outOfScope.key}\\` ${outOfScope.error}. Usage: \\`${found.usage(prefix)}\\``,\n );\n return;\n }\n await found.run({\n bot: this.#bot,\n options: values,\n source: \"prefix\",\n guildId: message.guildId,\n channelId: message.channelId,\n userId: message.author.id,\n member: message.member ?? null,\n interaction: undefined,\n message,\n reply,\n defer: async () => {},\n } as CommandContext<OptionMap>);\n }\n}\n",
|
|
10
|
+
"import { ChannelKinds, type APIOverwrite } from \"@lunibee/types\";\nimport type { ChannelCreateOptions } from \"@lunibee/managers\";\n\n/** What every kind of channel takes when it is created. */\ninterface CreateBase {\n /** 1-100 characters. */\n name: string;\n /** The category to put it in. */\n parent?: string;\n position?: number;\n permissionOverwrites?: APIOverwrite[];\n /** Audit-log reason. */\n reason?: string;\n}\n\n/** Seconds of inactivity before a thread in the channel archives itself. */\ntype AutoArchive = 60 | 1440 | 4320 | 10080;\n\n/** A text or announcement channel. */\nexport interface CreateTextChannel extends CreateBase {\n kind: \"text\" | \"announcement\";\n topic?: string;\n nsfw?: boolean;\n /** Seconds a member must wait between messages (0-21600). */\n slowmode?: number;\n autoArchive?: AutoArchive;\n}\n\n/** A voice or stage channel. */\nexport interface CreateVoiceChannel extends CreateBase {\n kind: \"voice\" | \"stage\";\n /** Bits per second. */\n bitrate?: number;\n /** 0-99; 0 is unlimited. */\n userLimit?: number;\n /** Voice region id, or `null` for automatic. */\n region?: string | null;\n videoQuality?: \"auto\" | \"720p\";\n nsfw?: boolean;\n}\n\n/** A category. */\nexport interface CreateCategoryChannel extends CreateBase {\n kind: \"category\";\n}\n\n/** A forum tag: a unicode emoji, or a custom emoji's id. */\nexport interface ForumTagInput {\n name: string;\n emoji?: string;\n /** Only moderators can apply it. */\n moderated?: boolean;\n}\n\n/** A forum or media channel. */\nexport interface CreateForumChannel extends CreateBase {\n kind: \"forum\" | \"media\";\n /** The guidelines shown above the posts. */\n topic?: string;\n nsfw?: boolean;\n slowmode?: number;\n /** Slowmode for posts' threads, in seconds. */\n threadSlowmode?: number;\n autoArchive?: AutoArchive;\n tags?: ForumTagInput[];\n /** The reaction added to new posts: a unicode emoji, or a custom emoji's id. */\n defaultReaction?: string;\n sortOrder?: \"latest-activity\" | \"creation-date\";\n /** Forum only. */\n layout?: \"list\" | \"gallery\";\n}\n\n/** The options for `guild.createChannel()`; `kind` decides which others apply. */\nexport type CreateChannelOptions =\n | CreateTextChannel\n | CreateVoiceChannel\n | CreateCategoryChannel\n | CreateForumChannel;\n\nconst CREATABLE = [\n \"text\",\n \"announcement\",\n \"voice\",\n \"stage\",\n \"category\",\n \"forum\",\n \"media\",\n] as const satisfies readonly CreateChannelOptions[\"kind\"][];\n\nfunction emoji(value: string): {\n emoji_id: string | null;\n emoji_name: string | null;\n} {\n return /^\\d+$/.test(value)\n ? { emoji_id: value, emoji_name: null }\n : { emoji_id: null, emoji_name: value };\n}\n\n/**\n * Turns `createChannel()` options into the request Discord expects.\n * @throws {RangeError} For a name or number Discord would refuse.\n */\nexport function channelCreatePayload(\n options: CreateChannelOptions,\n): ChannelCreateOptions {\n if (!(CREATABLE as readonly string[]).includes(options.kind))\n throw new TypeError(\n `Cannot create a ${String(options.kind)} channel here. Use one of: ${CREATABLE.join(\", \")}.`,\n );\n if (options.name.length < 1 || options.name.length > 100)\n throw new RangeError(\"A channel name must be 1-100 characters.\");\n const body: ChannelCreateOptions = {\n name: options.name,\n type: ChannelKinds[options.kind][0],\n parent_id: options.parent,\n position: options.position,\n permission_overwrites: options.permissionOverwrites,\n reason: options.reason,\n };\n switch (options.kind) {\n case \"text\":\n case \"announcement\":\n case \"forum\":\n case \"media\": {\n if (\n options.slowmode !== undefined &&\n (!Number.isInteger(options.slowmode) ||\n options.slowmode < 0 ||\n options.slowmode > 21_600)\n )\n throw new RangeError(\"slowmode must be 0-21600 seconds.\");\n body.topic = options.topic;\n body.nsfw = options.nsfw;\n body.rate_limit_per_user = options.slowmode;\n body.default_auto_archive_duration = options.autoArchive;\n if (options.kind === \"forum\" || options.kind === \"media\") {\n body.default_thread_rate_limit_per_user =\n options.threadSlowmode;\n body.available_tags = options.tags?.map((tag) => ({\n name: tag.name,\n moderated: tag.moderated ?? false,\n ...(tag.emoji ? emoji(tag.emoji) : {}),\n }));\n if (options.defaultReaction)\n body.default_reaction_emoji = emoji(\n options.defaultReaction,\n );\n if (options.sortOrder)\n body.default_sort_order =\n options.sortOrder === \"latest-activity\" ? 0 : 1;\n if (options.layout)\n body.default_forum_layout =\n options.layout === \"list\" ? 1 : 2;\n }\n break;\n }\n case \"voice\":\n case \"stage\":\n if (\n options.userLimit !== undefined &&\n (!Number.isInteger(options.userLimit) ||\n options.userLimit < 0 ||\n options.userLimit > 99)\n )\n throw new RangeError(\"userLimit must be 0-99.\");\n body.bitrate = options.bitrate;\n body.user_limit = options.userLimit;\n body.rtc_region = options.region;\n body.nsfw = options.nsfw;\n if (options.videoQuality)\n body.video_quality_mode =\n options.videoQuality === \"auto\" ? 1 : 2;\n break;\n case \"category\":\n break;\n }\n return body;\n}\n",
|
|
11
|
+
"import type { Collection } from \"@lunibee/collection\";\nimport type { ChannelKind, UnknownChannelKind } from \"@lunibee/types\";\nimport type {\n BanOptions,\n ChannelEditOptions,\n GuildManager,\n MemberEditOptions,\n MessageCreateOptions,\n MessageEditOptions,\n MessageQueryOptions,\n RoleEditOptions,\n} from \"@lunibee/managers\";\nimport type {\n Channel,\n ChannelOfKind,\n Guild,\n GuildMember,\n Message,\n Role,\n User,\n} from \"@lunibee/structures\";\nimport type { Client } from \"./index.js\";\nimport {\n channelCreatePayload,\n type CreateChannelOptions,\n} from \"./channel-create.js\";\n\n/** A length of time: milliseconds, or text such as `\"90s\"`, `\"10m\"`, `\"2h\"`, `\"1d\"`, `\"1w\"` or `\"1h30m\"`. */\nexport type Duration = number | string;\n\nconst UNIT_MS: Record<string, number> = {\n ms: 1,\n s: 1_000,\n m: 60_000,\n h: 3_600_000,\n d: 86_400_000,\n w: 604_800_000,\n};\n\n/**\n * Turns a {@link Duration} into milliseconds.\n * @throws {RangeError} If a number is negative or not finite, or the text is not a duration.\n */\nexport function parseDuration(value: Duration): number {\n if (typeof value === \"number\") {\n if (!Number.isFinite(value) || value < 0)\n throw new RangeError(\n \"A duration must be a non-negative, finite number of milliseconds.\",\n );\n return value;\n }\n const text = value.replace(/\\s+/g, \"\").toLowerCase();\n if (!/^(?:\\d+(?:\\.\\d+)?(?:ms|s|m|h|d|w))+$/.test(text))\n throw new RangeError(\n `Invalid duration: ${JSON.stringify(value)}. Use a number of milliseconds or text such as \"90s\", \"10m\" or \"1h30m\".`,\n );\n let total = 0;\n for (const [, amount, unit] of text.matchAll(\n /(\\d+(?:\\.\\d+)?)(ms|s|m|h|d|w)/g,\n ))\n total += Number(amount) * UNIT_MS[unit!]!;\n return Math.round(total);\n}\n\n/** Message text, or a full payload. */\nexport type MessageInput = string | MessageCreateOptions;\n\nfunction payload(input: MessageInput): MessageCreateOptions {\n return typeof input === \"string\" ? { content: input } : input;\n}\n\n/**\n * A reference to one Discord thing by its ids. A handle holds no data, so it\n * is cheap to create, can be made before the thing is cached, and fails only\n * when you use it.\n *\n * - `peek()` reads the cache and returns `undefined` when it is not there.\n * - `get()` reads the cache, and asks Discord when it is not there.\n * - `fetch()` asks Discord now and refreshes the cache.\n */\nexport interface Handle<T> {\n peek(): T | undefined;\n get(): Promise<T>;\n fetch(): Promise<T>;\n}\n\n/** A user, by id. Made by `bot.person(id)`. */\nexport class UserHandle implements Handle<User> {\n public constructor(\n private readonly bot: Client,\n public readonly id: string,\n ) {}\n\n public peek(): User | undefined {\n return this.bot.users.get(this.id);\n }\n public get(): Promise<User> {\n return this.bot.users.resolve(this.id);\n }\n public fetch(): Promise<User> {\n return this.bot.users.fetch(this.id);\n }\n\n /** Opens (or reuses) the direct-message channel with this user. */\n public async dm(): Promise<ChannelHandle> {\n const data = await this.bot.users.createDM(this.id);\n this.bot.channels.upsert(data);\n return new ChannelHandle(this.bot, data.id);\n }\n /** Sends this user a direct message. */\n public async send(message: MessageInput): Promise<Message> {\n return (await this.dm()).send(message);\n }\n}\n\n/** A guild, by id. Made by `bot.guild(id)`. */\nexport class GuildHandle implements Handle<Guild> {\n public constructor(\n private readonly bot: Client,\n public readonly id: string,\n ) {}\n\n public peek(): Guild | undefined {\n return this.bot.guilds.get(this.id);\n }\n public get(): Promise<Guild> {\n return this.bot.guilds.resolve(this.id);\n }\n public fetch(): Promise<Guild> {\n return this.bot.guilds.fetch(this.id);\n }\n\n /** The cached members, live: it changes as the Gateway updates them. */\n public get members(): Collection<string, GuildMember> {\n return this.bot.guilds.members(this.id).cache;\n }\n /** The cached roles, live. */\n public get roles(): Collection<string, Role> {\n return this.bot.guilds.roles(this.id).cache;\n }\n /** The cached channels of this guild, as a snapshot taken when you read it. */\n public get channels(): Collection<string, Channel> {\n return this.bot.channels.cache.filter(\n (channel) => channel.guildId === this.id,\n );\n }\n\n public member(userId: string): MemberHandle {\n return new MemberHandle(this.bot, this.id, userId);\n }\n public role(roleId: string): RoleHandle {\n return new RoleHandle(this.bot, this.id, roleId);\n }\n public channel(channelId: string): ChannelHandle {\n return new ChannelHandle(this.bot, channelId);\n }\n\n /**\n * Creates a channel. `kind` decides which other options apply, and the\n * result is typed to match: a `\"voice\"` option gives a `VoiceChannel`.\n * @example await bot.guild(id).createChannel({ kind: \"text\", name: \"general\", parent: categoryId });\n */\n public async createChannel<O extends CreateChannelOptions>(\n options: O,\n ): Promise<ChannelOfKind<O[\"kind\"]>> {\n const channel = await this.bot.channels.create(\n this.id,\n channelCreatePayload(options),\n );\n return channel.as(options.kind) as ChannelOfKind<O[\"kind\"]>;\n }\n\n /** Bans a user, whether or not they are a member. */\n public ban(userId: string, options?: BanOptions): Promise<void> {\n return this.bot.guilds.members(this.id).ban(userId, options);\n }\n /** Lifts a ban. */\n public unban(userId: string, reason?: string): Promise<void> {\n return this.bot.guilds.members(this.id).unban(userId, reason);\n }\n /** Changes the guild's settings; `reason` is the audit-log reason. */\n public edit(options: Parameters<GuildManager[\"edit\"]>[1]): Promise<Guild> {\n return this.bot.guilds.edit(this.id, options);\n }\n /** Makes the bot leave the guild. */\n public leave(): Promise<void> {\n return this.bot.users.leaveGuild(this.id);\n }\n}\n\n/** A guild member, by guild id and user id. Made by `bot.member(guildId, userId)`. */\nexport class MemberHandle implements Handle<GuildMember> {\n public constructor(\n private readonly bot: Client,\n public readonly guildId: string,\n public readonly userId: string,\n ) {}\n\n private get members() {\n return this.bot.guilds.members(this.guildId);\n }\n\n public peek(): GuildMember | undefined {\n return this.members.get(this.userId);\n }\n public get(): Promise<GuildMember> {\n return this.members.resolve(this.userId);\n }\n public fetch(): Promise<GuildMember> {\n return this.members.fetch(this.userId);\n }\n\n public guild(): GuildHandle {\n return new GuildHandle(this.bot, this.guildId);\n }\n public user(): UserHandle {\n return new UserHandle(this.bot, this.userId);\n }\n\n public kick(reason?: string): Promise<void> {\n return this.members.kick(this.userId, reason);\n }\n public ban(options?: BanOptions): Promise<void> {\n return this.members.ban(this.userId, options);\n }\n public unban(reason?: string): Promise<void> {\n return this.members.unban(this.userId, reason);\n }\n /** Changes nickname, roles, mute or deafen; put the audit-log reason in `options.reason`. */\n public edit(options: MemberEditOptions): Promise<GuildMember> {\n return this.members.edit(this.userId, options);\n }\n public addRole(roleId: string, reason?: string): Promise<void> {\n return this.members.addRole(this.userId, roleId, reason);\n }\n public removeRole(roleId: string, reason?: string): Promise<void> {\n return this.members.removeRole(this.userId, roleId, reason);\n }\n /**\n * Times the member out for `duration` (`\"10m\"`, `\"2h\"`, 90_000), or lifts\n * the timeout with `null`.\n */\n public async timeout(\n duration: Duration | null,\n reason?: string,\n ): Promise<GuildMember> {\n return this.members.timeout(\n this.userId,\n duration === null ? null : parseDuration(duration),\n reason,\n );\n }\n}\n\n/** A role, by guild id and role id. Made by `bot.role(guildId, roleId)`. */\nexport class RoleHandle implements Handle<Role> {\n public constructor(\n private readonly bot: Client,\n public readonly guildId: string,\n public readonly roleId: string,\n ) {}\n\n private get roles() {\n return this.bot.guilds.roles(this.guildId);\n }\n\n public peek(): Role | undefined {\n return this.roles.get(this.roleId);\n }\n public get(): Promise<Role> {\n return this.roles.resolve(this.roleId);\n }\n public fetch(): Promise<Role> {\n return this.roles.fetch(this.roleId);\n }\n\n public edit(options: RoleEditOptions): Promise<Role> {\n return this.roles.edit(this.roleId, options);\n }\n public delete(reason?: string): Promise<void> {\n return this.roles.remove(this.roleId, reason);\n }\n}\n\n/** A channel, by id. Made by `bot.channel(id)`. */\nexport class ChannelHandle implements Handle<Channel> {\n public constructor(\n private readonly bot: Client,\n public readonly id: string,\n ) {}\n\n public peek(): Channel | undefined {\n return this.bot.channels.get(this.id);\n }\n public get(): Promise<Channel> {\n return this.bot.channels.resolve(this.id);\n }\n public fetch(): Promise<Channel> {\n return this.bot.channels.fetch(this.id);\n }\n\n public message(messageId: string): MessageHandle {\n return new MessageHandle(this.bot, this.id, messageId);\n }\n\n /**\n * Gets the channel (cache, else Discord) and returns it typed as one of\n * `kinds`.\n * @throws {TypeError} If it is a different kind.\n */\n public async as<K extends ChannelKind | UnknownChannelKind>(\n ...kinds: K[]\n ): Promise<ChannelOfKind<K>> {\n return (await this.get()).as(...kinds);\n }\n\n /** Sends a message: text, or a full payload (`embeds`, `components`, `files`, …). */\n public send(message: MessageInput): Promise<Message> {\n return this.bot.channels.send(this.id, payload(message));\n }\n /** Reads messages: the latest, or around / before / after one. */\n public messages(query: MessageQueryOptions = {}): Promise<Message[]> {\n return this.bot.channels.fetchMessages(this.id, query);\n }\n public edit(options: ChannelEditOptions): Promise<Channel> {\n return this.bot.channels.edit(this.id, options);\n }\n public delete(reason?: string): Promise<void> {\n return this.bot.channels.remove(this.id, reason);\n }\n /** Deletes up to 100 messages younger than 14 days. */\n public bulkDelete(\n messageIds: Iterable<string>,\n reason?: string,\n ): Promise<void> {\n return this.bot.channels.bulkDeleteMessages(\n this.id,\n messageIds,\n reason,\n );\n }\n}\n\n/** A message, by channel id and message id. Made by `bot.message(channelId, messageId)`. */\nexport class MessageHandle implements Handle<Message> {\n public constructor(\n private readonly bot: Client,\n public readonly channelId: string,\n public readonly messageId: string,\n ) {}\n\n public peek(): Message | undefined {\n return this.bot.channels\n .cachedMessages(this.channelId)\n ?.cache.peek(this.messageId);\n }\n public async get(): Promise<Message> {\n return this.peek() ?? this.fetch();\n }\n public fetch(): Promise<Message> {\n return this.bot.channels.fetchMessage(this.channelId, this.messageId);\n }\n\n public channel(): ChannelHandle {\n return new ChannelHandle(this.bot, this.channelId);\n }\n\n public edit(message: string | MessageEditOptions): Promise<Message> {\n return this.bot.channels.editMessage(\n this.channelId,\n this.messageId,\n typeof message === \"string\" ? { content: message } : message,\n );\n }\n public delete(reason?: string): Promise<void> {\n return this.bot.channels.deleteMessage(\n this.channelId,\n this.messageId,\n reason,\n );\n }\n /** Sends a message that replies to this one. */\n public reply(message: MessageInput): Promise<Message> {\n return this.bot.channels.send(this.channelId, {\n ...payload(message),\n message_reference: {\n message_id: this.messageId,\n channel_id: this.channelId,\n },\n });\n }\n /** Adds the bot's reaction (`\"👍\"`, or `\"name:id\"` for a custom emoji). */\n public react(emoji: string): Promise<void> {\n return this.bot.channels.addReaction(\n this.channelId,\n this.messageId,\n emoji,\n );\n }\n public pin(reason?: string): Promise<void> {\n return this.bot.channels.pinMessage(\n this.channelId,\n this.messageId,\n reason,\n );\n }\n public unpin(reason?: string): Promise<void> {\n return this.bot.channels.unpinMessage(\n this.channelId,\n this.messageId,\n reason,\n );\n }\n /** Publishes the message from an announcement channel. */\n public crosspost(): Promise<Message> {\n return this.bot.channels.crosspostMessage(\n this.channelId,\n this.messageId,\n );\n }\n}\n",
|
|
12
|
+
"export {\n Permission,\n Permissions,\n PermissionFlagsBits,\n PermissionSet,\n PermissionsBitField,\n PermissionOverwriteEnum,\n computePermissions,\n type PermissionContext,\n type PermissionOverwrite,\n type PermissionRole,\n type PermissionName,\n} from \"./permissions.js\";\nexport {\n ClientEvent,\n type ClientEventName,\n type ClientEvents,\n type ClientListener,\n} from \"./events.js\";\nexport { Collector, type CollectorOptions } from \"./collector.js\";\nexport {\n RedisCache,\n type RedisCacheOptions,\n type RedisCacheDiagnostics,\n type RedisCommandClient,\n type RawDispatchSource,\n} from \"./redis-cache.js\";\nexport {\n createApi,\n type Api,\n type ApplicationNode,\n type ChannelNode,\n type GuildNode,\n type ListRoute,\n type MemberNode,\n type MembersRoute,\n type MessageNode,\n type MessagesRoute,\n type PageOptions,\n type Route,\n type RouteId,\n type RouteOptions,\n type UserNode,\n type WebhookNode,\n} from \"./api.js\";\nexport {\n command,\n option,\n CommandRegistry,\n type ChannelConfig,\n type ChoiceConfig,\n type BooleanConfig,\n type Command,\n type CommandContext,\n type CommandDefinition,\n type MentionableValue,\n type NumberConfig,\n type OptionDef,\n type OptionMap,\n type OptionValues,\n type StringConfig,\n} from \"./commands.js\";\nexport {\n channelCreatePayload,\n type CreateCategoryChannel,\n type CreateChannelOptions,\n type CreateForumChannel,\n type CreateTextChannel,\n type CreateVoiceChannel,\n type ForumTagInput,\n} from \"./channel-create.js\";\nexport {\n ChannelHandle,\n GuildHandle,\n MemberHandle,\n MessageHandle,\n RoleHandle,\n UserHandle,\n parseDuration,\n type Duration,\n type Handle,\n type MessageInput,\n} from \"./handles.js\";\nexport {\n GatewayIntentBits,\n IntentBits,\n resolveGatewayIntents,\n type GatewayIntentResolvable,\n} from \"@lunibee/types\";\n\nimport {\n ActivityEnum,\n GatewayIntentBits,\n resolveGatewayIntents,\n} from \"@lunibee/types\";\nimport {\n ApplicationCommandManager,\n ChannelManager,\n GuildManager,\n MonetizationManager,\n ApplicationEmojiManager,\n StageInstanceManager,\n UserManager,\n toRequest,\n} from \"@lunibee/managers\";\nimport { REST, Routes } from \"@lunibee/rest\";\nimport {\n User,\n GuildMember,\n Role,\n Emoji,\n type Channel,\n createChannel,\n Message,\n createInteraction,\n type InteractionClient,\n type InteractionData,\n type ResourceContext,\n} from \"@lunibee/structures\";\nimport { Gateway } from \"@lunibee/ws\";\nimport { VoiceManager } from \"@lunibee/voice\";\nimport {\n ClusterWorker,\n connectInQueue,\n readClusterContext,\n type ClusterContext,\n type IdentifySlotGate,\n} from \"@lunibee/sharding\";\nimport type {\n APIEntitlement,\n APISoundboardSound,\n APIChannel,\n APIGuild,\n APIGuildMember,\n APIGuildRoleEvent,\n APIGuildRoleDeleteEvent,\n APIGuildBanEvent,\n APIGuildEmojisUpdateEvent,\n APIGuildStickersUpdateEvent,\n APIMessageDeleteBulkEvent,\n APIMessageDeleteEvent,\n APIMessageReactionEvent,\n APIMessageReactionRemoveEmojiEvent,\n APIReadyEvent,\n APIRole,\n APIThreadEvent,\n APIThreadListSync,\n APIThreadMembersUpdate,\n APIVoiceState,\n APIVoiceServerUpdate,\n APIPresenceUpdate,\n APITypingStart,\n APIInviteCreate,\n APIInviteDelete,\n APIWebhooksUpdate,\n APIAutoModerationRule,\n APIAutoModerationActionExecution,\n APIGuildScheduledEvent,\n APIGuildScheduledEventUserEvent,\n APIStageInstance,\n APIChannelPinsUpdate,\n APIGuildMembersChunk,\n APIMessagePollVoteEvent,\n ClientOptions,\n UserData,\n} from \"@lunibee/types\";\nimport { ClientEvent, type ClientEvents } from \"./events.js\";\nimport { Collector, type CollectorOptions } from \"./collector.js\";\nimport { computePermissions, PermissionSet } from \"./permissions.js\";\nimport { createApi, type Api } from \"./api.js\";\nimport { CommandRegistry } from \"./commands.js\";\nimport {\n ChannelHandle,\n GuildHandle,\n MemberHandle,\n MessageHandle,\n RoleHandle,\n UserHandle,\n} from \"./handles.js\";\n\n/** Lifecycle state of a client. */\nexport type ClientState = \"idle\" | \"connecting\" | \"ready\" | \"destroyed\";\ntype Listener<T extends unknown[]> = (...args: T) => unknown;\ntype GuildMemberEvent = APIGuildMember & { guild_id: string };\n\n/** Minimal typed event emitter used by the client. */\nclass EventEmitter<Events extends { [K in keyof Events]: unknown[] }> {\n #listeners: { [K in keyof Events]?: Set<Listener<Events[K]>> } = {};\n /** Removes secrets from text this emitter prints; the client removes its token. */\n protected readonly redactSecrets = (text: string): string => text;\n public on<K extends keyof Events>(\n event: K,\n listener: Listener<Events[K]>,\n ): this {\n if (typeof listener !== \"function\")\n throw new TypeError(\"Event listener must be a function.\");\n (this.#listeners[event] ??= new Set()).add(listener);\n return this;\n }\n public once<K extends keyof Events>(\n event: K,\n listener: Listener<Events[K]>,\n ): this {\n const wrapped: Listener<Events[K]> = (...args) => {\n this.off(event, wrapped);\n return listener(...args);\n };\n return this.on(event, wrapped);\n }\n public off<K extends keyof Events>(\n event: K,\n listener: Listener<Events[K]>,\n ): this {\n this.#listeners[event]?.delete(listener);\n return this;\n }\n /** Alias of {@link off}, provided for Node.js `EventEmitter` familiarity. */\n public removeListener<K extends keyof Events>(\n event: K,\n listener: Listener<Events[K]>,\n ): this {\n return this.off(event, listener);\n }\n /** Number of listeners for `event`, as Node's `EventEmitter` reports it. */\n public listenerCount<K extends keyof Events>(event: K): number {\n return this.#listeners[event]?.size ?? 0;\n }\n public removeAllListeners<K extends keyof Events>(event?: K): this {\n if (event === undefined) this.#listeners = {};\n else delete this.#listeners[event];\n return this;\n }\n protected emit<K extends keyof Events>(\n event: K,\n ...args: Events[K]\n ): boolean {\n const listeners = this.#listeners[event];\n if (!listeners?.size) return false;\n for (const listener of [...listeners]) {\n try {\n const result = listener(...args);\n if (\n result &&\n typeof (result as PromiseLike<unknown>).then === \"function\"\n )\n void Promise.resolve(result).catch((error) =>\n this.#handleError(event, error),\n );\n } catch (error) {\n this.#handleError(event, error);\n }\n }\n return true;\n }\n /** Sends a listener's error to the `error` listeners. When there are none, or\n * an `error` listener itself fails, it becomes a process warning instead of\n * disappearing (never a new `error` event, so it cannot loop). */\n #handleError(event: keyof Events, error: unknown): void {\n const normalized =\n error instanceof Error\n ? error\n : new Error(String(error), { cause: error });\n // Every emitter in this file declares `error: [Error]`.\n const errorListeners = this.#listeners[\n ClientEvent.Error as keyof Events\n ] as Set<Listener<[Error]>> | undefined;\n const listeners =\n event === ClientEvent.Error ? [] : [...(errorListeners ?? [])];\n if (listeners.length === 0)\n return warnListenerError(event, normalized, this.redactSecrets);\n for (const listener of listeners) {\n try {\n const result = listener(normalized);\n if (\n result &&\n typeof (result as PromiseLike<unknown>).then === \"function\"\n )\n void Promise.resolve(result).catch((failure) =>\n warnListenerError(\n ClientEvent.Error,\n failure,\n this.redactSecrets,\n ),\n );\n } catch (failure) {\n warnListenerError(\n ClientEvent.Error,\n failure,\n this.redactSecrets,\n );\n }\n }\n }\n}\n\n/** Reports an error no listener handled as a process warning (stderr by default), with secrets removed. */\nfunction warnListenerError(\n event: PropertyKey,\n error: unknown,\n redact: (text: string) => string = (text) => text,\n): void {\n const failure = error instanceof Error ? error : new Error(String(error));\n process.emitWarning(\n redact(\n `A \"${String(event)}\" listener threw and no error listener handled it: ${failure.message}`,\n ),\n {\n type: \"LunibeeWarning\",\n code: \"LUNIBEE_UNHANDLED_LISTENER_ERROR\",\n detail:\n failure.stack === undefined ? undefined : redact(failure.stack),\n },\n );\n}\n\n/** Main Lunibee Discord client. */\nexport class Client\n extends EventEmitter<ClientEvents>\n implements InteractionClient\n{\n public readonly rest: REST;\n public readonly users: UserManager;\n public readonly guilds: GuildManager;\n public readonly channels: ChannelManager;\n /** Stage instances, cached by stage channel ID. */\n public readonly stageInstances: StageInstanceManager;\n public readonly application: { commands: ApplicationCommandManager };\n #api?: Api;\n /**\n * Discord's REST API as a chained path: `bot.api.guilds(id).members(userId).patch({ nick })`.\n * Uses this client's rate limiting and retries; `bot.rest` and `Routes` stay available.\n */\n public get api(): Api {\n return (this.#api ??= createApi(this.rest));\n }\n /** Slash and prefix commands made with `command()`: `add`, `deploy` and `listen`. */\n public readonly commands: CommandRegistry = new CommandRegistry(this);\n /** SKUs, entitlements and subscriptions; available after READY (application ID known). */\n public monetization?: MonetizationManager;\n /** The application's own emojis; available after READY (application ID known). */\n public applicationEmojis?: ApplicationEmojiManager;\n public get ws(): Gateway {\n return this.#gateway;\n }\n public get gateway(): Gateway {\n return this.#gateway;\n }\n public user?: UserData;\n /**\n * Voice connections, one per guild: `await bot.voice.join({ guildId,\n * channelId })` resolves when audio can flow. Fed by this client's own\n * VOICE_STATE_UPDATE and VOICE_SERVER_UPDATE events.\n */\n public readonly voice: VoiceManager;\n public readyAt?: Date;\n public state: ClientState = \"idle\";\n /**\n * The bot token this client is authenticated with, or `null` once the\n * client has been destroyed.\n */\n /** Replaces the bot token in text Lunibee prints (listener warnings). */\n protected override readonly redactSecrets = (text: string): string => {\n const token = this.options.token;\n return token && token.length >= 8\n ? text.split(token).join(\"[token]\")\n : text;\n };\n public get token(): string | null {\n return this.state === \"destroyed\" ? null : (this.options.token ?? null);\n }\n public get uptime(): number | null {\n return this.readyAt ? Date.now() - this.readyAt.getTime() : null;\n }\n public get ping(): number {\n return this.#gateway.ping;\n }\n /** Whether the client is ready and connected. */\n public isReady(): boolean {\n return this.state === \"ready\";\n }\n /** Sets the bot's presence / status. @param data Presence payload. @returns Whether the payload was sent. */\n public setPresence(\n data: import(\"@lunibee/types\").GatewayPresence,\n ): boolean {\n return this.#gateway.setPresence(data);\n }\n /**\n * Sets what the bot is doing: \"Playing chess\", \"Watching the logs\". Pass\n * `null` to clear it. For a custom status (type `ActivityEnum.Custom`) the\n * text shown is `state`, so it is set to `name` unless you give one.\n * @example bot.setActivity(\"the logs\", { type: ActivityEnum.Watching, status: \"idle\" });\n * @returns Whether the update was sent (false while the Gateway is not connected).\n */\n public setActivity(\n name: string | null,\n options: {\n type?: import(\"@lunibee/types\").ActivityEnum;\n url?: string;\n state?: string;\n status?: import(\"@lunibee/types\").GatewayPresence[\"status\"];\n } = {},\n ): boolean {\n const type = options.type ?? ActivityEnum.Playing;\n return this.setPresence({\n status: options.status ?? \"online\",\n activities:\n name === null\n ? []\n : [\n {\n name,\n type,\n url: options.url,\n state:\n options.state ??\n (type === ActivityEnum.Custom\n ? name\n : undefined),\n },\n ],\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.#gateway.setVoiceState(data);\n }\n /**\n * Joins, moves or leaves a voice channel (op 4). Stable public voice API.\n * Returns `false` (never throws) when disconnected, rate limited, or when\n * the guild belongs to another shard of a sharded setup.\n * @param guildId Guild snowflake. @param channelId Channel to join or move to; `null` leaves.\n * @param options `selfMute` and `selfDeaf`. @returns Whether it was sent.\n */\n public sendVoiceState(\n guildId: string,\n channelId: string | null,\n options: { selfMute?: boolean; selfDeaf?: boolean } = {},\n ): boolean {\n return this.#gateway.sendVoiceState(guildId, channelId, options);\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.#gateway.requestGuildMembers(data);\n }\n readonly #gateway: Gateway;\n /** Set when this process is a `ClusterManager` worker. */\n readonly #cluster: ClusterContext | null;\n /** The parent's IDENTIFY queue, when it coordinates this cluster's IDENTIFYs. */\n readonly #identifyGate?: IdentifySlotGate;\n /** Which resources Gateway events are allowed to cache. */\n readonly #collectors = new Set<{ stop(reason?: string): void }>();\n readonly #cache: Required<\n Omit<NonNullable<ClientOptions[\"cache\"]>, \"maxMembers\" | \"maxUsers\">\n >;\n readonly #resourceContext: ResourceContext;\n /** Whether the `Guilds` intent is on, so `client.guilds` lists every guild the bot is in. */\n readonly #guildsIntent: boolean;\n\n public constructor(public readonly options: ClientOptions) {\n super();\n const client = this;\n this.voice = new VoiceManager({\n get userId() {\n return client.user?.id;\n },\n canSendVoiceState: (guildId) => client.#gateway.ownsGuild(guildId),\n sendVoiceState: (guildId, channelId, voiceOptions) =>\n client.#gateway.sendVoiceState(\n guildId,\n channelId,\n voiceOptions,\n ),\n });\n if (!options.token?.trim())\n throw new TypeError(\"Client token is required.\");\n this.rest = new REST({ token: options.token, ...options.rest });\n this.#cache = {\n users: true,\n members: true,\n roles: true,\n emojis: true,\n presences: false,\n ...options.cache,\n };\n this.#guildsIntent =\n Array.isArray(options.intents) &&\n (resolveGatewayIntents(options.intents) &\n GatewayIntentBits.Guilds) !==\n 0;\n this.users = new UserManager(this.rest, {\n maxSize: options.cache?.maxUsers,\n });\n this.guilds = new GuildManager(this.rest, {\n maxMembers: options.cache?.maxMembers,\n });\n this.channels = new ChannelManager(this.rest, {\n messageCache: options.messageCache,\n allowedMentions: options.allowedMentions,\n });\n this.stageInstances = new StageInstanceManager(this.rest);\n const placeholderAppCommands = new ApplicationCommandManager(\n this.rest,\n \"0\",\n );\n this.application = { commands: placeholderAppCommands };\n this.#resourceContext = this.#createResourceContext();\n this.guilds.attachContext(this.#resourceContext);\n this.#cluster = readClusterContext();\n const shardId = options.gateway?.shardId;\n // In a coordinated cluster, every IDENTIFY of this shard (the first in\n // login(), and re-IDENTIFYs after a lost session) waits for the\n // parent's queue, so all clusters together respect Discord's limits.\n const gate =\n this.#cluster?.coordinatedIdentify && shardId !== undefined\n ? ClusterWorker.current()?.identifyGate\n : undefined;\n this.#identifyGate = gate;\n this.#gateway = new Gateway({\n token: options.token,\n intents: options.intents,\n ...(options.compress === undefined\n ? {}\n : { compress: options.compress }),\n ...(gate\n ? {\n identifyGate: {\n acquire: () => gate.acquire(shardId!),\n release: () => gate.release(shardId!),\n },\n }\n : {}),\n ...options.gateway,\n });\n\n this.#wireLifecycle();\n this.#wireMessages();\n this.#wireGuilds();\n this.#wireGuildFeatures();\n this.#wireChannels();\n this.#wireMisc();\n }\n\n /** Callbacks structures use to act through this client (send, edit, kick...). */\n #createResourceContext(): ResourceContext {\n return {\n sendMessage: (channelId, options) =>\n this.channels.send(channelId, options),\n editMessage: (channelId, messageId, options) =>\n this.channels.editMessage(channelId, messageId, options),\n deleteMessage: (channelId, messageId, reason) =>\n this.channels.deleteMessage(channelId, messageId, reason),\n crosspostMessage: (channelId, messageId) =>\n this.channels.crosspostMessage(channelId, messageId),\n editChannel: (channelId, options) =>\n this.channels.edit(channelId, options),\n deleteChannel: (channelId, reason) =>\n this.channels.remove(channelId, reason),\n addReaction: (channelId, messageId, emoji) =>\n this.channels.addReaction(channelId, messageId, emoji),\n removeOwnReaction: (channelId, messageId, emoji) =>\n this.channels.removeOwnReaction(channelId, messageId, emoji),\n removeReaction: (channelId, messageId, emoji, userId) =>\n this.channels.removeReaction(\n channelId,\n messageId,\n emoji,\n userId,\n ),\n removeAllReactions: (channelId, messageId) =>\n this.channels.removeAllReactions(channelId, messageId),\n pinMessage: (channelId, messageId, reason) =>\n this.channels.pinMessage(channelId, messageId, reason),\n unpinMessage: (channelId, messageId, reason) =>\n this.channels.unpinMessage(channelId, messageId, reason),\n collectInteractions: (options) =>\n this.createCollector(ClientEvent.InteractionCreate, options),\n cachedChannel: (channelId) => {\n const channel = this.channels.get(channelId);\n return channel && !channel.partial ? channel : undefined;\n },\n memberPermissions: (\n guildId,\n memberId,\n roleIds,\n channelId,\n timedOutUntil,\n ) =>\n this.#memberPermissions(\n guildId,\n memberId,\n roleIds,\n channelId,\n timedOutUntil,\n ),\n kickMember: (guildId, userId, reason) =>\n this.guilds.members(guildId).kick(userId, reason),\n banMember: (guildId, userId, options) =>\n this.guilds.members(guildId).ban(userId, options),\n editMember: (guildId, userId, options, reason) =>\n this.guilds.members(guildId).edit(userId, {\n ...options,\n reason:\n typeof options.reason === \"string\"\n ? options.reason\n : reason,\n }),\n addMemberRole: (guildId, userId, roleId, reason) =>\n this.guilds.members(guildId).addRole(userId, roleId, reason),\n removeMemberRole: (guildId, userId, roleId, reason) =>\n this.guilds.members(guildId).removeRole(userId, roleId, reason),\n editPermissionOverwrite: async (\n channelId,\n targetId,\n changes,\n options,\n ) => {\n const bits = { allow: 0n, deny: 0n, inherit: 0n };\n for (const [name, value] of Object.entries(changes)) {\n // Names only: a number or bit string here is a mistake, not a permission.\n if (!/^[A-Za-z]+$/.test(name))\n throw new TypeError(`Unknown permission: ${name}`);\n let bit: bigint;\n try {\n bit = new PermissionSet(name).bitfield;\n } catch {\n throw new TypeError(`Unknown permission: ${name}`);\n }\n const key =\n value === true\n ? \"allow\"\n : value === false\n ? \"deny\"\n : \"inherit\";\n bits[key] |= bit;\n }\n return this.channels\n .permissionOverwrites(channelId)\n .update(targetId, bits, options);\n },\n };\n }\n\n /** Session lifecycle: ready, resume, open and close. */\n #wireLifecycle(): void {\n // ── Lifecycle ────────────────────────────────────────────────────────────\n this.#gateway.on(\"READY\", (data) => {\n const ready = data as APIReadyEvent;\n this.user = ready.user;\n this.users.set(this.user.id, new User(this.user));\n this.readyAt = new Date();\n this.state = \"ready\";\n const appId = ready.application?.id ?? this.user.id;\n (\n this.application as { commands: ApplicationCommandManager }\n ).commands = new ApplicationCommandManager(this.rest, appId);\n if (this.monetization?.applicationId !== appId)\n this.monetization = new MonetizationManager(this.rest, appId);\n if (this.applicationEmojis?.applicationId !== appId)\n this.applicationEmojis = new ApplicationEmojiManager(\n this.rest,\n appId,\n );\n this.emit(ClientEvent.Ready, this.user);\n });\n this.#gateway.on(\"RESUMED\", () => {\n this.state = \"ready\";\n this.emit(ClientEvent.Resumed);\n });\n this.#gateway.on(\"invalidSession\", (isRecoverable) => {\n this.emit(ClientEvent.InvalidSession, isRecoverable as boolean);\n });\n this.#gateway.on(\"open\", () => this.emit(ClientEvent.Open));\n this.#gateway.on(\"close\", (data) => {\n if (this.state !== \"destroyed\") this.state = \"idle\";\n this.emit(\n ClientEvent.Close,\n data as { code: number; action: string },\n );\n });\n }\n\n /** Messages, reactions and polls. */\n #wireMessages(): void {\n // ── Messages ─────────────────────────────────────────────────────────────\n this.#gateway.on(\"MESSAGE_CREATE\", (data) => {\n const payload = data as import(\"@lunibee/types\").APIMessage;\n const message = new Message(payload, this.#resourceContext);\n this.#observeMessage(message);\n // The author's member (roles, nickname) comes with every guild\n // message; keep the cached member current with it.\n if (\n payload.member &&\n payload.guild_id &&\n this.guilds.has(payload.guild_id)\n )\n this.#upsertMember(payload.guild_id, {\n ...payload.member,\n user: payload.member.user ?? payload.author,\n } as APIGuildMember);\n // With messageCache enabled, Gateway messages enter the bounded\n // cache so later edits and deletes can see the previous content;\n // listeners get the cached instance.\n const cached = this.options.messageCache\n ? this.channels\n .messages(message.channelId)\n .upsert(data as import(\"@lunibee/types\").APIMessage)\n : message;\n this.emit(ClientEvent.MessageCreate, cached);\n });\n this.#gateway.on(\"MESSAGE_UPDATE\", (data) => {\n const partial = data as import(\"@lunibee/types\").APIMessage;\n if (!partial.author) {\n // Discord sends only the changed fields for some updates\n // (an embed unfurl, say). With no author there is nothing to\n // build a message from: patch the cached one, or ignore it.\n const cachedMessage = this.channels\n .cachedMessages(partial.channel_id)\n ?.cache.peek(partial.id);\n if (!cachedMessage) return;\n const before = this.listenerCount(ClientEvent.MessageUpdate)\n ? this.#snapshot(cachedMessage)\n : null;\n if (partial.content !== undefined)\n cachedMessage.content = partial.content;\n this.emit(ClientEvent.MessageUpdate, cachedMessage, before);\n return;\n }\n const message = new Message(\n data as import(\"@lunibee/types\").APIMessage,\n this.#resourceContext,\n );\n this.#observeMessage(message);\n // The cached message is replaced, not merged, so listeners receive\n // the previous version intact alongside the new one.\n const messages = this.channels.cachedMessages(message.channelId);\n const previous = messages?.cache.peek(message.id);\n if (previous) messages!.set(message.id, message);\n this.emit(ClientEvent.MessageUpdate, message, previous ?? null);\n });\n this.#gateway.on(\"MESSAGE_DELETE\", (data) => {\n const payload = data as APIMessageDeleteEvent;\n const messages = this.channels.cachedMessages(payload.channel_id);\n const removed = messages?.cache.peek(payload.id);\n messages?.delete(payload.id);\n this.emit(ClientEvent.MessageDelete, payload, removed);\n });\n this.#gateway.on(\"MESSAGE_DELETE_BULK\", (data) => {\n const payload = data as APIMessageDeleteBulkEvent;\n const messages = this.channels.cachedMessages(payload.channel_id);\n const removed: Message[] = [];\n if (messages)\n for (const id of payload.ids) {\n const message = messages.cache.peek(id);\n if (message) removed.push(message);\n messages.delete(id);\n }\n this.emit(ClientEvent.MessageDeleteBulk, payload, removed);\n });\n\n // ── Reactions ────────────────────────────────────────────────────────────\n this.#gateway.on(\"MESSAGE_REACTION_ADD\", (data) =>\n this.emit(\n ClientEvent.MessageReactionAdd,\n data as APIMessageReactionEvent,\n ),\n );\n this.#gateway.on(\"MESSAGE_REACTION_REMOVE\", (data) =>\n this.emit(\n ClientEvent.MessageReactionRemove,\n data as APIMessageReactionEvent,\n ),\n );\n this.#gateway.on(\"MESSAGE_REACTION_REMOVE_ALL\", (data) =>\n this.emit(\n ClientEvent.MessageReactionRemoveAll,\n data as APIMessageDeleteEvent,\n ),\n );\n this.#gateway.on(\"MESSAGE_REACTION_REMOVE_EMOJI\", (data) =>\n this.emit(\n ClientEvent.MessageReactionRemoveEmoji,\n data as APIMessageReactionRemoveEmojiEvent,\n ),\n );\n\n // ── Polls ────────────────────────────────────────────────────────────────\n this.#gateway.on(\"MESSAGE_POLL_VOTE_ADD\", (data) =>\n this.emit(\n ClientEvent.MessagePollVoteAdd,\n data as APIMessagePollVoteEvent,\n ),\n );\n this.#gateway.on(\"MESSAGE_POLL_VOTE_REMOVE\", (data) =>\n this.emit(\n ClientEvent.MessagePollVoteRemove,\n data as APIMessagePollVoteEvent,\n ),\n );\n }\n\n /** Guilds, members, bans and roles. */\n #wireGuilds(): void {\n // ── Guilds ───────────────────────────────────────────────────────────────\n this.#gateway.on(\"GUILD_CREATE\", (data) => {\n const payload = data as APIGuild & {\n members?: APIGuildMember[];\n voice_states?: APIVoiceState[];\n channels?: APIChannel[];\n threads?: APIChannel[];\n unavailable?: boolean;\n };\n if (payload.unavailable) {\n this.emit(ClientEvent.GuildUnavailable, payload);\n return;\n }\n // A guild already in cache that arrives again (e.g. after an outage\n // or gateway resume) has become *available* rather than newly joined.\n // guildAvailable (a known guild comes back) vs. guildCreate (a new guild).\n const wasCached = this.guilds.has(payload.id);\n this.guilds.patch(payload);\n for (const role of payload.roles ?? [])\n this.#upsertRole(payload.id, role);\n if (this.#cache.emojis) {\n const emojis = this.guilds.emojis(payload.id);\n for (const emoji of payload.emojis ?? []) emojis.upsert(emoji);\n }\n for (const member of payload.members ?? [])\n this.#upsertMember(payload.id, member);\n for (const state of payload.voice_states ?? [])\n this.#storeVoiceState(payload.id, state);\n // Channels in GUILD_CREATE omit guild_id; restore it so the\n // channel can be cleaned up with its guild.\n for (const channelData of [\n ...(payload.channels ?? []),\n ...(payload.threads ?? []),\n ])\n this.channels.upsert({ ...channelData, guild_id: payload.id });\n this.emit(\n wasCached\n ? ClientEvent.GuildAvailable\n : ClientEvent.GuildCreate,\n payload,\n );\n });\n this.#gateway.on(\"GUILD_UPDATE\", (data) => {\n const payload = data as APIGuild;\n // The copy of the previous state is only made for a listener.\n const cached = this.listenerCount(ClientEvent.GuildUpdate)\n ? this.guilds.get(payload.id)\n : undefined;\n const previous = cached ? this.#snapshot(cached) : null;\n this.guilds.patch(payload);\n this.emit(ClientEvent.GuildUpdate, payload, previous);\n });\n this.#gateway.on(\"GUILD_DELETE\", (data) => {\n const payload = data as { id: string; unavailable?: boolean };\n if (payload.unavailable) {\n this.emit(ClientEvent.GuildUnavailable, payload);\n return;\n }\n this.guilds.delete(payload.id);\n this.channels.deleteGuildChannels(payload.id);\n this.voice.handleGuildRemove(payload.id);\n this.emit(ClientEvent.GuildDelete, payload);\n });\n\n // ── Guild Members ────────────────────────────────────────────────────────\n this.#gateway.on(\"GUILD_MEMBER_ADD\", (data) => {\n const member = data as GuildMemberEvent;\n this.#upsertMember(member.guild_id, member);\n this.emit(ClientEvent.GuildMemberAdd, member);\n });\n this.#gateway.on(\"GUILD_MEMBER_UPDATE\", (data) => {\n const member = data as GuildMemberEvent;\n const cached =\n this.#cache.members && !this.#guildGone(member.guild_id)\n ? this.guilds.members(member.guild_id).get(member.user.id)\n : undefined;\n // A fresh instance keeps the client context (a private field).\n const previous =\n cached && this.listenerCount(ClientEvent.GuildMemberUpdate)\n ? this.#snapshot(\n cached,\n new GuildMember(\n { user: member.user, guild_id: member.guild_id },\n this.#resourceContext,\n ),\n )\n : null;\n this.#upsertMember(member.guild_id, member);\n this.emit(ClientEvent.GuildMemberUpdate, member, previous);\n });\n this.#gateway.on(\"GUILD_MEMBER_REMOVE\", (data) => {\n const member = data as GuildMemberEvent;\n // A guild the bot has left has no per-guild state to clean up;\n // creating it here would leak an empty manager for that guild.\n if (!this.#guildGone(member.guild_id))\n this.guilds.members(member.guild_id).delete(member.user.id);\n this.emit(ClientEvent.GuildMemberRemove, member);\n });\n this.#gateway.on(\"GUILD_MEMBERS_CHUNK\", (data) => {\n const chunk = data as APIGuildMembersChunk;\n for (const member of chunk.members)\n this.#upsertMember(chunk.guild_id, member);\n this.emit(ClientEvent.GuildMembersChunk, chunk);\n });\n\n // ── Guild Bans ───────────────────────────────────────────────────────────\n this.#gateway.on(\"GUILD_BAN_ADD\", (data) => {\n const ban = data as APIGuildBanEvent;\n if (!this.#guildGone(ban.guild_id)) {\n const bans = this.guilds.bans(ban.guild_id);\n // Keep a reason already fetched over REST; the event carries none.\n bans.set(ban.user.id, {\n reason: bans.get(ban.user.id)?.reason ?? null,\n user: ban.user,\n });\n this.guilds.members(ban.guild_id).delete(ban.user.id);\n }\n this.emit(ClientEvent.GuildBanAdd, ban);\n });\n this.#gateway.on(\"GUILD_BAN_REMOVE\", (data) => {\n const ban = data as APIGuildBanEvent;\n if (!this.#guildGone(ban.guild_id))\n this.guilds.bans(ban.guild_id).delete(ban.user.id);\n this.emit(ClientEvent.GuildBanRemove, ban);\n });\n\n // ── Guild Roles ──────────────────────────────────────────────────────────\n this.#gateway.on(\"GUILD_ROLE_CREATE\", (data) => {\n const event = data as APIGuildRoleEvent;\n this.#upsertRole(event.guild_id, event.role);\n this.emit(ClientEvent.GuildRoleCreate, event);\n });\n this.#gateway.on(\"GUILD_ROLE_UPDATE\", (data) => {\n const event = data as APIGuildRoleEvent;\n const cached = this.#cache.roles\n ? this.guilds.roles(event.guild_id).get(event.role.id)\n : undefined;\n const previous =\n cached && this.listenerCount(ClientEvent.GuildRoleUpdate)\n ? this.#snapshot(cached)\n : null;\n this.#upsertRole(event.guild_id, event.role);\n this.emit(ClientEvent.GuildRoleUpdate, event, previous);\n });\n this.#gateway.on(\"GUILD_ROLE_DELETE\", (data) => {\n const event = data as APIGuildRoleDeleteEvent;\n const roles = this.guilds.roles(event.guild_id);\n const removed = roles.get(event.role_id) ?? null;\n roles.delete(event.role_id);\n this.emit(ClientEvent.GuildRoleDelete, event, removed);\n });\n }\n\n /** Guild emojis, stickers, soundboard, monetization, integrations, scheduled events and AutoMod. */\n #wireGuildFeatures(): void {\n // ── Guild Emojis & Stickers ──────────────────────────────────────────────\n this.#gateway.on(\"GUILD_EMOJIS_UPDATE\", (data) => {\n const event = data as APIGuildEmojisUpdateEvent;\n let previous: Emoji[] | null = null;\n // The event carries the guild's full emoji list.\n if (this.#cache.emojis) {\n const emojis = this.guilds.emojis(event.guild_id);\n if (this.listenerCount(ClientEvent.GuildEmojisUpdate))\n previous = [...emojis.cache.values()].map((emoji) =>\n this.#snapshot(emoji),\n );\n const current = new Set(event.emojis.map((emoji) => emoji.id));\n for (const id of [...emojis.cache.keys()])\n if (!current.has(id)) emojis.delete(id);\n for (const emoji of event.emojis) emojis.upsert(emoji);\n }\n this.emit(ClientEvent.GuildEmojisUpdate, event, previous);\n });\n this.#gateway.on(\"GUILD_STICKERS_UPDATE\", (data) => {\n const event = data as APIGuildStickersUpdateEvent;\n // The event carries the guild's full sticker list. `sync` replaces\n // the raw objects, so the previous list needs no copying.\n const stickers = this.guilds.stickers(event.guild_id);\n const previous = [...stickers.cache.values()];\n stickers.sync(event.stickers);\n this.emit(ClientEvent.GuildStickersUpdate, event, previous);\n });\n\n // ── Soundboard ───────────────────────────────────────────────────────────\n this.#gateway.on(\"GUILD_SOUNDBOARD_SOUND_CREATE\", (data) => {\n const sound = data as APISoundboardSound;\n if (sound.guild_id)\n this.guilds\n .soundboard(sound.guild_id)\n .set(sound.sound_id, sound);\n this.emit(ClientEvent.SoundboardSoundCreate, sound);\n });\n this.#gateway.on(\"GUILD_SOUNDBOARD_SOUND_UPDATE\", (data) => {\n const sound = data as APISoundboardSound;\n if (sound.guild_id)\n this.guilds\n .soundboard(sound.guild_id)\n .set(sound.sound_id, sound);\n this.emit(ClientEvent.SoundboardSoundUpdate, sound);\n });\n this.#gateway.on(\"GUILD_SOUNDBOARD_SOUND_DELETE\", (data) => {\n const event = data as { sound_id: string; guild_id: string };\n this.guilds.soundboard(event.guild_id).delete(event.sound_id);\n this.emit(ClientEvent.SoundboardSoundDelete, event);\n });\n this.#gateway.on(\"GUILD_SOUNDBOARD_SOUNDS_UPDATE\", (data) => {\n const event = data as {\n guild_id: string;\n soundboard_sounds: APISoundboardSound[];\n };\n const sounds = this.guilds.soundboard(event.guild_id);\n sounds.clear();\n for (const sound of event.soundboard_sounds)\n sounds.set(sound.sound_id, sound);\n this.emit(ClientEvent.SoundboardSoundsUpdate, event);\n });\n\n // ── Monetization ─────────────────────────────────────────────────────────\n this.#gateway.on(\"ENTITLEMENT_CREATE\", (data) => {\n const entitlement = data as APIEntitlement;\n this.monetization?.set(entitlement.id, entitlement);\n this.emit(ClientEvent.EntitlementCreate, entitlement);\n });\n this.#gateway.on(\"ENTITLEMENT_UPDATE\", (data) => {\n const entitlement = data as APIEntitlement;\n this.monetization?.set(entitlement.id, entitlement);\n this.emit(ClientEvent.EntitlementUpdate, entitlement);\n });\n this.#gateway.on(\"ENTITLEMENT_DELETE\", (data) => {\n const entitlement = data as APIEntitlement;\n this.monetization?.delete(entitlement.id);\n this.emit(ClientEvent.EntitlementDelete, entitlement);\n });\n\n // ── Guild Integrations ───────────────────────────────────────────────────\n this.#gateway.on(\"GUILD_INTEGRATIONS_UPDATE\", (data) =>\n this.emit(\n ClientEvent.GuildIntegrationsUpdate,\n data as { guild_id: string },\n ),\n );\n\n // ── Guild Scheduled Events ───────────────────────────────────────────────\n this.#gateway.on(\"GUILD_SCHEDULED_EVENT_CREATE\", (data) => {\n const event = data as APIGuildScheduledEvent;\n this.guilds.scheduledEvents(event.guild_id).set(event.id, event);\n this.emit(ClientEvent.GuildScheduledEventCreate, event);\n });\n this.#gateway.on(\"GUILD_SCHEDULED_EVENT_UPDATE\", (data) => {\n const event = data as APIGuildScheduledEvent;\n const events = this.guilds.scheduledEvents(event.guild_id);\n const previous = events.get(event.id) ?? null;\n events.set(event.id, event);\n this.emit(ClientEvent.GuildScheduledEventUpdate, event, previous);\n });\n this.#gateway.on(\"GUILD_SCHEDULED_EVENT_DELETE\", (data) => {\n const event = data as APIGuildScheduledEvent;\n this.guilds.scheduledEvents(event.guild_id).delete(event.id);\n this.emit(ClientEvent.GuildScheduledEventDelete, event);\n });\n this.#gateway.on(\"GUILD_SCHEDULED_EVENT_USER_ADD\", (data) =>\n this.emit(\n ClientEvent.GuildScheduledEventUserAdd,\n data as APIGuildScheduledEventUserEvent,\n ),\n );\n this.#gateway.on(\"GUILD_SCHEDULED_EVENT_USER_REMOVE\", (data) =>\n this.emit(\n ClientEvent.GuildScheduledEventUserRemove,\n data as APIGuildScheduledEventUserEvent,\n ),\n );\n\n // ── AutoMod ──────────────────────────────────────────────────────────────\n this.#gateway.on(\"AUTO_MODERATION_RULE_CREATE\", (data) => {\n const rule = data as APIAutoModerationRule;\n this.guilds.autoModerationRules(rule.guild_id).set(rule.id, rule);\n this.emit(ClientEvent.AutoModerationRuleCreate, rule);\n });\n this.#gateway.on(\"AUTO_MODERATION_RULE_UPDATE\", (data) => {\n const rule = data as APIAutoModerationRule;\n const rules = this.guilds.autoModerationRules(rule.guild_id);\n const previous = rules.get(rule.id) ?? null;\n rules.set(rule.id, rule);\n this.emit(ClientEvent.AutoModerationRuleUpdate, rule, previous);\n });\n this.#gateway.on(\"AUTO_MODERATION_RULE_DELETE\", (data) => {\n const rule = data as APIAutoModerationRule;\n this.guilds.autoModerationRules(rule.guild_id).delete(rule.id);\n this.emit(ClientEvent.AutoModerationRuleDelete, rule);\n });\n this.#gateway.on(\"AUTO_MODERATION_ACTION_EXECUTION\", (data) =>\n this.emit(\n ClientEvent.AutoModerationActionExecution,\n data as APIAutoModerationActionExecution,\n ),\n );\n }\n\n /** Channels, threads, stage instances, invites and webhooks. */\n #wireChannels(): void {\n // ── Channels ─────────────────────────────────────────────────────────────\n this.#gateway.on(\"CHANNEL_CREATE\", (data) => {\n const channel = this.channels.upsert(data as APIChannel);\n this.emit(ClientEvent.ChannelCreate, channel);\n });\n this.#gateway.on(\"CHANNEL_UPDATE\", (data) => {\n const previous = this.listenerCount(ClientEvent.ChannelUpdate)\n ? this.#previousChannel(data as APIChannel)\n : null;\n const channel = this.channels.upsert(data as APIChannel);\n this.emit(ClientEvent.ChannelUpdate, channel, previous);\n });\n this.#gateway.on(\"CHANNEL_DELETE\", (data) => {\n const payload = data as APIChannel;\n const removed = this.channels.get(payload.id) ?? null;\n this.channels.delete(payload.id);\n this.emit(ClientEvent.ChannelDelete, payload, removed);\n });\n this.#gateway.on(\"CHANNEL_PINS_UPDATE\", (data) =>\n this.emit(\n ClientEvent.ChannelPinsUpdate,\n data as APIChannelPinsUpdate,\n ),\n );\n\n // ── Threads ──────────────────────────────────────────────────────────────\n this.#gateway.on(\"THREAD_CREATE\", (data) => {\n const channel = this.channels.upsert(data as APIThreadEvent);\n this.emit(ClientEvent.ThreadCreate, channel);\n });\n this.#gateway.on(\"THREAD_UPDATE\", (data) => {\n const previous = this.listenerCount(ClientEvent.ThreadUpdate)\n ? this.#previousChannel(data as APIThreadEvent)\n : null;\n const channel = this.channels.upsert(data as APIThreadEvent);\n this.emit(ClientEvent.ThreadUpdate, channel, previous);\n });\n this.#gateway.on(\"THREAD_DELETE\", (data) => {\n const payload = data as APIThreadEvent;\n const removed = this.channels.get(payload.id) ?? null;\n this.channels.delete(payload.id);\n this.emit(ClientEvent.ThreadDelete, payload, removed);\n });\n this.#gateway.on(\"THREAD_LIST_SYNC\", (data) => {\n const sync = data as APIThreadListSync;\n for (const thread of sync.threads)\n this.channels.upsert({ ...thread, guild_id: sync.guild_id });\n this.emit(ClientEvent.ThreadListSync, sync);\n });\n this.#gateway.on(\"THREAD_MEMBERS_UPDATE\", (data) =>\n this.emit(\n ClientEvent.ThreadMembersUpdate,\n data as APIThreadMembersUpdate,\n ),\n );\n this.#gateway.on(\"THREAD_MEMBER_UPDATE\", (data) =>\n this.emit(\n ClientEvent.ThreadMemberUpdate,\n data as import(\"@lunibee/types\").APIThreadMember,\n ),\n );\n\n // ── Stage Instances ──────────────────────────────────────────────────────\n this.#gateway.on(\"STAGE_INSTANCE_CREATE\", (data) => {\n const stage = data as APIStageInstance;\n this.stageInstances.set(stage.channel_id, stage);\n this.emit(ClientEvent.StageInstanceCreate, stage);\n });\n this.#gateway.on(\"STAGE_INSTANCE_UPDATE\", (data) => {\n const stage = data as APIStageInstance;\n const previous = this.stageInstances.get(stage.channel_id) ?? null;\n this.stageInstances.set(stage.channel_id, stage);\n this.emit(ClientEvent.StageInstanceUpdate, stage, previous);\n });\n this.#gateway.on(\"STAGE_INSTANCE_DELETE\", (data) => {\n const stage = data as APIStageInstance;\n this.stageInstances.delete(stage.channel_id);\n this.emit(ClientEvent.StageInstanceDelete, stage);\n });\n\n // ── Invites ──────────────────────────────────────────────────────────────\n this.#gateway.on(\"INVITE_CREATE\", (data) => {\n const invite = data as APIInviteCreate;\n if (invite.guild_id)\n this.guilds.invites(invite.guild_id).set(invite.code, invite);\n this.emit(ClientEvent.InviteCreate, invite);\n });\n this.#gateway.on(\"INVITE_DELETE\", (data) => {\n const invite = data as APIInviteDelete;\n if (invite.guild_id)\n this.guilds.invites(invite.guild_id).delete(invite.code);\n this.emit(ClientEvent.InviteDelete, invite);\n });\n\n // ── Webhooks ─────────────────────────────────────────────────────────────\n this.#gateway.on(\"WEBHOOKS_UPDATE\", (data) =>\n this.emit(ClientEvent.WebhooksUpdate, data as APIWebhooksUpdate),\n );\n }\n\n /** Voice, presence, typing, interactions, raw frames and errors. */\n #wireMisc(): void {\n // ── Voice ────────────────────────────────────────────────────────────────\n this.#gateway.on(\"VOICE_STATE_UPDATE\", (data) => {\n const state = data as APIVoiceState;\n const previous = state.guild_id\n ? (this.guilds.voiceStates(state.guild_id).get(state.user_id) ??\n null)\n : null;\n if (state.guild_id) this.#storeVoiceState(state.guild_id, state);\n this.voice.handleVoiceState({\n ...state,\n channel_id: state.channel_id ?? null,\n });\n this.emit(ClientEvent.VoiceStateUpdate, state, previous);\n });\n this.#gateway.on(\"VOICE_SERVER_UPDATE\", (data) => {\n const server = data as APIVoiceServerUpdate;\n this.voice.handleVoiceServer({\n ...server,\n endpoint: server.endpoint ?? null,\n });\n this.emit(ClientEvent.VoiceServerUpdate, server);\n });\n\n // ── Presence & Typing ────────────────────────────────────────────────────\n this.#gateway.on(\"PRESENCE_UPDATE\", (data) => {\n const presence = data as APIPresenceUpdate;\n let previous: APIPresenceUpdate | null = null;\n if (this.#cache.presences && presence.guild_id) {\n const presences = this.guilds.presences(presence.guild_id);\n previous = presences.get(presence.user.id) ?? null;\n presences.set(presence.user.id, presence);\n }\n this.emit(ClientEvent.PresenceUpdate, presence, previous);\n });\n this.#gateway.on(\"TYPING_START\", (data) =>\n this.emit(ClientEvent.TypingStart, data as APITypingStart),\n );\n\n // ── Interactions ─────────────────────────────────────────────────────────\n this.#gateway.on(\"INTERACTION_CREATE\", (data) =>\n this.emit(\n ClientEvent.InteractionCreate,\n createInteraction(this, data as InteractionData),\n ),\n );\n\n // ── Raw / Error ───────────────────────────────────────────────────────────\n this.#gateway.on(\"RAW\", (data) =>\n this.emit(\n ClientEvent.Raw,\n data as { event: string; data: unknown },\n ),\n );\n this.#gateway.on(\"error\", (error) =>\n this.emit(ClientEvent.Error, error as Error),\n );\n }\n\n /**\n * Convenience method to connect the bot to Discord.\n * Optionally overrides the configured token.\n * @param token Optional token override.\n * @returns The token used to log in.\n * @throws {TypeError} If the resulting token is empty.\n */\n /** Caches a message's author, and its channel only when none is cached: the\n * message carries a stub channel that must not overwrite a full one. */\n #observeMessage(message: Message): void {\n if (!this.channels.has(message.channelId))\n this.channels.set(message.channelId, message.channel);\n if (this.#cache.users)\n this.#merge(this.users, message.author.id, message.author);\n }\n\n #upsertMember(guildId: string, data: APIGuildMember): GuildMember {\n const member = new GuildMember(\n { ...data, guild_id: guildId },\n this.#resourceContext,\n );\n if (this.#cache.users)\n this.#merge(this.users, member.user.id, member.user);\n // Members of a guild the bot has left are not kept: they would sit\n // in a per-guild manager nothing prunes.\n if (!this.#cache.members || this.#guildGone(guildId)) return member;\n const members = this.guilds.members(guildId);\n const known = members.get(member.user.id);\n const timedOutUntil = known?.timedOutUntil;\n const merged = this.#merge(members, member.user.id, member);\n // A partial member (the one on a message) leaves the timeout out; that\n // is \"not sent\", not \"no timeout\", so the cached value stays.\n if (\n known &&\n timedOutUntil !== undefined &&\n data.communication_disabled_until === undefined\n )\n merged.timedOutUntil = timedOutUntil;\n return merged;\n }\n\n /**\n * Whether a guild is known not to be the bot's: with the `Guilds` intent\n * every guild arrives in `GUILD_CREATE` first, so an uncached one was left\n * (or never joined). Without that intent nothing is known, so nothing is.\n */\n #guildGone(guildId: string): boolean {\n return this.#guildsIntent && !this.guilds.has(guildId);\n }\n\n /** A voice state without a channel means the user left voice. */\n #storeVoiceState(guildId: string, state: APIVoiceState): void {\n const states = this.guilds.voiceStates(guildId);\n if (state.channel_id) states.set(state.user_id, state);\n else states.delete(state.user_id);\n }\n\n #upsertRole(guildId: string, data: APIRole): Role {\n if (!this.#cache.roles) return new Role(data);\n return this.#merge(this.guilds.roles(guildId), data.id, new Role(data));\n }\n\n /**\n * Copies a cached structure's fields before an in-place merge changes them.\n * Pass `blank` (a fresh instance of the same class) when the class has\n * private fields, so the copy keeps them.\n */\n #snapshot<T extends object>(\n cached: T,\n blank: T = Object.create(Object.getPrototypeOf(cached)) as T,\n ): T {\n // A key loop: Object.assign into an Object.create() object takes the\n // slow path (about 3x slower for a Guild). Structures hold no\n // symbol-keyed fields, so own string keys are all there is to copy.\n const from = cached as Record<string, unknown>;\n const into = blank as Record<string, unknown>;\n for (const key of Object.keys(from)) into[key] = from[key];\n return blank;\n }\n\n /** A copy of the cached channel an update is about to change, or null. */\n #previousChannel(data: APIChannel): Channel | null {\n const cached = this.channels.get(data.id);\n if (!cached) return null;\n // Channel keeps its client context in a private field; build the copy\n // through the same factory so it keeps the subclass and the context.\n return this.#snapshot(\n cached,\n createChannel(\n { id: cached.id, type: cached.type, guild_id: cached.guildId },\n this.#resourceContext,\n ),\n );\n }\n\n /** Merges `next` into the cached instance so references stay valid.\n * Fields a partial payload left undefined keep their cached value. */\n #merge<T extends object>(\n manager: {\n get(id: string): T | undefined;\n set(id: string, value: T): unknown;\n },\n id: string,\n next: T,\n ): T {\n const existing = manager.get(id);\n if (!existing) {\n manager.set(id, next);\n return next;\n }\n // A key loop: Object.entries allocates a pair per field, on every event.\n const from = next as Record<string, unknown>;\n const into = existing as Record<string, unknown>;\n for (const key of Object.keys(from)) {\n const value = from[key];\n if (value !== undefined) into[key] = value;\n }\n // Storing it again marks a REST fetch in flight for this key as\n // stale, so the older REST answer cannot undo this update.\n manager.set(id, existing);\n return existing;\n }\n\n /**\n * Collects the first argument of a client event until a limit, timeout,\n * idle timeout, abort or `stop()`. The collector unsubscribes itself when\n * it ends. Items are keyed by `options.key`, else their `id`, else order.\n */\n public createCollector<E extends keyof ClientEvents>(\n event: E,\n options: CollectorOptions<ClientEvents[E][0]> & {\n key?: (item: ClientEvents[E][0]) => string;\n } = {},\n ): Collector<string, ClientEvents[E][0]> {\n const collector = new Collector<string, ClientEvents[E][0]>(options);\n let order = 0;\n const listener = (...args: ClientEvents[E]): void => {\n const item = args[0];\n const id = (item as { id?: unknown } | null | undefined)?.id;\n const key =\n options.key?.(item) ??\n (typeof id === \"string\" ? id : String(order++));\n collector\n .handle(key, item)\n .catch((error: unknown) =>\n this.emit(\n ClientEvent.Error,\n error instanceof Error\n ? error\n : new Error(String(error)),\n ),\n );\n };\n this.on(event, listener);\n this.#collectors.add(collector);\n collector.onDispose(() => {\n this.off(event, listener);\n this.#collectors.delete(collector);\n });\n return collector;\n }\n\n /**\n * Names a guild by id. The handle reads it (`peek()` from the cache, `get()`\n * from the cache or Discord, `fetch()` from Discord) and acts on it.\n */\n public guild(id: string): GuildHandle {\n return new GuildHandle(this, id);\n }\n /** Names a channel by id; see {@link Client.guild} for the read methods. */\n public channel(id: string): ChannelHandle {\n return new ChannelHandle(this, id);\n }\n /**\n * Names a user by id; see {@link Client.guild} for the read methods.\n * (`bot.user` is the bot's own account, hence the different name.)\n */\n public person(id: string): UserHandle {\n return new UserHandle(this, id);\n }\n /** Names a guild member by guild id and user id. */\n public member(guildId: string, userId: string): MemberHandle {\n return new MemberHandle(this, guildId, userId);\n }\n /** Names a role by guild id and role id. */\n public role(guildId: string, roleId: string): RoleHandle {\n return new RoleHandle(this, guildId, roleId);\n }\n /** Names a message by channel id and message id. */\n public message(channelId: string, messageId: string): MessageHandle {\n return new MessageHandle(this, channelId, messageId);\n }\n\n /** Structures built by this client (members from interactions...) act through this. */\n public get resourceContext(): ResourceContext {\n return this.#resourceContext;\n }\n\n /** Guild- or channel-level permissions from a member's role IDs and the cached roles and overwrites. */\n #memberPermissions(\n guildId: string,\n memberId: string,\n roleIds: readonly string[],\n channelId?: string,\n timedOutUntil?: Date | null,\n ): PermissionSet | null {\n const guild = this.guilds.get(guildId);\n if (!guild) return null;\n let channel = channelId ? this.channels.get(channelId) : undefined;\n if (channelId) {\n // Threads use their parent's overwrites; without it the answer is unknown.\n if (channel?.isThread())\n channel = channel.parentId\n ? this.channels.get(channel.parentId)\n : undefined;\n if (!channel || channel.partial || channel.guildId !== guildId)\n return null;\n }\n return computePermissions({\n guildId,\n ownerId: guild.ownerId,\n memberId,\n memberRoleIds: [...roleIds],\n roles: this.guilds.roles(guildId).values(),\n overwrites: channel?.permissionOverwrites,\n timedOutUntil,\n });\n }\n\n /**\n * Resolves a member's permissions from cached state: guild-level for a\n * guild ID, or channel-level (including overwrites) for a cached channel\n * ID. Returns null when the guild or member is not cached.\n */\n public permissionsFor(\n memberId: string,\n guildOrChannelId: string,\n ): PermissionSet | null {\n let channel = this.channels.get(guildOrChannelId);\n // A placeholder's overwrites are unknown: so is the answer.\n if (channel?.partial) return null;\n // Threads have no overwrites of their own: they use the parent's.\n // Without a cached parent the answer would be guild-level only, which\n // could wrongly grant access, so report it as unknown instead.\n if (channel?.isThread()) {\n channel = channel.parentId\n ? this.channels.get(channel.parentId)\n : undefined;\n if (!channel || channel.partial) return null;\n }\n const guildId = channel?.guildId ?? guildOrChannelId;\n const guild = this.guilds.get(guildId);\n const member = this.guilds.members(guildId).get(memberId);\n if (!guild || !member) return null;\n return computePermissions({\n guildId,\n ownerId: guild.ownerId,\n memberId,\n memberRoleIds: member.roleIds,\n roles: this.guilds.roles(guildId).values(),\n overwrites: channel?.permissionOverwrites,\n timedOutUntil: member.timedOutUntil,\n });\n }\n\n /** Fetches Discord's default soundboard sounds. */\n public fetchDefaultSoundboardSounds(): Promise<APISoundboardSound[]> {\n return this.rest.get<APISoundboardSound[]>(\n Routes.soundboardDefaultSounds(),\n );\n }\n\n /**\n * Connects to the Gateway. Resolves with the token used;\n * do not log the return value.\n */\n public async login(token?: string): Promise<string> {\n if (this.state === \"destroyed\")\n throw new Error(\"Cannot login a destroyed client.\");\n if (token?.trim()) {\n this.rest.setToken(token);\n this.options.token = token;\n }\n const usedToken = this.options.token;\n if (!usedToken?.trim())\n throw new TypeError(\"A bot token is required to log in.\");\n const shardId = this.#assertClusterShard();\n this.state = \"connecting\";\n if (this.#identifyGate && shardId !== undefined)\n await connectInQueue(this.#gateway, shardId, this.#identifyGate, {\n waitForReady: this.#cluster?.startup === \"sequential\",\n readyTimeout: this.#cluster?.readyTimeout,\n });\n else await this.#gateway.connect();\n return usedToken;\n }\n\n /**\n * Inside a cluster worker a Client must run one of that cluster's shards,\n * with the deployment's total shard count: otherwise it would IDENTIFY\n * outside the cluster's assignment (every cluster as shard 0, or unsharded).\n * @returns The shard ID, or `undefined` outside a cluster.\n * @throws {Error} When the shard is missing or not this cluster's.\n */\n #assertClusterShard(): number | undefined {\n const cluster = this.#cluster;\n if (!cluster) return undefined;\n const { shardId, shardCount } = this.options.gateway ?? {};\n const fix = `new Client({ …, gateway: { shardId, shardCount: ${cluster.shardCount} } }) with shardId one of ${cluster.shardIds.join(\", \")}, or a ShardManager to run them all`;\n if (shardId === undefined)\n throw new Error(\n `This process is cluster ${cluster.clusterId}'s worker: use ${fix}.`,\n );\n if (!cluster.shardIds.includes(shardId))\n throw new Error(\n `Shard ${shardId} belongs to another cluster; cluster ${cluster.clusterId} runs ${cluster.shardIds.join(\", \")}. Use ${fix}.`,\n );\n if (shardCount !== cluster.shardCount)\n throw new Error(\n `gateway.shardCount must be the deployment's ${cluster.shardCount} shards (got ${String(shardCount)}).`,\n );\n return shardId;\n }\n\n /**\n * Destroys the client, permanently closing the Gateway connection.\n */\n public destroy(): void {\n this.state = \"destroyed\";\n // Leave voice channels while the Gateway can still send op 4.\n this.voice.destroy();\n this.#gateway.close();\n // Collectors hold timers and listeners, and the caches hold every\n // structure the bot has seen: release both.\n for (const collector of [...this.#collectors])\n collector.stop(\"destroyed\");\n this.users.clear();\n this.guilds.clear();\n this.channels.clear();\n }\n\n // ── InteractionClient implementation ─────────────────────────────────────\n\n public postInteractionResponse(\n id: string,\n token: string,\n response: import(\"@lunibee/structures\").InteractionResponse,\n ): Promise<unknown> {\n const json = response.toJSON();\n // `?with_response=true` makes Discord return the created message.\n const callback = response.withResponse\n ? `${Routes.interactionCallback(id, token)}?with_response=true`\n : Routes.interactionCallback(id, token);\n // Only message responses (4 reply, 7 update) carry mentions; a modal or a deferral does not.\n const carriesMessage = json.type === 4 || json.type === 7;\n // Files in the reply turn the callback into an upload.\n const upload = json.data\n ? toRequest(\n json.data,\n carriesMessage ? this.options.allowedMentions : undefined,\n )\n : undefined;\n return this.rest.post(\n callback,\n upload === undefined ? json : { ...json, data: upload.body },\n { files: upload?.files },\n );\n }\n public editInteractionReply(\n token: string,\n data: Record<string, unknown>,\n applicationId?: string,\n ): Promise<unknown> {\n // The interaction's application ID, which differs from the bot user's\n // ID for some older applications.\n const appId = applicationId ?? this.user?.id;\n if (!appId)\n return Promise.reject(new Error(\"Client is unauthenticated.\"));\n const { body, files } = toRequest(data, this.options.allowedMentions);\n return this.rest.patch(\n Routes.interactionOriginalResponse(appId, token),\n body,\n { files },\n );\n }\n public deleteInteractionReply(\n token: string,\n applicationId?: string,\n ): Promise<void> {\n const appId = applicationId ?? this.user?.id;\n if (!appId)\n return Promise.reject(new Error(\"Client is unauthenticated.\"));\n return this.rest.delete(\n Routes.interactionOriginalResponse(appId, token),\n );\n }\n public async followUpInteraction(\n token: string,\n data: Record<string, unknown>,\n applicationId?: string,\n ): Promise<unknown> {\n const appId = applicationId ?? this.user?.id;\n if (!appId)\n return Promise.reject(new Error(\"Client is unauthenticated.\"));\n const { body, files } = toRequest(data, this.options.allowedMentions);\n return this.rest.post(Routes.webhook(appId, token), body, { files });\n }\n public interactionWebhookMessage(\n method: \"GET\" | \"PATCH\" | \"DELETE\",\n applicationId: string,\n token: string,\n messageId: string,\n data?: Record<string, unknown>,\n ): Promise<unknown> {\n const path =\n messageId === \"@original\"\n ? Routes.interactionOriginalResponse(applicationId, token)\n : Routes.webhookMessage(applicationId, token, messageId);\n if (method === \"GET\") return this.rest.get(path);\n if (method === \"PATCH\") {\n const request = data\n ? toRequest(data, this.options.allowedMentions)\n : undefined;\n return this.rest.patch(path, request?.body, {\n files: request?.files,\n });\n }\n return this.rest.delete(path);\n }\n\n // ── Client Utilities ─────────────────────────────────────────────────────\n\n /** Fetches a webhook from Discord. */\n public async fetchWebhook(\n id: string,\n token?: string,\n ): Promise<Record<string, unknown>> {\n return this.rest.get(Routes.webhook(id, token)) as Promise<\n Record<string, unknown>\n >;\n }\n\n /** Fetches a guild preview from Discord. */\n public async fetchGuildPreview(\n guildId: string,\n ): Promise<Record<string, unknown>> {\n return this.rest.get(Routes.guildPreview(guildId)) as Promise<\n Record<string, unknown>\n >;\n }\n\n /** Fetches the voice regions from Discord. */\n public fetchVoiceRegions(): Promise<Record<string, unknown>[]> {\n return this.rest.get(\"/voice/regions\") as Promise<\n Record<string, unknown>[]\n >;\n }\n\n /** Fetches an invite from Discord. */\n public fetchInvite(\n code: string,\n options?: {\n withCounts?: boolean;\n guildScheduledEventId?: string;\n },\n ): Promise<Record<string, unknown>> {\n const query = new URLSearchParams();\n if (options?.withCounts) query.set(\"with_counts\", \"true\");\n if (options?.guildScheduledEventId)\n query.set(\n \"guild_scheduled_event_id\",\n options.guildScheduledEventId,\n );\n const qs = query.toString();\n return this.rest.get(\n `/invites/${encodeURIComponent(code)}${qs ? `?${qs}` : \"\"}`,\n ) as Promise<Record<string, unknown>>;\n }\n\n /** Fetches a sticker from Discord. */\n public async fetchSticker(id: string): Promise<Record<string, unknown>> {\n return this.rest.get(Routes.sticker(id)) as Promise<\n Record<string, unknown>\n >;\n }\n\n /** Fetches premium sticker packs from Discord. */\n public fetchPremiumStickerPacks(): Promise<Record<string, unknown>> {\n return this.rest.get(Routes.stickerPacks()) as Promise<\n Record<string, unknown>\n >;\n }\n\n /** Fetches a guild template from Discord. */\n public fetchGuildTemplate(code: string): Promise<Record<string, unknown>> {\n return this.rest.get(\n `/guilds/templates/${encodeURIComponent(code)}`,\n ) as Promise<Record<string, unknown>>;\n }\n\n /** Generates an invite link for this client. */\n public generateInvite(options?: {\n scopes?: string[];\n permissions?: string | bigint;\n }): string {\n if (!this.user)\n throw new Error(\"Client must be ready to generate invite.\");\n const params = new URLSearchParams({\n client_id: this.user.id,\n scope: (options?.scopes ?? [\"bot\"]).join(\" \"),\n });\n if (options?.permissions) {\n params.set(\"permissions\", String(options.permissions));\n }\n return `https://discord.com/api/oauth2/authorize?${params.toString()}`;\n }\n}\n"
|
|
13
|
+
],
|
|
14
|
+
"mappings": "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",
|
|
15
|
+
"debugId": "BA934EB30EED6CAE64756E2164756E21",
|
|
16
|
+
"names": []
|
|
17
|
+
}
|