UNPKG

seyfert

Version:

The most advanced framework for discord bots

508 lines (507 loc) 20 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ModalSubmitInteraction = exports.MessageCommandInteraction = exports.UserCommandInteraction = exports.ChatInputCommandInteraction = exports.UserSelectMenuInteraction = exports.RoleSelectMenuInteraction = exports.MentionableSelectMenuInteraction = exports.ChannelSelectMenuInteraction = exports.StringSelectMenuInteraction = exports.SelectMenuInteraction = exports.ButtonInteraction = exports.ComponentInteraction = exports.EntryPointInteraction = exports.ApplicationCommandInteraction = exports.Interaction = exports.AutocompleteInteraction = exports.BaseInteraction = void 0; const types_1 = require("../types"); const builders_1 = require("../builders"); const transformers_1 = require("../client/transformers"); const common_1 = require("../common"); const mixer_1 = require("../deps/mixer"); const _1 = require("./"); const DiscordBase_1 = require("./extra/DiscordBase"); const Permissions_1 = require("./extra/Permissions"); class BaseInteraction extends DiscordBase_1.DiscordBase { client; __reply; user; member; channel; message; replied; appPermissions; entitlements; constructor(client, interaction, __reply) { super(client, interaction); this.client = client; this.__reply = __reply; if (interaction.member) { this.member = transformers_1.Transformers.InteractionGuildMember(client, interaction.member, interaction.member.user, interaction.guild_id); } if (interaction.message) { this.message = transformers_1.Transformers.Message(client, interaction.message); } this.appPermissions = new Permissions_1.PermissionsBitField(Number(interaction.app_permissions)); if ('channel' in interaction) { this.channel = (0, _1.channelFrom)(interaction.channel, client); } this.user = this.member?.user ?? transformers_1.Transformers.User(client, interaction.user); this.entitlements = interaction.entitlements.map(e => transformers_1.Transformers.Entitlement(this.client, e)); } static transformBodyRequest(body, files, self) { switch (body.type) { case types_1.InteractionResponseType.ApplicationCommandAutocompleteResult: case types_1.InteractionResponseType.DeferredMessageUpdate: case types_1.InteractionResponseType.DeferredChannelMessageWithSource: return body; case types_1.InteractionResponseType.ChannelMessageWithSource: case types_1.InteractionResponseType.UpdateMessage: { //@ts-ignore return { type: body.type, data: BaseInteraction.transformBody(body.data ?? {}, files, self), }; } case types_1.InteractionResponseType.Modal: return { type: body.type, data: body.data instanceof builders_1.Modal ? body.data.toJSON() : { ...body.data, components: body.data?.components ? body.data.components.map(x => x instanceof builders_1.ActionRow ? x.toJSON() : x) : [], }, }; case types_1.InteractionResponseType.LaunchActivity: return body; default: return body; } } static transformBody(body, files, self) { const poll = body.poll; const payload = { allowed_mentions: self.options?.allowedMentions, ...body, components: body.components?.map(x => (x instanceof builders_1.ActionRow ? x.toJSON() : x)), embeds: body?.embeds?.map(x => (x instanceof builders_1.Embed ? x.toJSON() : x)), poll: poll ? (poll instanceof builders_1.PollBuilder ? poll.toJSON() : poll) : undefined, }; if ('attachments' in body) { payload.attachments = body.attachments?.map((x, i) => ({ id: i, ...(0, builders_1.resolveAttachment)(x), })) ?? undefined; } else if (files?.length) { payload.attachments = files?.map(({ filename }, id) => ({ id, filename, })); } return payload; } async matchReplied(body, withResponse = false) { if (this.__reply) { //@ts-expect-error const { files, ...rest } = body.data ?? {}; //@ts-expect-error const data = body.data instanceof builders_1.Modal ? body.data : rest; const parsedFiles = files ? await (0, builders_1.resolveFiles)(files) : undefined; await (this.replied = this.__reply({ body: BaseInteraction.transformBodyRequest({ data, type: body.type }, parsedFiles, this.client), files: parsedFiles, }).then(() => (this.replied = true))); return; } const result = await (this.replied = this.client.interactions.reply(this.id, this.token, body, withResponse)); this.replied = true; return result?.resource?.message ? transformers_1.Transformers.WebhookMessage(this.client, result.resource.message, this.id, this.token) : undefined; } async reply(body, withResponse) { if (this.replied) { throw new Error('Interaction already replied'); } const result = await this.matchReplied(body, withResponse); // @ts-expect-error if (body.data instanceof builders_1.Modal) { // @ts-expect-error if (body.data.__exec) this.client.components.modals.set(this.user.id, body.data.__exec); else if (this.client.components.modals.has(this.user.id)) this.client.components.modals.delete(this.user.id); } return result; } deferReply(flags, withResponse) { return this.reply({ type: types_1.InteractionResponseType.DeferredChannelMessageWithSource, data: { flags, }, }, withResponse); } isButton() { return false; } isChannelSelectMenu() { return false; } isRoleSelectMenu() { return false; } isMentionableSelectMenu() { return false; } isUserSelectMenu() { return false; } isStringSelectMenu() { return false; } isChatInput() { return false; } isUser() { return false; } isMessage() { return false; } isAutocomplete() { return false; } isModal() { return false; } isEntryPoint() { return false; } static from(client, gateway, __reply) { switch (gateway.type) { case types_1.InteractionType.ApplicationCommandAutocomplete: return new AutocompleteInteraction(client, gateway, undefined, __reply); // biome-ignore lint/suspicious/noFallthroughSwitchClause: bad interaction between biome and ts-server case types_1.InteractionType.ApplicationCommand: switch (gateway.data.type) { case types_1.ApplicationCommandType.ChatInput: return new ChatInputCommandInteraction(client, gateway, __reply); case types_1.ApplicationCommandType.User: return new UserCommandInteraction(client, gateway, __reply); case types_1.ApplicationCommandType.Message: return new MessageCommandInteraction(client, gateway, __reply); case types_1.ApplicationCommandType.PrimaryEntryPoint: return new EntryPointInteraction(client, gateway, __reply); } // biome-ignore lint/suspicious/noFallthroughSwitchClause: bad interaction between biome and ts-server case types_1.InteractionType.MessageComponent: switch (gateway.data.component_type) { case types_1.ComponentType.Button: return new ButtonInteraction(client, gateway, __reply); case types_1.ComponentType.ChannelSelect: return new ChannelSelectMenuInteraction(client, gateway, __reply); case types_1.ComponentType.RoleSelect: return new RoleSelectMenuInteraction(client, gateway, __reply); case types_1.ComponentType.MentionableSelect: return new MentionableSelectMenuInteraction(client, gateway, __reply); case types_1.ComponentType.UserSelect: return new UserSelectMenuInteraction(client, gateway, __reply); case types_1.ComponentType.StringSelect: return new StringSelectMenuInteraction(client, gateway, __reply); } case types_1.InteractionType.ModalSubmit: return new ModalSubmitInteraction(client, gateway); default: return new BaseInteraction(client, gateway); } } async fetchGuild(force = false) { return this.guildId ? this.client.guilds.fetch(this.guildId, force) : undefined; } } exports.BaseInteraction = BaseInteraction; class AutocompleteInteraction extends BaseInteraction { __reply; options; constructor(client, interaction, resolver, __reply) { super(client, interaction); this.__reply = __reply; this.options = resolver ?? transformers_1.Transformers.OptionResolver(client, interaction.data.options, undefined, interaction.guild_id, interaction.data.resolved); } getInput() { return this.options.getAutocompleteValue() ?? ''; } respond(choices) { return super.reply({ data: { choices }, type: types_1.InteractionResponseType.ApplicationCommandAutocompleteResult }); } isAutocomplete() { return true; } /** @intenal */ async reply(..._args) { throw new Error('Cannot use reply in this interaction'); } } exports.AutocompleteInteraction = AutocompleteInteraction; class Interaction extends BaseInteraction { fetchMessage(messageId) { return this.client.interactions.fetchResponse(this.token, messageId); } fetchResponse() { return this.fetchMessage('@original'); } write(body, withResponse) { return this.reply({ type: types_1.InteractionResponseType.ChannelMessageWithSource, data: body, }, withResponse); } modal(body) { return this.reply({ type: types_1.InteractionResponseType.Modal, data: body, }); } async editOrReply(body, fetchReply) { if (await this.replied) { const { content, embeds, allowed_mentions, components, files, attachments, poll } = body; return this.editResponse({ content, embeds, allowed_mentions, components, files, attachments, poll }); } return this.write(body, fetchReply); } editMessage(messageId, body) { return this.client.interactions.editMessage(this.token, messageId, body); } editResponse(body) { return this.editMessage('@original', body); } deleteResponse() { return this.deleteMessage('@original'); } deleteMessage(messageId) { return this.client.interactions.deleteResponse(this.token, messageId); } followup(body) { return this.client.interactions.followup(this.token, body); } } exports.Interaction = Interaction; class ApplicationCommandInteraction extends Interaction { type; respond(data) { return this.reply(data); } } exports.ApplicationCommandInteraction = ApplicationCommandInteraction; /** * Seyfert don't support activities, so this interaction is blank */ class EntryPointInteraction extends ApplicationCommandInteraction { async withReponse(data) { let body = { type: types_1.InteractionResponseType.LaunchActivity }; if (data) { let { files, ...rest } = data; files = files ? await (0, builders_1.resolveFiles)(files) : undefined; body = BaseInteraction.transformBody(rest, files, this.client); } const response = await this.client.proxy .interactions(this.id)(this.token) .callback.post({ body, query: { with_response: true }, }); const result = { interaction: (0, common_1.toCamelCase)(response.interaction), }; if (response.resource) { if (response.resource.type !== types_1.InteractionResponseType.LaunchActivity) { result.resource = { type: response.resource.type, message: transformers_1.Transformers.WebhookMessage(this.client, response.resource.message, this.id, this.token), }; } else { result.resource = { type: response.resource.type, activityInstance: response.resource.activity_instance, }; } } return result; } isEntryPoint() { return true; } } exports.EntryPointInteraction = EntryPointInteraction; class ComponentInteraction extends Interaction { update(data) { return this.reply({ type: types_1.InteractionResponseType.UpdateMessage, data, }); } deferUpdate() { return this.reply({ type: types_1.InteractionResponseType.DeferredMessageUpdate, }); } get customId() { return this.data.customId; } get componentType() { return this.data.componentType; } } exports.ComponentInteraction = ComponentInteraction; class ButtonInteraction extends ComponentInteraction { isButton() { return true; } } exports.ButtonInteraction = ButtonInteraction; class SelectMenuInteraction extends ComponentInteraction { __reply; constructor(client, interaction, __reply) { super(client, interaction); this.__reply = __reply; } get values() { return this.data.values; } } exports.SelectMenuInteraction = SelectMenuInteraction; class StringSelectMenuInteraction extends SelectMenuInteraction { isStringSelectMenu() { return true; } } exports.StringSelectMenuInteraction = StringSelectMenuInteraction; class ChannelSelectMenuInteraction extends SelectMenuInteraction { __reply; channels; constructor(client, interaction, __reply) { super(client, interaction); this.__reply = __reply; const resolved = interaction.data.resolved; this.channels = this.values.map(x => (0, _1.channelFrom)(resolved.channels[x], this.client)); } isChannelSelectMenu() { return true; } } exports.ChannelSelectMenuInteraction = ChannelSelectMenuInteraction; class MentionableSelectMenuInteraction extends SelectMenuInteraction { __reply; roles; members; users; constructor(client, interaction, __reply) { super(client, interaction); this.__reply = __reply; const resolved = interaction.data.resolved; this.roles = resolved.roles ? this.values.map(x => transformers_1.Transformers.GuildRole(this.client, resolved.roles[x], this.guildId)) : []; this.members = resolved.members ? this.values.map(x => transformers_1.Transformers.InteractionGuildMember(this.client, resolved.members[x], resolved.users[this.values.find(u => u === x)], this.guildId)) : []; this.users = resolved.users ? this.values.map(x => transformers_1.Transformers.User(this.client, resolved.users[x])) : []; } isMentionableSelectMenu() { return true; } } exports.MentionableSelectMenuInteraction = MentionableSelectMenuInteraction; class RoleSelectMenuInteraction extends SelectMenuInteraction { __reply; roles; constructor(client, interaction, __reply) { super(client, interaction); this.__reply = __reply; const resolved = interaction.data.resolved; this.roles = this.values.map(x => transformers_1.Transformers.GuildRole(this.client, resolved.roles[x], this.guildId)); } isRoleSelectMenu() { return true; } } exports.RoleSelectMenuInteraction = RoleSelectMenuInteraction; class UserSelectMenuInteraction extends SelectMenuInteraction { __reply; members; users; constructor(client, interaction, __reply) { super(client, interaction); this.__reply = __reply; const resolved = interaction.data.resolved; this.users = this.values.map(x => transformers_1.Transformers.User(this.client, resolved.users[x])); this.members = resolved.members ? this.values.map(x => transformers_1.Transformers.InteractionGuildMember(this.client, resolved.members[x], resolved.users[this.values.find(u => u === x)], this.guildId)) : []; } isUserSelectMenu() { return true; } } exports.UserSelectMenuInteraction = UserSelectMenuInteraction; class ChatInputCommandInteraction extends ApplicationCommandInteraction { isChatInput() { return true; } } exports.ChatInputCommandInteraction = ChatInputCommandInteraction; class UserCommandInteraction extends ApplicationCommandInteraction { isUser() { return true; } } exports.UserCommandInteraction = UserCommandInteraction; class MessageCommandInteraction extends ApplicationCommandInteraction { isMessage() { return true; } } exports.MessageCommandInteraction = MessageCommandInteraction; let ModalSubmitInteraction = class ModalSubmitInteraction extends BaseInteraction { update(data, withResponse) { return this.reply({ type: types_1.InteractionResponseType.UpdateMessage, data, }, withResponse); } deferUpdate(withResponse) { return this.reply({ type: types_1.InteractionResponseType.DeferredMessageUpdate, }, withResponse); } get customId() { return this.data.customId; } get components() { return this.data.components; } getInputValue(customId, required) { let value; for (const { components } of this.components) { const get = components.find(x => x.customId === customId); if (get) { value = get.value; break; } } if (!value && required) throw new Error(`${customId} component doesn't have a value`); return value; } isModal() { return true; } }; exports.ModalSubmitInteraction = ModalSubmitInteraction; exports.ModalSubmitInteraction = ModalSubmitInteraction = __decorate([ (0, mixer_1.mix)(Interaction) ], ModalSubmitInteraction);