diff --git a/.mocharc.cjs b/.mocharc.cjs index ae8736faa..4b98aedf5 100644 --- a/.mocharc.cjs +++ b/.mocharc.cjs @@ -1,23 +1,23 @@ // @ts-check // If we are running in Bun or Deno, they have native TypeScript support with .js imports, node requires .ts imports -const supportsTypescript = 'Bun' in globalThis || 'Deno' in globalThis +const supportsTypescript = 'Bun' in globalThis || 'Deno' in globalThis; /** @type {import("mocha").MochaInstanceOptions & Record} */ const mochaConfig = { timeout: 2000, 'watch-extensions': 'ts', 'watch-files': ['src', 'tests'], -} +}; if (!supportsTypescript) { - mochaConfig.require = ['ts-node/register'] + mochaConfig.require = ['ts-node/register']; // Node options - mochaConfig.loader = ['ts-node/esm'] + mochaConfig.loader = ['ts-node/esm']; // Node will output a ExperimentalWarning about --loader (--experimental-loader) and a DeprecationWarning because ts-node uses fs.Stat - mochaConfig['no-warnings'] = true - mochaConfig['enable-source-maps'] = true + mochaConfig['no-warnings'] = true; + mochaConfig['enable-source-maps'] = true; } -module.exports = mochaConfig +module.exports = mochaConfig; diff --git a/biome.jsonc b/biome.jsonc index 9798b6e42..948c73041 100644 --- a/biome.jsonc +++ b/biome.jsonc @@ -38,7 +38,6 @@ "javascript": { "formatter": { "trailingCommas": "all", - "semicolons": "asNeeded", "quoteStyle": "single" } }, diff --git a/docker-apps/rest-passthrough/src/fastify.ts b/docker-apps/rest-passthrough/src/fastify.ts index 27bf4709f..4a9d403a7 100644 --- a/docker-apps/rest-passthrough/src/fastify.ts +++ b/docker-apps/rest-passthrough/src/fastify.ts @@ -1,10 +1,10 @@ -import fastifyEnv from '@fastify/env' -import fastifyHelmet from '@fastify/helmet' -import fastifyMultipart from '@fastify/multipart' -import fastify, { type FastifyInstance } from 'fastify' +import fastifyEnv from '@fastify/env'; +import fastifyHelmet from '@fastify/helmet'; +import fastifyMultipart from '@fastify/multipart'; +import fastify, { type FastifyInstance } from 'fastify'; export const buildFastifyApp = async (): Promise => { - const app = await fastify() + const app = await fastify(); await app.register(fastifyEnv, { schema: { @@ -25,28 +25,28 @@ export const buildFastifyApp = async (): Promise => { }, required: ['DISCORD_TOKEN', 'AUTHORIZATION_TOKEN'], }, - }) + }); - await app.register(fastifyHelmet) - app.register(fastifyMultipart, { attachFieldsToBody: true }) + await app.register(fastifyHelmet); + app.register(fastifyMultipart, { attachFieldsToBody: true }); app.addHook('onRequest', async (request, reply) => { if (request.headers.authorization !== request.server.config.AUTHORIZATION_TOKEN) { reply.status(401).send({ message: 'Credentials not valid.', - }) + }); } - }) + }); - return app -} + return app; +}; declare module 'fastify' { interface FastifyInstance { config: { - HOST: string - DISCORD_TOKEN: string - AUTHORIZATION_TOKEN: string - } + HOST: string; + DISCORD_TOKEN: string; + AUTHORIZATION_TOKEN: string; + }; } } diff --git a/docker-apps/rest-passthrough/src/server.ts b/docker-apps/rest-passthrough/src/server.ts index dba5cb695..eef93e4b2 100644 --- a/docker-apps/rest-passthrough/src/server.ts +++ b/docker-apps/rest-passthrough/src/server.ts @@ -1,79 +1,79 @@ -import { createRestManager, type RequestMethods } from '@discordeno/rest' -import type { MultipartFile, MultipartValue } from '@fastify/multipart' -import { buildFastifyApp } from './fastify.js' +import { createRestManager, type RequestMethods } from '@discordeno/rest'; +import type { MultipartFile, MultipartValue } from '@fastify/multipart'; +import { buildFastifyApp } from './fastify.js'; -const app = await buildFastifyApp() +const app = await buildFastifyApp(); if (!app.config.DISCORD_TOKEN || !app.config.AUTHORIZATION_TOKEN) { - console.error('Missing environment variables. Both DISCORD_TOKEN and AUTHORIZATION_TOKEN are required.') - process.exit(1) + console.error('Missing environment variables. Both DISCORD_TOKEN and AUTHORIZATION_TOKEN are required.'); + process.exit(1); } const discordRestManager = createRestManager({ token: app.config.DISCORD_TOKEN, -}) +}); app.get('/timecheck', async (_request, reply) => { reply.status(200).send({ message: Date.now(), - }) -}) + }); +}); app.all('/*', async (request, reply) => { - let url = request.originalUrl + let url = request.originalUrl; if (url.startsWith('/v')) { - url = url.slice(url.indexOf('/', 2)) + url = url.slice(url.indexOf('/', 2)); } - const isMultipart = request.headers['content-type']?.startsWith('multipart/form-data') - const body = request.method !== 'GET' && request.method !== 'DELETE' ? request.body : undefined + const isMultipart = request.headers['content-type']?.startsWith('multipart/form-data'); + const body = request.method !== 'GET' && request.method !== 'DELETE' ? request.body : undefined; try { const result = await discordRestManager.makeRequest(request.method as RequestMethods, url, { body: isMultipart && body ? await parseMultiformBody(body) : body, - }) + }); if (result) { - reply.status(200).send(result) + reply.status(200).send(result); } else { - reply.status(204).send({}) + reply.status(204).send({}); } } catch (error) { - app.log.error(error) + app.log.error(error); reply.status(500).send({ message: error, - }) + }); } -}) +}); try { await app.listen({ host: app.config.HOST, port: 8000, - }) - console.log(`Proxy listening on port 8000`) + }); + console.log(`Proxy listening on port 8000`); } catch (error) { - app.log.error(error) - process.exit(1) + app.log.error(error); + process.exit(1); } async function parseMultiformBody(body: unknown): Promise { - const form = new FormData() + const form = new FormData(); - if (typeof body !== 'object' || !body) return form + if (typeof body !== 'object' || !body) return form; for (const objectValue of Object.values(body)) { - const value = objectValue as MultipartFile | MultipartValue + const value = objectValue as MultipartFile | MultipartValue; if (value.type === 'file') { - form.append(value.fieldname, new Blob([Uint8Array.from(await value.toBuffer())]), value.filename) + form.append(value.fieldname, new Blob([Uint8Array.from(await value.toBuffer())]), value.filename); } if (value.type === 'field' && typeof value.value === 'string') { - form.append(value.fieldname, value.value) + form.append(value.fieldname, value.value); } } - return form + return form; } diff --git a/examples/advanced/src/bot.ts b/examples/advanced/src/bot.ts index 915b4d73e..5fede6f9d 100644 --- a/examples/advanced/src/bot.ts +++ b/examples/advanced/src/bot.ts @@ -1,6 +1,6 @@ -import { createBot, type logger as discordenoLogger, Intents, LogDepth } from '@discordeno/bot' -import { createProxyCache } from 'dd-cache-proxy' -import { configs } from './config.js' +import { createBot, type logger as discordenoLogger, Intents, LogDepth } from '@discordeno/bot'; +import { createProxyCache } from 'dd-cache-proxy'; +import { configs } from './config.js'; const rawBot = createBot({ token: configs.token, @@ -38,7 +38,7 @@ const rawBot = createBot({ discriminator: true, }, }, -}) +}); export const bot = createProxyCache(rawBot, { desiredProps: { @@ -50,7 +50,7 @@ export const bot = createProxyCache(rawBot, { role: true, default: false, }, -}) +}); // By default, bot.logger will use an instance of the logger from @discordeno/bot, this logger supports depth and we need to change it, so we need to say to TS that we know what we are doing with as -;(bot.logger as typeof discordenoLogger).setDepth(LogDepth.Full) +(bot.logger as typeof discordenoLogger).setDepth(LogDepth.Full); diff --git a/examples/advanced/src/commands.ts b/examples/advanced/src/commands.ts index a493e8d08..7d64541b9 100644 --- a/examples/advanced/src/commands.ts +++ b/examples/advanced/src/commands.ts @@ -1,21 +1,21 @@ -import { type ApplicationCommandOption, type ApplicationCommandTypes, Collection } from '@discordeno/bot' -import type { bot } from './bot.js' +import { type ApplicationCommandOption, type ApplicationCommandTypes, Collection } from '@discordeno/bot'; +import type { bot } from './bot.js'; -export const commands = new Collection() +export const commands = new Collection(); export function createCommand(command: Command): void { - commands.set(command.name, command) + commands.set(command.name, command); } export interface Command { /** The name of this command. */ - name: string + name: string; /** What does this command do? */ - description: string + description: string; /** The type of command this is. */ - type: ApplicationCommandTypes + type: ApplicationCommandTypes; /** The options for this command */ - options?: ApplicationCommandOption[] + options?: ApplicationCommandOption[]; /** This will be executed when the command is run. */ - execute: (interaction: typeof bot.transformers.$inferredTypes.interaction, options: Record) => unknown + execute: (interaction: typeof bot.transformers.$inferredTypes.interaction, options: Record) => unknown; } diff --git a/examples/advanced/src/commands/ping.ts b/examples/advanced/src/commands/ping.ts index c7eb55b3c..d59348b43 100644 --- a/examples/advanced/src/commands/ping.ts +++ b/examples/advanced/src/commands/ping.ts @@ -1,15 +1,15 @@ -import { ApplicationCommandTypes, createEmbeds, snowflakeToTimestamp } from '@discordeno/bot' -import { createCommand } from '../commands.js' +import { ApplicationCommandTypes, createEmbeds, snowflakeToTimestamp } from '@discordeno/bot'; +import { createCommand } from '../commands.js'; createCommand({ name: 'ping', description: 'See if the bot latency is okay', type: ApplicationCommandTypes.ChatInput, async execute(interaction) { - const ping = Date.now() - snowflakeToTimestamp(interaction.id) + const ping = Date.now() - snowflakeToTimestamp(interaction.id); - const embeds = createEmbeds().setTitle(`The bot ping is ${ping}ms`) + const embeds = createEmbeds().setTitle(`The bot ping is ${ping}ms`); - await interaction.respond({ embeds }) + await interaction.respond({ embeds }); }, -}) +}); diff --git a/examples/advanced/src/commands/warn.ts b/examples/advanced/src/commands/warn.ts index 8f3ad19e2..cbcbe2337 100644 --- a/examples/advanced/src/commands/warn.ts +++ b/examples/advanced/src/commands/warn.ts @@ -1,7 +1,7 @@ -import { ApplicationCommandOptionTypes, ApplicationCommandTypes, createEmbeds, type Member, Permissions, type User } from '@discordeno/bot' -import { bot } from '../bot.js' -import { createCommand } from '../commands.js' -import { calculateMemberPermissions } from '../utils/permissions.js' +import { ApplicationCommandOptionTypes, ApplicationCommandTypes, createEmbeds, type Member, Permissions, type User } from '@discordeno/bot'; +import { bot } from '../bot.js'; +import { createCommand } from '../commands.js'; +import { calculateMemberPermissions } from '../utils/permissions.js'; createCommand({ name: 'warn', @@ -23,58 +23,58 @@ createCommand({ ], async execute(interaction, options) { if (!interaction.guildId || !interaction.member) { - await interaction.respond('This command can only be ran in guilds') - return + await interaction.respond('This command can only be ran in guilds'); + return; } // Type based on the options declared above - const { user, reason } = options as { user: UserResolved; reason?: string } + const { user, reason } = options as { user: UserResolved; reason?: string }; - const guild = await bot.cache.guilds.get(interaction.guildId) + const guild = await bot.cache.guilds.get(interaction.guildId); if (!guild || !guild.roles) { - await interaction.respond('An error has occurred') - return + await interaction.respond('An error has occurred'); + return; } - await interaction.defer() + await interaction.defer(); - const perms = new Permissions(await calculateMemberPermissions(guild, interaction.member)) + const perms = new Permissions(await calculateMemberPermissions(guild, interaction.member)); - const adminPerm = perms.has('ADMINISTRATOR') - const kickMembersPerm = adminPerm || perms.has('KICK_MEMBERS') + const adminPerm = perms.has('ADMINISTRATOR'); + const kickMembersPerm = adminPerm || perms.has('KICK_MEMBERS'); if (!kickMembersPerm) { - await interaction.respond("You don't have the necessary permissions to warn a members (this command requires `Kick members`)") - return + await interaction.respond("You don't have the necessary permissions to warn a members (this command requires `Kick members`)"); + return; } const embeds = createEmbeds() .setTitle('Warned User:') .setDescription(`User: <@${user.user.id}>\nReason: ${reason}`) .setColor(0x00ff00) - .setTimestamp(Date.now()) + .setTimestamp(Date.now()); const warnEmbeds = createEmbeds() .setTitle('Warning:') .setDescription(`You have been warned in **${guild.name}** for \`${reason}\``) - .setTimestamp(Date.now()) + .setTimestamp(Date.now()); try { - const dmChannel = await bot.helpers.getDmChannel(user.user.id) - await bot.helpers.sendMessage(dmChannel.id, { embeds: warnEmbeds }) + const dmChannel = await bot.helpers.getDmChannel(user.user.id); + await bot.helpers.sendMessage(dmChannel.id, { embeds: warnEmbeds }); } catch (error) { - bot.logger.error(`There was an error in the warn command:`, error) + bot.logger.error(`There was an error in the warn command:`, error); - await interaction.respond(`Could not warn user <@${user.user.id}> | They likely do not have their DMs open.`) - return + await interaction.respond(`Could not warn user <@${user.user.id}> | They likely do not have their DMs open.`); + return; } - await interaction.respond({ embeds }) + await interaction.respond({ embeds }); }, -}) +}); interface UserResolved { - user: User - member?: Member + user: User; + member?: Member; } diff --git a/examples/advanced/src/config.ts b/examples/advanced/src/config.ts index 01a52c3e5..a0c6cae82 100644 --- a/examples/advanced/src/config.ts +++ b/examples/advanced/src/config.ts @@ -1,11 +1,11 @@ -const token = process.env.TOKEN +const token = process.env.TOKEN; -if (!token) throw new Error('Missing TOKEN environment variable') +if (!token) throw new Error('Missing TOKEN environment variable'); export const configs: Config = { token, -} +}; export interface Config { - token: string + token: string; } diff --git a/examples/advanced/src/events/interactionCreate.ts b/examples/advanced/src/events/interactionCreate.ts index b74a5d9f3..44c28eb81 100644 --- a/examples/advanced/src/events/interactionCreate.ts +++ b/examples/advanced/src/events/interactionCreate.ts @@ -1,22 +1,22 @@ -import { commandOptionsParser, InteractionTypes } from '@discordeno/bot' -import { bot } from '../bot.js' -import { commands } from '../commands.js' +import { commandOptionsParser, InteractionTypes } from '@discordeno/bot'; +import { bot } from '../bot.js'; +import { commands } from '../commands.js'; bot.events.interactionCreate = async (interaction) => { - if (!interaction.data || interaction.type !== InteractionTypes.ApplicationCommand) return + if (!interaction.data || interaction.type !== InteractionTypes.ApplicationCommand) return; - const command = commands.get(interaction.data.name) + const command = commands.get(interaction.data.name); if (!command) { - bot.logger.error(`Command ${interaction.data.name} not found`) - return + bot.logger.error(`Command ${interaction.data.name} not found`); + return; } - const options = commandOptionsParser(interaction) + const options = commandOptionsParser(interaction); try { - await command.execute(interaction, options) + await command.execute(interaction, options); } catch (error) { - bot.logger.error(`There was an error running the ${command.name} command.`, error) + bot.logger.error(`There was an error running the ${command.name} command.`, error); } -} +}; diff --git a/examples/advanced/src/events/ready.ts b/examples/advanced/src/events/ready.ts index 5b7255836..91fd913f8 100644 --- a/examples/advanced/src/events/ready.ts +++ b/examples/advanced/src/events/ready.ts @@ -1,8 +1,8 @@ -import { bot } from '../bot.js' +import { bot } from '../bot.js'; bot.events.ready = ({ user, shardId }) => { if (shardId === bot.gateway.lastShardId) { // All shards are ready - bot.logger.info(`Successfully connected to the gateway as ${user.username}#${user.discriminator}`) + bot.logger.info(`Successfully connected to the gateway as ${user.username}#${user.discriminator}`); } -} +}; diff --git a/examples/advanced/src/index.ts b/examples/advanced/src/index.ts index 0d69c323b..c4e4e6c37 100644 --- a/examples/advanced/src/index.ts +++ b/examples/advanced/src/index.ts @@ -1,14 +1,14 @@ -import 'dotenv/config' +import 'dotenv/config'; -import { bot } from './bot.js' -import importDirectory from './utils/loader.js' +import { bot } from './bot.js'; +import importDirectory from './utils/loader.js'; -bot.logger.info('Starting bot...') +bot.logger.info('Starting bot...'); -bot.logger.info('Loading commands...') -await importDirectory('./dist/commands') +bot.logger.info('Loading commands...'); +await importDirectory('./dist/commands'); -bot.logger.info('Loading events...') -await importDirectory('./dist/events') +bot.logger.info('Loading events...'); +await importDirectory('./dist/events'); -await bot.start() +await bot.start(); diff --git a/examples/advanced/src/register-commands.ts b/examples/advanced/src/register-commands.ts index 39d03d497..695769411 100644 --- a/examples/advanced/src/register-commands.ts +++ b/examples/advanced/src/register-commands.ts @@ -1,16 +1,16 @@ -import 'dotenv/config' +import 'dotenv/config'; -import { bot } from './bot.js' -import importDirectory from './utils/loader.js' -import { updateApplicationCommands } from './utils/updateCommands.js' +import { bot } from './bot.js'; +import importDirectory from './utils/loader.js'; +import { updateApplicationCommands } from './utils/updateCommands.js'; -bot.logger.info('Loading commands...') -await importDirectory('./dist/commands') +bot.logger.info('Loading commands...'); +await importDirectory('./dist/commands'); -bot.logger.info('Updating commands...') -await updateApplicationCommands() +bot.logger.info('Updating commands...'); +await updateApplicationCommands(); -bot.logger.info('Done!') +bot.logger.info('Done!'); // We need to manually exit as the REST Manager has timeouts that will keep NodeJS alive -process.exit() +process.exit(); diff --git a/examples/advanced/src/utils/loader.ts b/examples/advanced/src/utils/loader.ts index 990755056..a313d09fe 100644 --- a/examples/advanced/src/utils/loader.ts +++ b/examples/advanced/src/utils/loader.ts @@ -1,15 +1,15 @@ -import { readdir } from 'node:fs/promises' -import { logger } from '@discordeno/bot' +import { readdir } from 'node:fs/promises'; +import { logger } from '@discordeno/bot'; export default async function importDirectory(folder: string): Promise { - const files = await readdir(folder, { recursive: true }) + const files = await readdir(folder, { recursive: true }); for (const filename of files) { - if (!filename.endsWith('.js')) continue + if (!filename.endsWith('.js')) continue; // Using `file://` and `process.cwd()` to avoid weird issues with relative paths and/or Windows await import(`file://${process.cwd()}/${folder}/${filename}`).catch((x) => logger.fatal(`Cannot import file (${folder}/${filename}) for reason:`, x), - ) + ); } } diff --git a/examples/advanced/src/utils/permissions.ts b/examples/advanced/src/utils/permissions.ts index 4e0fcf5c7..bc4d2a419 100644 --- a/examples/advanced/src/utils/permissions.ts +++ b/examples/advanced/src/utils/permissions.ts @@ -1,24 +1,24 @@ -import assert from 'node:assert' -import { BitwisePermissionFlags } from '@discordeno/bot' -import type { bot } from '../bot.js' +import assert from 'node:assert'; +import { BitwisePermissionFlags } from '@discordeno/bot'; +import type { bot } from '../bot.js'; export async function calculateMemberPermissions( guild: typeof bot.transformers.$inferredTypes.guild | typeof bot.cache.$inferredTypes.guild, member: typeof bot.transformers.$inferredTypes.member, ) { - if (member.id === guild.ownerId) return 8n + if (member.id === guild.ownerId) return 8n; - let permissions = guild.roles?.get(guild.id)?.permissions.bitfield - const rolePerms = member.roles.map((x) => guild.roles?.get(x)?.permissions.bitfield).filter((x): x is bigint => x !== undefined) + let permissions = guild.roles?.get(guild.id)?.permissions.bitfield; + const rolePerms = member.roles.map((x) => guild.roles?.get(x)?.permissions.bitfield).filter((x): x is bigint => x !== undefined); // Small hack to avoid calling assert with 0n - if (permissions === undefined) assert(permissions) + if (permissions === undefined) assert(permissions); for (const rolePerm of rolePerms) { - permissions |= rolePerm + permissions |= rolePerm; } - if ((permissions & BigInt(BitwisePermissionFlags.ADMINISTRATOR)) === BigInt(BitwisePermissionFlags.ADMINISTRATOR)) return 8n + if ((permissions & BigInt(BitwisePermissionFlags.ADMINISTRATOR)) === BigInt(BitwisePermissionFlags.ADMINISTRATOR)) return 8n; - return permissions + return permissions; } diff --git a/examples/advanced/src/utils/updateCommands.ts b/examples/advanced/src/utils/updateCommands.ts index d92a348d6..edaa70a39 100644 --- a/examples/advanced/src/utils/updateCommands.ts +++ b/examples/advanced/src/utils/updateCommands.ts @@ -1,6 +1,6 @@ -import { bot } from '../bot.js' -import { commands } from '../commands.js' +import { bot } from '../bot.js'; +import { commands } from '../commands.js'; export async function updateApplicationCommands(): Promise { - await bot.helpers.upsertGlobalApplicationCommands(commands.array()) + await bot.helpers.upsertGlobalApplicationCommands(commands.array()); } diff --git a/examples/beginner/src/bot.ts b/examples/beginner/src/bot.ts index c6232dfd0..69ae019bb 100644 --- a/examples/beginner/src/bot.ts +++ b/examples/beginner/src/bot.ts @@ -1,6 +1,6 @@ -import { createBot, Intents } from '@discordeno/bot' -import { createProxyCache } from 'dd-cache-proxy' -import { configs } from './config.js' +import { createBot, Intents } from '@discordeno/bot'; +import { createProxyCache } from 'dd-cache-proxy'; +import { configs } from './config.js'; const rawBot = createBot({ token: configs.token, @@ -22,7 +22,7 @@ const rawBot = createBot({ username: true, }, }, -}) +}); export const bot = createProxyCache(rawBot, { desiredProps: { @@ -32,4 +32,4 @@ export const bot = createProxyCache(rawBot, { guild: true, default: false, }, -}) +}); diff --git a/examples/beginner/src/commands.ts b/examples/beginner/src/commands.ts index 8c0577358..f54a1bed9 100644 --- a/examples/beginner/src/commands.ts +++ b/examples/beginner/src/commands.ts @@ -1,27 +1,27 @@ -import { type ApplicationCommandOption, type ApplicationCommandTypes, Collection } from '@discordeno/bot' -import type { bot } from './bot.js' +import { type ApplicationCommandOption, type ApplicationCommandTypes, Collection } from '@discordeno/bot'; +import type { bot } from './bot.js'; -export const commands = new Collection() +export const commands = new Collection(); export function createCommand(command: Command): void { - commands.set(command.name, command) + commands.set(command.name, command); } export interface Command { - name: string - description: string - usage?: string[] - options?: ApplicationCommandOption[] - type: ApplicationCommandTypes + name: string; + description: string; + usage?: string[]; + options?: ApplicationCommandOption[]; + type: ApplicationCommandTypes; /** Defaults to `Guild` */ - scope?: 'Global' | 'Guild' - execute: (interaction: typeof bot.transformers.$inferredTypes.interaction) => unknown - subcommands?: Array + scope?: 'Global' | 'Guild'; + execute: (interaction: typeof bot.transformers.$inferredTypes.interaction) => unknown; + subcommands?: Array; } -export type SubCommand = Omit +export type SubCommand = Omit; export interface SubCommandGroup { - name: string - subCommands: SubCommand[] + name: string; + subCommands: SubCommand[]; } diff --git a/examples/beginner/src/commands/ping.ts b/examples/beginner/src/commands/ping.ts index 436fab402..2d494ec76 100644 --- a/examples/beginner/src/commands/ping.ts +++ b/examples/beginner/src/commands/ping.ts @@ -1,6 +1,6 @@ -import { ApplicationCommandTypes, snowflakeToTimestamp } from '@discordeno/bot' -import { createCommand } from '../commands.js' -import { humanizeMilliseconds } from '../utils/helpers.js' +import { ApplicationCommandTypes, snowflakeToTimestamp } from '@discordeno/bot'; +import { createCommand } from '../commands.js'; +import { humanizeMilliseconds } from '../utils/helpers.js'; createCommand({ name: 'ping', @@ -8,8 +8,8 @@ createCommand({ type: ApplicationCommandTypes.ChatInput, scope: 'Global', async execute(interaction) { - const ping = Date.now() - snowflakeToTimestamp(interaction.id) + const ping = Date.now() - snowflakeToTimestamp(interaction.id); - await interaction.respond(`🏓 Pong! Ping ${ping}ms (${humanizeMilliseconds(ping)})`) + await interaction.respond(`🏓 Pong! Ping ${ping}ms (${humanizeMilliseconds(ping)})`); }, -}) +}); diff --git a/examples/beginner/src/config.ts b/examples/beginner/src/config.ts index a196faa4d..63dc30956 100644 --- a/examples/beginner/src/config.ts +++ b/examples/beginner/src/config.ts @@ -1,12 +1,12 @@ -const token = process.env.BOT_TOKEN +const token = process.env.BOT_TOKEN; -if (!token) throw new Error('Missing BOT_TOKEN environment variable') +if (!token) throw new Error('Missing BOT_TOKEN environment variable'); export const configs: Config = { /** Get token from ENV variable */ token, -} +}; export interface Config { - token: string + token: string; } diff --git a/examples/beginner/src/events/guildCreate.ts b/examples/beginner/src/events/guildCreate.ts index 1f07ed7cb..80403f7f7 100644 --- a/examples/beginner/src/events/guildCreate.ts +++ b/examples/beginner/src/events/guildCreate.ts @@ -1,4 +1,4 @@ -import { bot } from '../bot.js' -import { updateGuildCommands } from '../utils/helpers.js' +import { bot } from '../bot.js'; +import { updateGuildCommands } from '../utils/helpers.js'; -bot.events.guildCreate = async (guild) => await updateGuildCommands(guild) +bot.events.guildCreate = async (guild) => await updateGuildCommands(guild); diff --git a/examples/beginner/src/events/interactionCreate.ts b/examples/beginner/src/events/interactionCreate.ts index aa658797b..2bab51eaf 100644 --- a/examples/beginner/src/events/interactionCreate.ts +++ b/examples/beginner/src/events/interactionCreate.ts @@ -1,94 +1,94 @@ -import { ApplicationCommandOptionTypes, hasProperty } from '@discordeno/bot' -import chalk from 'chalk' -import { bot } from '../bot.js' -import { commands } from '../commands.js' -import { getGuildFromId, isSubCommand, isSubCommandGroup } from '../utils/helpers.js' -import { createLogger } from '../utils/logger.js' +import { ApplicationCommandOptionTypes, hasProperty } from '@discordeno/bot'; +import chalk from 'chalk'; +import { bot } from '../bot.js'; +import { commands } from '../commands.js'; +import { getGuildFromId, isSubCommand, isSubCommandGroup } from '../utils/helpers.js'; +import { createLogger } from '../utils/logger.js'; -const logger = createLogger({ name: 'Event: InteractionCreate' }) +const logger = createLogger({ name: 'Event: InteractionCreate' }); bot.events.interactionCreate = async (interaction) => { - if (!interaction.data || !interaction.id) return + if (!interaction.data || !interaction.id) return; - let guildName = 'Direct Message' - let guild = {} as typeof bot.transformers.$inferredTypes.guild + let guildName = 'Direct Message'; + let guild = {} as typeof bot.transformers.$inferredTypes.guild; // Set guild, if there was an error getting the guild, then just say it was a DM. (What else are we going to do?) if (interaction.guildId) { const guildOrVoid = await getGuildFromId(interaction.guildId).catch((err) => { - logger.error(err) - }) + logger.error(err); + }); if (guildOrVoid) { - guild = guildOrVoid - guildName = guild.name + guild = guildOrVoid; + guildName = guild.name; } } logger.info( `[Command: ${chalk.bgYellow.black(interaction.data.name)} - ${chalk.bgBlack.white(`Trigger`)}] by @${interaction.user.username} in ${guildName}${guildName !== 'Direct Message' ? ` (${guild.id})` : ``}`, - ) + ); - let command = commands.get(interaction.data.name) + let command = commands.get(interaction.data.name); if (!command) { logger.warn( `[Command: ${chalk.bgYellow.black(interaction.data.name)} - ${chalk.bgBlack.yellow(`Not Found`)}] by @${interaction.user.username} in ${guildName}${guildName !== 'Direct Message' ? ` (${guild.id})` : ``}`, - ) + ); - return + return; } if (interaction.data.options?.[0]) { - const optionType = interaction.data.options[0].type + const optionType = interaction.data.options[0].type; if (optionType === ApplicationCommandOptionTypes.SubCommandGroup) { // Check if command has subcommand and handle types - if (!command.subcommands) return + if (!command.subcommands) return; // Try to find the subcommand group - const subCommandGroup = command.subcommands?.find((command) => command.name === interaction.data?.options?.[0].name) - if (!subCommandGroup) return + const subCommandGroup = command.subcommands?.find((command) => command.name === interaction.data?.options?.[0].name); + if (!subCommandGroup) return; - if (isSubCommand(subCommandGroup)) return + if (isSubCommand(subCommandGroup)) return; // Get name of the command which we are looking for - const targetCmdName = interaction.data.options?.[0].options?.[0].name ?? interaction.data.options?.[0].options?.[0].name - if (!targetCmdName) return + const targetCmdName = interaction.data.options?.[0].options?.[0].name ?? interaction.data.options?.[0].options?.[0].name; + if (!targetCmdName) return; // Try to find the command - command = subCommandGroup.subCommands.find((c) => c.name === targetCmdName) + command = subCommandGroup.subCommands.find((c) => c.name === targetCmdName); } if (optionType === ApplicationCommandOptionTypes.SubCommand) { // Check if command has subcommand and handle types - if (!command?.subcommands) return + if (!command?.subcommands) return; // Try to find the command - const found = command.subcommands.find((command) => command.name === interaction.data?.options?.[0].name) - if (!found) return + const found = command.subcommands.find((command) => command.name === interaction.data?.options?.[0].name); + if (!found) return; - if (isSubCommandGroup(found)) return + if (isSubCommandGroup(found)) return; - command = found + command = found; } } try { - if (!command) throw new Error('Not command could be found') + if (!command) throw new Error('Not command could be found'); - await command.execute(interaction) + await command.execute(interaction); logger.info( `[Command: ${chalk.bgYellow.black(interaction.data.name)} - ${chalk.bgBlack.green(`Success`)}] by @${interaction.user.username} in ${guildName}${guildName !== 'Direct Message' ? ` (${guild.id})` : ``}`, - ) + ); } catch (err) { logger.error( `[Command: ${chalk.bgYellow.black(interaction.data.name)} - ${chalk.bgBlack.red(`Error`)}] by @${interaction.user.username} in ${guildName}${guildName !== 'Direct Message' ? ` (${guild.id})` : ``}`, - ) + ); - if (typeof err !== 'object' || !err || !hasProperty(err, 'message') || err.message === 'Not command could be found') return + if (typeof err !== 'object' || !err || !hasProperty(err, 'message') || err.message === 'Not command could be found') return; - logger.error(err) + logger.error(err); } -} +}; diff --git a/examples/beginner/src/events/ready.ts b/examples/beginner/src/events/ready.ts index ddcdf5e2b..7b4814206 100644 --- a/examples/beginner/src/events/ready.ts +++ b/examples/beginner/src/events/ready.ts @@ -1,11 +1,11 @@ -import { ActivityTypes } from '@discordeno/bot' -import { bot } from '../bot.js' -import { createLogger } from '../utils/logger.js' +import { ActivityTypes } from '@discordeno/bot'; +import { bot } from '../bot.js'; +import { createLogger } from '../utils/logger.js'; -const logger = createLogger({ name: 'Event: Ready' }) +const logger = createLogger({ name: 'Event: Ready' }); bot.events.ready = async ({ shardId }) => { - logger.info('Bot Ready') + logger.info('Bot Ready'); await bot.gateway.editShardStatus(shardId, { status: 'online', @@ -18,5 +18,5 @@ bot.events.ready = async ({ shardId }) => { }, }, ], - }) -} + }); +}; diff --git a/examples/beginner/src/index.ts b/examples/beginner/src/index.ts index b0f5f89cf..30a137aec 100644 --- a/examples/beginner/src/index.ts +++ b/examples/beginner/src/index.ts @@ -1,15 +1,15 @@ -import 'dotenv/config' +import 'dotenv/config'; -import { bot } from './bot.js' -import importDirectory from './utils/loader.js' -import logger from './utils/logger.js' +import { bot } from './bot.js'; +import importDirectory from './utils/loader.js'; +import logger from './utils/logger.js'; -logger.info('Starting bot...') +logger.info('Starting bot...'); -logger.info('Loading commands...') -await importDirectory('./dist/commands') +logger.info('Loading commands...'); +await importDirectory('./dist/commands'); -logger.info('Loading events...') -await importDirectory('./dist/events') +logger.info('Loading events...'); +await importDirectory('./dist/events'); -await bot.start() +await bot.start(); diff --git a/examples/beginner/src/register-commands.ts b/examples/beginner/src/register-commands.ts index f690db9d1..fba5c7b93 100644 --- a/examples/beginner/src/register-commands.ts +++ b/examples/beginner/src/register-commands.ts @@ -1,16 +1,16 @@ -import 'dotenv/config' +import 'dotenv/config'; -import { bot } from './bot.js' -import { updateCommands } from './utils/helpers.js' -import importDirectory from './utils/loader.js' +import { bot } from './bot.js'; +import { updateCommands } from './utils/helpers.js'; +import importDirectory from './utils/loader.js'; -bot.logger.info('Loading commands...') -await importDirectory('./dist/commands') +bot.logger.info('Loading commands...'); +await importDirectory('./dist/commands'); -bot.logger.info('Updating commands...') -await updateCommands() +bot.logger.info('Updating commands...'); +await updateCommands(); -bot.logger.info('Done!') +bot.logger.info('Done!'); // We need to manually exit as the REST Manager has timeouts that will keep NodeJS alive -process.exit() +process.exit(); diff --git a/examples/beginner/src/utils/helpers.ts b/examples/beginner/src/utils/helpers.ts index 5d07ccf8a..623326ed9 100644 --- a/examples/beginner/src/utils/helpers.ts +++ b/examples/beginner/src/utils/helpers.ts @@ -1,14 +1,14 @@ -import { type CreateApplicationCommand, hasProperty } from '@discordeno/bot' -import { bot } from '../bot.js' -import { commands, type SubCommand, type SubCommandGroup } from '../commands.js' -import { createLogger } from './logger.js' +import { type CreateApplicationCommand, hasProperty } from '@discordeno/bot'; +import { bot } from '../bot.js'; +import { commands, type SubCommand, type SubCommandGroup } from '../commands.js'; +import { createLogger } from './logger.js'; -const logger = createLogger({ name: 'Helpers' }) +const logger = createLogger({ name: 'Helpers' }); /** This function will update all commands, or the defined scope */ export async function updateCommands(scope?: 'Guild' | 'Global'): Promise { - const globalCommands: MakeRequired[] = [] - const perGuildCommands: MakeRequired[] = [] + const globalCommands: MakeRequired[] = []; + const perGuildCommands: MakeRequired[] = []; for (const command of commands.values()) { if (command.scope === 'Guild') { @@ -17,34 +17,34 @@ export async function updateCommands(scope?: 'Guild' | 'Global'): Promise description: command.description, type: command.type, options: command.options ? command.options : undefined, - }) + }); } else { globalCommands.push({ name: command.name, description: command.description, type: command.type, options: command.options ? command.options : undefined, - }) + }); } } if (globalCommands.length && (scope === 'Global' || scope === undefined)) { - logger.info('Updating Global Commands, changes should apply in short...') - await bot.helpers.upsertGlobalApplicationCommands(globalCommands).catch(logger.error) + logger.info('Updating Global Commands, changes should apply in short...'); + await bot.helpers.upsertGlobalApplicationCommands(globalCommands).catch(logger.error); } if (perGuildCommands.length && (scope === 'Guild' || scope === undefined)) { await Promise.all( bot.cache.guilds.memory.map(async (guild) => { - await bot.helpers.upsertGuildApplicationCommands(guild.id, perGuildCommands) + await bot.helpers.upsertGuildApplicationCommands(guild.id, perGuildCommands); }), - ) + ); } } /** Update commands for a guild */ export async function updateGuildCommands(guild: typeof bot.transformers.$inferredTypes.guild): Promise { - const perGuildCommands: MakeRequired[] = [] + const perGuildCommands: MakeRequired[] = []; for (const command of commands.values()) { if (command.scope === 'Guild') { @@ -53,49 +53,49 @@ export async function updateGuildCommands(guild: typeof bot.transformers.$inferr description: command.description, type: command.type, options: command.options ? command.options : undefined, - }) + }); } } if (perGuildCommands.length) { - await bot.helpers.upsertGuildApplicationCommands(guild.id, perGuildCommands) + await bot.helpers.upsertGuildApplicationCommands(guild.id, perGuildCommands); } } export async function getGuildFromId(guildId: bigint) { - const cached = await bot.cache.guilds.get(guildId) + const cached = await bot.cache.guilds.get(guildId); - if (cached) return cached + if (cached) return cached; - return await bot.helpers.getGuild(guildId) + return await bot.helpers.getGuild(guildId); } export function humanizeMilliseconds(milliseconds: number): string { // Gets ms into seconds - const time = milliseconds / 1000 - if (time < 1) return '< 1s' + const time = milliseconds / 1000; + if (time < 1) return '< 1s'; - const days = Math.floor(time / 86400) - const hours = Math.floor((time % 86400) / 3600) - const minutes = Math.floor(((time % 86400) % 3600) / 60) - const seconds = Math.floor(((time % 86400) % 3600) % 60) + const days = Math.floor(time / 86400); + const hours = Math.floor((time % 86400) / 3600); + const minutes = Math.floor(((time % 86400) % 3600) / 60); + const seconds = Math.floor(((time % 86400) % 3600) % 60); - const dayString = days ? `${days}d ` : '' - const hourString = hours ? `${hours}h ` : '' - const minuteString = minutes ? `${minutes}m ` : '' - const secondString = seconds ? `${seconds}s ` : '' + const dayString = days ? `${days}d ` : ''; + const hourString = hours ? `${hours}h ` : ''; + const minuteString = minutes ? `${minutes}m ` : ''; + const secondString = seconds ? `${seconds}s ` : ''; - return `${dayString}${hourString}${minuteString}${secondString}` + return `${dayString}${hourString}${minuteString}${secondString}`; } export function isSubCommand(data: SubCommand | SubCommandGroup): data is SubCommand { - return !hasProperty(data, 'subCommands') + return !hasProperty(data, 'subCommands'); } export function isSubCommandGroup(data: SubCommand | SubCommandGroup): data is SubCommandGroup { - return hasProperty(data, 'subCommands') + return hasProperty(data, 'subCommands'); } type MakeRequired = TObj & { - [Key in TKey]-?: TObj[Key] -} + [Key in TKey]-?: TObj[Key]; +}; diff --git a/examples/beginner/src/utils/loader.ts b/examples/beginner/src/utils/loader.ts index 5b1c6f541..213ceaf16 100644 --- a/examples/beginner/src/utils/loader.ts +++ b/examples/beginner/src/utils/loader.ts @@ -1,15 +1,15 @@ -import { readdir } from 'node:fs/promises' -import logger from './logger.js' +import { readdir } from 'node:fs/promises'; +import logger from './logger.js'; export default async function importDirectory(folder: string): Promise { - const files = await readdir(folder, { recursive: true }) + const files = await readdir(folder, { recursive: true }); for (const filename of files) { - if (!filename.endsWith('.js')) continue + if (!filename.endsWith('.js')) continue; // Using `file://` and `process.cwd()` to avoid weird issues with relative paths and/or Windows await import(`file://${process.cwd()}/${folder}/${filename}`).catch((x) => logger.fatal(`Cannot import file (${folder}/${filename}) for reason:`, x), - ) + ); } } diff --git a/examples/beginner/src/utils/logger.ts b/examples/beginner/src/utils/logger.ts index 4838e581b..47182b8b1 100644 --- a/examples/beginner/src/utils/logger.ts +++ b/examples/beginner/src/utils/logger.ts @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/no-unsafe-argument */ -import chalk from 'chalk' +import chalk from 'chalk'; export enum LogLevels { Debug, @@ -15,70 +15,70 @@ const prefixes = new Map([ [LogLevels.Warn, 'WARN'], [LogLevels.Error, 'ERROR'], [LogLevels.Fatal, 'FATAL'], -]) +]); -const noColor: (str: string) => string = (msg) => msg +const noColor: (str: string) => string = (msg) => msg; const colorFunctions = new Map string>([ [LogLevels.Debug, chalk.gray], [LogLevels.Info, chalk.cyan], [LogLevels.Warn, chalk.yellow], [LogLevels.Error, (str: string) => chalk.red(str)], [LogLevels.Fatal, (str: string) => chalk.red.bold.italic(str)], -]) +]); export function createLogger({ logLevel = LogLevels.Info, name }: { logLevel?: LogLevels; name?: string } = {}): Logger { function log(level: LogLevels, ...args: any[]): void { - if (level < logLevel) return + if (level < logLevel) return; - let color = colorFunctions.get(level) - if (!color) color = noColor + let color = colorFunctions.get(level); + if (!color) color = noColor; - const date = new Date() + const date = new Date(); const log = [ `[${date.toLocaleDateString()} ${date.toLocaleTimeString()}]`, color(prefixes.get(level) ?? 'DEBUG'), name ? `${name} >` : '>', ...args, - ] + ]; switch (level) { case LogLevels.Debug: - return console.debug(...log) + return console.debug(...log); case LogLevels.Info: - return console.info(...log) + return console.info(...log); case LogLevels.Warn: - return console.warn(...log) + return console.warn(...log); case LogLevels.Error: - return console.error(...log) + return console.error(...log); case LogLevels.Fatal: - return console.error(...log) + return console.error(...log); default: - return console.log(...log) + return console.log(...log); } } function setLevel(level: LogLevels): void { - logLevel = level + logLevel = level; } function debug(...args: any[]): void { - log(LogLevels.Debug, ...args) + log(LogLevels.Debug, ...args); } function info(...args: any[]): void { - log(LogLevels.Info, ...args) + log(LogLevels.Info, ...args); } function warn(...args: any[]): void { - log(LogLevels.Warn, ...args) + log(LogLevels.Warn, ...args); } function error(...args: any[]): void { - log(LogLevels.Error, ...args) + log(LogLevels.Error, ...args); } function fatal(...args: any[]): void { - log(LogLevels.Fatal, ...args) + log(LogLevels.Fatal, ...args); } return { @@ -89,18 +89,18 @@ export function createLogger({ logLevel = LogLevels.Info, name }: { logLevel?: L warn, error, fatal, - } + }; } -export const logger = createLogger({ name: 'Main' }) -export default logger +export const logger = createLogger({ name: 'Main' }); +export default logger; export interface Logger { - log: (level: LogLevels, ...args: any[]) => void - debug: (...args: any[]) => void - info: (...args: any[]) => void - warn: (...args: any[]) => void - error: (...args: any[]) => void - fatal: (...args: any[]) => void - setLevel: (level: LogLevels) => void + log: (level: LogLevels, ...args: any[]) => void; + debug: (...args: any[]) => void; + info: (...args: any[]) => void; + warn: (...args: any[]) => void; + error: (...args: any[]) => void; + fatal: (...args: any[]) => void; + setLevel: (level: LogLevels) => void; } diff --git a/examples/bigbot/src/bot/bot.ts b/examples/bigbot/src/bot/bot.ts index 995707597..e0dc82d53 100644 --- a/examples/bigbot/src/bot/bot.ts +++ b/examples/bigbot/src/bot/bot.ts @@ -1,7 +1,7 @@ -import { Collection, createBot } from '@discordeno/bot' -import { DISCORD_TOKEN, GATEWAY_AUTHORIZATION, GATEWAY_INTENTS, GATEWAY_URL, REST_AUTHORIZATION, REST_URL } from '../config.js' -import type { ManagerGetShardInfoFromGuildId, ShardInfo, WorkerPresencesUpdate, WorkerShardPayload } from '../gateway/worker/types.js' -import type { Command } from './commands.js' +import { Collection, createBot } from '@discordeno/bot'; +import { DISCORD_TOKEN, GATEWAY_AUTHORIZATION, GATEWAY_INTENTS, GATEWAY_URL, REST_AUTHORIZATION, REST_URL } from '../config.js'; +import type { ManagerGetShardInfoFromGuildId, ShardInfo, WorkerPresencesUpdate, WorkerShardPayload } from '../gateway/worker/types.js'; +import type { Command } from './commands.js'; const rawBot = createBot({ token: DISCORD_TOKEN, @@ -28,19 +28,19 @@ const rawBot = createBot({ authorization: REST_AUTHORIZATION, }, }, -}) +}); -export const bot = rawBot as CustomBot +export const bot = rawBot as CustomBot; // TEMPLATE-SETUP: If you want/need to add any custom properties on the Bot type, you can do it in these lines below and the `CustomBot` type below. Make sure to do it in both or else you will get an error by TypeScript -bot.commands = new Collection() +bot.commands = new Collection(); -overrideGatewayImplementations(bot) +overrideGatewayImplementations(bot); export type CustomBot = typeof rawBot & { - commands: Collection -} + commands: Collection; +}; // Override the default gateway functions to allow the methods on the gateway object to proxy the requests to the gateway proxy function overrideGatewayImplementations(bot: CustomBot): void { @@ -56,8 +56,8 @@ function overrideGatewayImplementations(bot: CustomBot): void { 'Content-Type': 'application/json', Authorization: GATEWAY_AUTHORIZATION, }, - }) - } + }); + }; bot.gateway.editBotStatus = async (payload) => { await fetch(GATEWAY_URL, { @@ -70,8 +70,8 @@ function overrideGatewayImplementations(bot: CustomBot): void { 'Content-Type': 'application/json', Authorization: GATEWAY_AUTHORIZATION, }, - }) - } + }); + }; } export async function getShardInfoFromGuild(guildId?: bigint): Promise> { @@ -85,11 +85,11 @@ export async function getShardInfoFromGuild(guildId?: bigint): Promise(command: Command): void { - bot.commands.set(command.name, command as Command) + bot.commands.set(command.name, command as Command); } export type Command = CreateApplicationCommand & { /** @inheritdoc */ - options?: TOptions + options?: TOptions; /** * Should this command be only deployed on the Dev guild? * * @default false */ - devOnly?: boolean + devOnly?: boolean; /** Function to run when the interaction is executed */ - run: (interaction: typeof bot.transformers.$inferredTypes.interaction, options: GetCommandOptions) => unknown + run: (interaction: typeof bot.transformers.$inferredTypes.interaction, options: GetCommandOptions) => unknown; /** Function to run when an autocomplete interaction is fired */ - autoComplete?: (interaction: typeof bot.transformers.$inferredTypes.interaction, options: GetCommandOptions) => unknown -} + autoComplete?: (interaction: typeof bot.transformers.$inferredTypes.interaction, options: GetCommandOptions) => unknown; +}; export type GetCommandOptions = T extends CommandOptions ? { [Prop in keyof BuildOptions as Prop]: BuildOptions[Prop] } - : never + : never; -export type CommandOption = Camelize -export type CommandOptions = CommandOption[] +export type CommandOption = Camelize; +export type CommandOptions = CommandOption[]; // Option parsing -type ResolvedValues = ParsedInteractionOption, ExtractDesiredBehavior>[string] +type ResolvedValues = ParsedInteractionOption, ExtractDesiredBehavior>[string]; // Using omit + exclude is a slight trick to avoid a type error on Pick export type InteractionResolvedChannel = Omit< typeof bot.transformers.$inferredTypes.channel, Exclude -> -export type InteractionResolvedMember = Omit +>; +export type InteractionResolvedMember = Omit; export interface InteractionResolvedUser { - user: typeof bot.transformers.$inferredTypes.user - member: InteractionResolvedMember + user: typeof bot.transformers.$inferredTypes.user; + member: InteractionResolvedMember; } /** @@ -56,30 +56,30 @@ export interface InteractionResolvedUser { * The entries are sorted based on the enum value */ interface TypeToResolvedMap { - [ApplicationCommandOptionTypes.String]: string - [ApplicationCommandOptionTypes.Integer]: number - [ApplicationCommandOptionTypes.Boolean]: boolean - [ApplicationCommandOptionTypes.User]: InteractionResolvedUser - [ApplicationCommandOptionTypes.Channel]: InteractionResolvedChannel - [ApplicationCommandOptionTypes.Role]: typeof bot.transformers.$inferredTypes.role - [ApplicationCommandOptionTypes.Mentionable]: typeof bot.transformers.$inferredTypes.role | InteractionResolvedUser - [ApplicationCommandOptionTypes.Number]: number - [ApplicationCommandOptionTypes.Attachment]: typeof bot.transformers.$inferredTypes.attachment + [ApplicationCommandOptionTypes.String]: string; + [ApplicationCommandOptionTypes.Integer]: number; + [ApplicationCommandOptionTypes.Boolean]: boolean; + [ApplicationCommandOptionTypes.User]: InteractionResolvedUser; + [ApplicationCommandOptionTypes.Channel]: InteractionResolvedChannel; + [ApplicationCommandOptionTypes.Role]: typeof bot.transformers.$inferredTypes.role; + [ApplicationCommandOptionTypes.Mentionable]: typeof bot.transformers.$inferredTypes.role | InteractionResolvedUser; + [ApplicationCommandOptionTypes.Number]: number; + [ApplicationCommandOptionTypes.Attachment]: typeof bot.transformers.$inferredTypes.attachment; } -type ConvertTypeToResolved = T extends keyof TypeToResolvedMap ? TypeToResolvedMap[T] : ResolvedValues +type ConvertTypeToResolved = T extends keyof TypeToResolvedMap ? TypeToResolvedMap[T] : ResolvedValues; -type SubCommandApplicationCommand = ApplicationCommandOptionTypes.SubCommand | ApplicationCommandOptionTypes.SubCommandGroup -type GetOptionName = T extends { name: string } ? T['name'] : never +type SubCommandApplicationCommand = ApplicationCommandOptionTypes.SubCommand | ApplicationCommandOptionTypes.SubCommandGroup; +type GetOptionName = T extends { name: string } ? T['name'] : never; type GetOptionValue = T extends { type: ApplicationCommandOptionTypes; required?: boolean } ? T extends { type: SubCommandApplicationCommand; options?: CommandOptions } ? BuildOptions : ConvertTypeToResolved | (T['required'] extends true ? never : undefined) - : never + : never; type BuildOptions = { - [Prop in keyof Omit as GetOptionName]: GetOptionValue -} + [Prop in keyof Omit as GetOptionName]: GetOptionValue; +}; -type ExtractDesiredProps = T extends Bot ? Props : never -type ExtractDesiredBehavior = T extends Bot ? Behavior : never +type ExtractDesiredProps = T extends Bot ? Props : never; +type ExtractDesiredBehavior = T extends Bot ? Behavior : never; diff --git a/examples/bigbot/src/bot/commands/ping.ts b/examples/bigbot/src/bot/commands/ping.ts index 8562faf0c..75793ba45 100644 --- a/examples/bigbot/src/bot/commands/ping.ts +++ b/examples/bigbot/src/bot/commands/ping.ts @@ -1,16 +1,16 @@ -import { snowflakeToTimestamp } from '@discordeno/bot' -import { getShardInfoFromGuild } from '../bot.js' -import createCommand from '../commands.js' +import { snowflakeToTimestamp } from '@discordeno/bot'; +import { getShardInfoFromGuild } from '../bot.js'; +import createCommand from '../commands.js'; createCommand({ name: 'ping', description: '🏓 Check whether the bot is online and responsive.', async run(interaction) { - const ping = Date.now() - snowflakeToTimestamp(interaction.id) - const shardInfo = await getShardInfoFromGuild(interaction.guildId) + const ping = Date.now() - snowflakeToTimestamp(interaction.id); + const shardInfo = await getShardInfoFromGuild(interaction.guildId); - const shardPing = shardInfo.rtt === -1 ? '*Not yet available*' : `${shardInfo.rtt}ms` + const shardPing = shardInfo.rtt === -1 ? '*Not yet available*' : `${shardInfo.rtt}ms`; - await interaction.respond(`🏓 Pong! Gateway Latency: ${shardPing}, Roundtrip Latency: ${ping}ms. I am online and responsive! 🕙`) + await interaction.respond(`🏓 Pong! Gateway Latency: ${shardPing}, Roundtrip Latency: ${ping}ms. I am online and responsive! 🕙`); }, -}) +}); diff --git a/examples/bigbot/src/bot/events/interactions/create.ts b/examples/bigbot/src/bot/events/interactions/create.ts index ce2a2526b..6fecbde82 100644 --- a/examples/bigbot/src/bot/events/interactions/create.ts +++ b/examples/bigbot/src/bot/events/interactions/create.ts @@ -1,39 +1,39 @@ -import { commandOptionsParser, InteractionTypes, LogLevels, type logger } from '@discordeno/bot' -import chalk from 'chalk' -import { bot } from '../../bot.js' +import { commandOptionsParser, InteractionTypes, LogLevels, type logger } from '@discordeno/bot'; +import chalk from 'chalk'; +import { bot } from '../../bot.js'; bot.events.interactionCreate = async (interaction) => { - const isAutocomplete = interaction.type === InteractionTypes.ApplicationCommandAutocomplete - const isCommandOrAutocomplete = interaction.type === InteractionTypes.ApplicationCommand || isAutocomplete + const isAutocomplete = interaction.type === InteractionTypes.ApplicationCommandAutocomplete; + const isCommandOrAutocomplete = interaction.type === InteractionTypes.ApplicationCommand || isAutocomplete; - if (!interaction.data || !isCommandOrAutocomplete) return + if (!interaction.data || !isCommandOrAutocomplete) return; - const command = bot.commands.get(interaction.data.name) + const command = bot.commands.get(interaction.data.name); if (!command) { - logCommand(interaction, 'Missing', interaction.data.name) - await interaction.respond('❌ Something went wrong. I was not able to find this command.') + logCommand(interaction, 'Missing', interaction.data.name); + await interaction.respond('❌ Something went wrong. I was not able to find this command.'); - return + return; } - logCommand(interaction, 'Trigger', interaction.data.name) + logCommand(interaction, 'Trigger', interaction.data.name); - const options = commandOptionsParser(interaction) + const options = commandOptionsParser(interaction); try { if (isAutocomplete) { - await command.autoComplete?.(interaction, options) + await command.autoComplete?.(interaction, options); } else { - await command.run(interaction, options) + await command.run(interaction, options); } - logCommand(interaction, 'Success', interaction.data.name) + logCommand(interaction, 'Success', interaction.data.name); } catch (error) { - logCommand(interaction, 'Failure', interaction.data.name, LogLevels.Error, error) - await interaction.respond('❌ Something went wrong. The command execution has thrown an error.') + logCommand(interaction, 'Failure', interaction.data.name, LogLevels.Error, error); + await interaction.respond('❌ Something went wrong. The command execution has thrown an error.'); } -} +}; function logCommand( interaction: typeof bot.transformers.$inferredTypes.interaction, @@ -42,11 +42,11 @@ function logCommand( logLevel: LogLevels = LogLevels.Info, ...restArgs: unknown[] ): void { - const typeColor = ['Failure', 'Missing'].includes(type) ? chalk.red(type) : type === 'Success' ? chalk.green(type) : chalk.white(type) + const typeColor = ['Failure', 'Missing'].includes(type) ? chalk.red(type) : type === 'Success' ? chalk.green(type) : chalk.white(type); - const autocomplete = interaction.type === InteractionTypes.ApplicationCommandAutocomplete ? ' (AutoComplete) ' : '' - const command = `Command${autocomplete}: ${chalk.bgYellow.black(commandName || 'Unknown')} - ${chalk.bgBlack(typeColor)}` - const user = chalk.bgGreen.black(`@${interaction.user.username} (${interaction.user.id})`) - const guild = chalk.bgMagenta.black(interaction.guildId ? `guildId: ${interaction.guildId}` : 'DM') - ;(bot.logger as typeof logger).log(logLevel, `${command} - By ${user} in ${guild}`, ...restArgs) + const autocomplete = interaction.type === InteractionTypes.ApplicationCommandAutocomplete ? ' (AutoComplete) ' : ''; + const command = `Command${autocomplete}: ${chalk.bgYellow.black(commandName || 'Unknown')} - ${chalk.bgBlack(typeColor)}`; + const user = chalk.bgGreen.black(`@${interaction.user.username} (${interaction.user.id})`); + const guild = chalk.bgMagenta.black(interaction.guildId ? `guildId: ${interaction.guildId}` : 'DM'); + (bot.logger as typeof logger).log(logLevel, `${command} - By ${user} in ${guild}`, ...restArgs); } diff --git a/examples/bigbot/src/bot/events/nodejs.ts b/examples/bigbot/src/bot/events/nodejs.ts index 354654ccd..e3d478ad4 100644 --- a/examples/bigbot/src/bot/events/nodejs.ts +++ b/examples/bigbot/src/bot/events/nodejs.ts @@ -1,21 +1,21 @@ -import { inspect } from 'node:util' -import { createEmbeds } from '@discordeno/bot' -import { BUGS_ERRORS_REPORT_WEBHOOK } from '../../config.js' -import { bot } from '../bot.js' -import { webhookURLToIDAndToken } from '../utils/webhook.js' +import { inspect } from 'node:util'; +import { createEmbeds } from '@discordeno/bot'; +import { BUGS_ERRORS_REPORT_WEBHOOK } from '../../config.js'; +import { bot } from '../bot.js'; +import { webhookURLToIDAndToken } from '../utils/webhook.js'; process.on('unhandledRejection', async (error) => { - bot.logger.error('An unhandled rejection occurred', error) + bot.logger.error('An unhandled rejection occurred', error); - if (!BUGS_ERRORS_REPORT_WEBHOOK || !error) return + if (!BUGS_ERRORS_REPORT_WEBHOOK || !error) return; - const { id, token } = webhookURLToIDAndToken(BUGS_ERRORS_REPORT_WEBHOOK) + const { id, token } = webhookURLToIDAndToken(BUGS_ERRORS_REPORT_WEBHOOK); - if (!id || !token) return + if (!id || !token) return; - const inspectedError = inspect(error) + const inspectedError = inspect(error); - const embeds = createEmbeds().setDescription(`\`\`\`${inspectedError}\`\`\``).setFooter('Unhandled rejection occurred').setTimestamp(Date.now()) + const embeds = createEmbeds().setDescription(`\`\`\`${inspectedError}\`\`\``).setFooter('Unhandled rejection occurred').setTimestamp(Date.now()); - await bot.helpers.executeWebhook(id, token, { embeds }) -}) + await bot.helpers.executeWebhook(id, token, { embeds }); +}); diff --git a/examples/bigbot/src/bot/fastify.ts b/examples/bigbot/src/bot/fastify.ts index 800784db1..750d1b96e 100644 --- a/examples/bigbot/src/bot/fastify.ts +++ b/examples/bigbot/src/bot/fastify.ts @@ -1,17 +1,17 @@ -import fastify, { type FastifyInstance } from 'fastify' -import { EVENT_HANDLER_AUTHORIZATION } from '../config.js' +import fastify, { type FastifyInstance } from 'fastify'; +import { EVENT_HANDLER_AUTHORIZATION } from '../config.js'; export function buildFastifyApp(): FastifyInstance { - const app = fastify() + const app = fastify(); // Authorization check app.addHook('onRequest', async (req, res) => { if (req.headers.authorization !== EVENT_HANDLER_AUTHORIZATION) { res.status(401).send({ message: 'Credentials not valid.', - }) + }); } - }) + }); - return app + return app; } diff --git a/examples/bigbot/src/bot/index.ts b/examples/bigbot/src/bot/index.ts index 9a63ee1de..4db800f2a 100644 --- a/examples/bigbot/src/bot/index.ts +++ b/examples/bigbot/src/bot/index.ts @@ -1,6 +1,6 @@ -import { join as joinPath } from 'node:path' -import type { DiscordGatewayPayload, GatewayDispatchEventNames } from '@discordeno/bot' -import { connect as connectAmqp } from 'amqplib' +import { join as joinPath } from 'node:path'; +import type { DiscordGatewayPayload, GatewayDispatchEventNames } from '@discordeno/bot'; +import { connect as connectAmqp } from 'amqplib'; import { EVENT_HANDLER_HOST, EVENT_HANDLER_PORT, @@ -8,81 +8,81 @@ import { MESSAGEQUEUE_PASSWORD, MESSAGEQUEUE_URL, MESSAGEQUEUE_USERNAME, -} from '../config.js' -import { getDirnameFromFileUrl } from '../util.js' -import { bot } from './bot.js' -import { buildFastifyApp } from './fastify.js' -import importDirectory from './utils/loader.js' +} from '../config.js'; +import { getDirnameFromFileUrl } from '../util.js'; +import { bot } from './bot.js'; +import { buildFastifyApp } from './fastify.js'; +import importDirectory from './utils/loader.js'; // The importDirectory function uses 'readdir' that requires either a relative path compared to the process CWD or an absolute one, so to get one relative we need to use import.meta.url -const currentDirectory = getDirnameFromFileUrl(import.meta.url) +const currentDirectory = getDirnameFromFileUrl(import.meta.url); -await importDirectory(joinPath(currentDirectory, './commands')) -await importDirectory(joinPath(currentDirectory, './events')) +await importDirectory(joinPath(currentDirectory, './commands')); +await importDirectory(joinPath(currentDirectory, './events')); if (MESSAGEQUEUE_ENABLE) { - await connectToRabbitMQ() + await connectToRabbitMQ(); } -const app = buildFastifyApp() +const app = buildFastifyApp(); app.get('/timecheck', async (_req, res) => { - res.status(200).send({ message: Date.now() }) -}) + res.status(200).send({ message: Date.now() }); +}); app.post('/', async (req, res) => { - const body = req.body as GatewayEvent + const body = req.body as GatewayEvent; try { - handleGatewayEvent(body.payload, body.shardId) + handleGatewayEvent(body.payload, body.shardId); - res.status(200).send() + res.status(200).send(); } catch (error) { - bot.logger.error('There was an error handling the incoming gateway command', error) - res.status(500).send() + bot.logger.error('There was an error handling the incoming gateway command', error); + res.status(500).send(); } -}) +}); await app.listen({ host: EVENT_HANDLER_HOST, port: EVENT_HANDLER_PORT, -}) +}); -bot.logger.info(`Bot event handler is listening on port ${EVENT_HANDLER_PORT}`) +bot.logger.info(`Bot event handler is listening on port ${EVENT_HANDLER_PORT}`); async function handleGatewayEvent(payload: DiscordGatewayPayload, shardId: number): Promise { - bot.events.raw?.(payload, shardId) + bot.events.raw?.(payload, shardId); // If we don't have the event type we don't process it further - if (!payload.t) return + if (!payload.t) return; // Run the dispatch check - await bot.events.dispatchRequirements?.(payload, shardId) + await bot.events.dispatchRequirements?.(payload, shardId); - bot.handlers[payload.t as GatewayDispatchEventNames]?.(bot, payload, shardId) + bot.handlers[payload.t as GatewayDispatchEventNames]?.(bot, payload, shardId); } async function connectToRabbitMQ(): Promise { const connection = await connectAmqp(`amqp://${MESSAGEQUEUE_USERNAME}:${MESSAGEQUEUE_PASSWORD}@${MESSAGEQUEUE_URL}`).catch((error) => { - bot.logger.error('Failed to connect to RabbitMQ, retrying in 1s.', error) - setTimeout(connectToRabbitMQ, 1000) - }) + bot.logger.error('Failed to connect to RabbitMQ, retrying in 1s.', error); + setTimeout(connectToRabbitMQ, 1000); + }); - if (!connection) return + if (!connection) return; connection.on('close', () => { - setTimeout(connectToRabbitMQ, 1000) - }) + setTimeout(connectToRabbitMQ, 1000); + }); connection.on('error', (error) => { - bot.logger.error('There was an error in the connection with RabbitMQ, reconnecting in 1s.', error) - setTimeout(connectToRabbitMQ, 1000) - }) + bot.logger.error('There was an error in the connection with RabbitMQ, reconnecting in 1s.', error); + setTimeout(connectToRabbitMQ, 1000); + }); const channel = await connection.createChannel().catch((error) => { - bot.logger.error('There was an error creating the RabbitMQ channel', error) - }) + bot.logger.error('There was an error creating the RabbitMQ channel', error); + }); - if (!channel) return + if (!channel) return; const exchange = await channel .assertExchange('gatewayMessage', 'x-message-deduplication', { @@ -93,31 +93,31 @@ async function connectToRabbitMQ(): Promise { }, }) .catch((error) => { - bot.logger.error('There was an error asserting the exchange', error) - }) + bot.logger.error('There was an error asserting the exchange', error); + }); - if (!exchange) return + if (!exchange) return; - await channel.assertQueue('gatewayMessageQueue').catch(bot.logger.error) - await channel.bindQueue('gatewayMessageQueue', 'gatewayMessage', '').catch(bot.logger.error) + await channel.assertQueue('gatewayMessageQueue').catch(bot.logger.error); + await channel.bindQueue('gatewayMessageQueue', 'gatewayMessage', '').catch(bot.logger.error); await channel .consume('gatewayMessageQueue', async (message) => { - if (!message) return + if (!message) return; try { - const messageBody = JSON.parse(message.content.toString()) as GatewayEvent + const messageBody = JSON.parse(message.content.toString()) as GatewayEvent; - await handleGatewayEvent(messageBody.payload, messageBody.shardId) + await handleGatewayEvent(messageBody.payload, messageBody.shardId); - channel.ack(message) + channel.ack(message); } catch (error) { - bot.logger.error('There was an error handling events received from RabbitMQ', error) + bot.logger.error('There was an error handling events received from RabbitMQ', error); } }) - .catch(bot.logger.error) + .catch(bot.logger.error); } interface GatewayEvent { - payload: DiscordGatewayPayload - shardId: number + payload: DiscordGatewayPayload; + shardId: number; } diff --git a/examples/bigbot/src/bot/register-commands.ts b/examples/bigbot/src/bot/register-commands.ts index 494fb4f56..b23e19468 100644 --- a/examples/bigbot/src/bot/register-commands.ts +++ b/examples/bigbot/src/bot/register-commands.ts @@ -1,19 +1,19 @@ -import 'dotenv/config' +import 'dotenv/config'; -import { join as joinPath } from 'node:path' -import { getDirnameFromFileUrl } from '../util.js' -import { bot } from './bot.js' -import importDirectory from './utils/loader.js' -import { updateCommands } from './utils/updateCommands.js' +import { join as joinPath } from 'node:path'; +import { getDirnameFromFileUrl } from '../util.js'; +import { bot } from './bot.js'; +import importDirectory from './utils/loader.js'; +import { updateCommands } from './utils/updateCommands.js'; // The importDirectory function uses 'readdir' that requires either a relative path compared to the process CWD or an absolute one, so to get one relative we need to use import.meta.url -const currentDirectory = getDirnameFromFileUrl(import.meta.url) +const currentDirectory = getDirnameFromFileUrl(import.meta.url); -await importDirectory(joinPath(currentDirectory, './commands')) +await importDirectory(joinPath(currentDirectory, './commands')); -await updateCommands() +await updateCommands(); -bot.logger.info('Done!') +bot.logger.info('Done!'); // We need to manually exit as the REST Manager has timeouts that will keep NodeJS alive -process.exit() +process.exit(); diff --git a/examples/bigbot/src/bot/utils/loader.ts b/examples/bigbot/src/bot/utils/loader.ts index ff0af7113..41b5318d3 100644 --- a/examples/bigbot/src/bot/utils/loader.ts +++ b/examples/bigbot/src/bot/utils/loader.ts @@ -1,13 +1,13 @@ -import { readdir } from 'node:fs/promises' -import { bot } from '../bot.js' +import { readdir } from 'node:fs/promises'; +import { bot } from '../bot.js'; export default async function importDirectory(folder: string): Promise { - const files = await readdir(folder, { recursive: true }) + const files = await readdir(folder, { recursive: true }); for (const filename of files) { - if (!filename.endsWith('.js')) continue + if (!filename.endsWith('.js')) continue; // Using `file://` to avoid weird issues with paths on Windows - await import(`file://${folder}/${filename}`).catch((x) => bot.logger.fatal(`Cannot import file (${folder}/${filename}) for reason:`, x)) + await import(`file://${folder}/${filename}`).catch((x) => bot.logger.fatal(`Cannot import file (${folder}/${filename}) for reason:`, x)); } } diff --git a/examples/bigbot/src/bot/utils/updateCommands.ts b/examples/bigbot/src/bot/utils/updateCommands.ts index 109dc6c66..da1a2e21b 100644 --- a/examples/bigbot/src/bot/utils/updateCommands.ts +++ b/examples/bigbot/src/bot/utils/updateCommands.ts @@ -1,19 +1,19 @@ -import assert from 'node:assert' -import { DEV_SERVER_ID, DEVELOPMENT } from '../../config.js' -import { bot } from '../bot.js' +import assert from 'node:assert'; +import { DEV_SERVER_ID, DEVELOPMENT } from '../../config.js'; +import { bot } from '../bot.js'; export async function updateCommands(): Promise { - bot.logger.info('Updating commands') + bot.logger.info('Updating commands'); - const userCommands = bot.commands.filter((x) => !x.devOnly).array() - await bot.helpers.upsertGlobalApplicationCommands(userCommands) + const userCommands = bot.commands.filter((x) => !x.devOnly).array(); + await bot.helpers.upsertGlobalApplicationCommands(userCommands); if (DEVELOPMENT) { - assert(DEV_SERVER_ID, 'The DEV_SERVER_ID environment is missing') + assert(DEV_SERVER_ID, 'The DEV_SERVER_ID environment is missing'); - bot.logger.info('Updating developer commands') + bot.logger.info('Updating developer commands'); - const devCommands = bot.commands.filter((x) => x.devOnly ?? false).array() - await bot.helpers.upsertGuildApplicationCommands(DEV_SERVER_ID, devCommands) + const devCommands = bot.commands.filter((x) => x.devOnly ?? false).array(); + await bot.helpers.upsertGuildApplicationCommands(DEV_SERVER_ID, devCommands); } } diff --git a/examples/bigbot/src/bot/utils/webhook.ts b/examples/bigbot/src/bot/utils/webhook.ts index 2dea8f7f6..29ef9c9a8 100644 --- a/examples/bigbot/src/bot/utils/webhook.ts +++ b/examples/bigbot/src/bot/utils/webhook.ts @@ -1,9 +1,9 @@ /** Get the webhook id and token from a webhook url. */ export function webhookURLToIDAndToken(url: string): { id?: string; token?: string } { - const [id, token] = url.substring(url.indexOf('webhooks/') + 9).split('/') + const [id, token] = url.substring(url.indexOf('webhooks/') + 9).split('/'); return { id, token, - } + }; } diff --git a/examples/bigbot/src/config.ts b/examples/bigbot/src/config.ts index 42138fb88..c44eabe2c 100644 --- a/examples/bigbot/src/config.ts +++ b/examples/bigbot/src/config.ts @@ -1,78 +1,78 @@ -import 'dotenv/config' +import 'dotenv/config'; -import { Intents } from '@discordeno/bot' +import { Intents } from '@discordeno/bot'; // #region Mapping of environment variables to javascript variables with some minimal parsing // General Configurations -export const DEVELOPMENT = process.env.DEVELOPMENT === 'true' -export const DEV_SERVER_ID = process.env.DEV_SERVER_ID -export const DISCORD_TOKEN = assertEnv('DISCORD_TOKEN') +export const DEVELOPMENT = process.env.DEVELOPMENT === 'true'; +export const DEV_SERVER_ID = process.env.DEV_SERVER_ID; +export const DISCORD_TOKEN = assertEnv('DISCORD_TOKEN'); // Bot Configuration -export const EVENT_HANDLER_AUTHORIZATION = assertEnv('EVENT_HANDLER_AUTHORIZATION') +export const EVENT_HANDLER_AUTHORIZATION = assertEnv('EVENT_HANDLER_AUTHORIZATION'); -export const EVENT_HANDLER_HOST = assertEnv('EVENT_HANDLER_HOST') -export const EVENT_HANDLER_PORT = parseNumber(assertEnv('EVENT_HANDLER_PORT'), 'EVENT_HANDLER_PORT') +export const EVENT_HANDLER_HOST = assertEnv('EVENT_HANDLER_HOST'); +export const EVENT_HANDLER_PORT = parseNumber(assertEnv('EVENT_HANDLER_PORT'), 'EVENT_HANDLER_PORT'); -export const BUGS_ERRORS_REPORT_WEBHOOK = process.env.BUGS_ERRORS_REPORT_WEBHOOK +export const BUGS_ERRORS_REPORT_WEBHOOK = process.env.BUGS_ERRORS_REPORT_WEBHOOK; // Rest Proxy Configurations -export const REST_AUTHORIZATION = assertEnv('REST_AUTHORIZATION') -export const REST_HOST = assertEnv('REST_HOST') -export const REST_PORT = parseNumber(assertEnv('REST_PORT'), 'REST_PORT') +export const REST_AUTHORIZATION = assertEnv('REST_AUTHORIZATION'); +export const REST_HOST = assertEnv('REST_HOST'); +export const REST_PORT = parseNumber(assertEnv('REST_PORT'), 'REST_PORT'); // Gateway Proxy Configurations -export const TOTAL_SHARDS = process.env.TOTAL_SHARDS ? parseNumber(process.env.TOTAL_SHARDS, 'TOTAL_SHARDS') : undefined -export const SHARDS_PER_WORKER = parseNumber(process.env.SHARDS_PER_WORKER ?? '16', 'SHARDS_PER_WORKER') -export const TOTAL_WORKERS = parseNumber(process.env.TOTAL_WORKERS ?? '4', 'TOTAL_WORKERS') +export const TOTAL_SHARDS = process.env.TOTAL_SHARDS ? parseNumber(process.env.TOTAL_SHARDS, 'TOTAL_SHARDS') : undefined; +export const SHARDS_PER_WORKER = parseNumber(process.env.SHARDS_PER_WORKER ?? '16', 'SHARDS_PER_WORKER'); +export const TOTAL_WORKERS = parseNumber(process.env.TOTAL_WORKERS ?? '4', 'TOTAL_WORKERS'); -export const GATEWAY_AUTHORIZATION = assertEnv('GATEWAY_AUTHORIZATION') -export const GATEWAY_HOST = assertEnv('GATEWAY_HOST') -export const GATEWAY_PORT = parseNumber(assertEnv('GATEWAY_PORT'), 'GATEWAY_PORT') +export const GATEWAY_AUTHORIZATION = assertEnv('GATEWAY_AUTHORIZATION'); +export const GATEWAY_HOST = assertEnv('GATEWAY_HOST'); +export const GATEWAY_PORT = parseNumber(assertEnv('GATEWAY_PORT'), 'GATEWAY_PORT'); // Message queue (RabbitMQ configuration) -export const MESSAGEQUEUE_ENABLE = process.env.MESSAGEQUEUE_ENABLE === 'true' +export const MESSAGEQUEUE_ENABLE = process.env.MESSAGEQUEUE_ENABLE === 'true'; -export const MESSAGEQUEUE_URL = process.env.MESSAGEQUEUE_URL -export const MESSAGEQUEUE_USERNAME = process.env.MESSAGEQUEUE_USERNAME -export const MESSAGEQUEUE_PASSWORD = process.env.MESSAGEQUEUE_PASSWORD +export const MESSAGEQUEUE_URL = process.env.MESSAGEQUEUE_URL; +export const MESSAGEQUEUE_USERNAME = process.env.MESSAGEQUEUE_USERNAME; +export const MESSAGEQUEUE_PASSWORD = process.env.MESSAGEQUEUE_PASSWORD; // Analytics (InfluxDB configuration) -export const INFLUX_ORG = process.env.INFLUX_ORG -export const INFLUX_BUCKET = process.env.INFLUX_BUCKET -export const INFLUX_TOKEN = process.env.INFLUX_TOKEN -export const INFLUX_URL = process.env.INFLUX_URL +export const INFLUX_ORG = process.env.INFLUX_ORG; +export const INFLUX_BUCKET = process.env.INFLUX_BUCKET; +export const INFLUX_TOKEN = process.env.INFLUX_TOKEN; +export const INFLUX_URL = process.env.INFLUX_URL; -export const INFLUX_ENABLED = INFLUX_URL && INFLUX_TOKEN && INFLUX_ORG && INFLUX_BUCKET +export const INFLUX_ENABLED = INFLUX_URL && INFLUX_TOKEN && INFLUX_ORG && INFLUX_BUCKET; // #endregion -export const EVENT_HANDLER_URL = `http://${EVENT_HANDLER_HOST}:${EVENT_HANDLER_PORT}` -export const REST_URL = `http://${REST_HOST}:${REST_PORT}` -export const GATEWAY_URL = `http://${GATEWAY_HOST}:${GATEWAY_PORT}` +export const EVENT_HANDLER_URL = `http://${EVENT_HANDLER_HOST}:${EVENT_HANDLER_PORT}`; +export const REST_URL = `http://${REST_HOST}:${REST_PORT}`; +export const GATEWAY_URL = `http://${GATEWAY_HOST}:${GATEWAY_PORT}`; // TEMPLATE-SETUP: Add/Remove the intents you need/don't need -export const GATEWAY_INTENTS = Intents.Guilds | Intents.GuildMessages +export const GATEWAY_INTENTS = Intents.Guilds | Intents.GuildMessages; // Helper functions function assertEnv(env: string): string { - if (process.env[env]) return process.env[env] + if (process.env[env]) return process.env[env]; - throw new TypeError(`The '${env}' environment variable must be set`) + throw new TypeError(`The '${env}' environment variable must be set`); } function parseNumber(envValue: string, env: string): number { - const parsed = Number.parseInt(envValue) + const parsed = Number.parseInt(envValue); - if (Number.isFinite(parsed)) return parsed + if (Number.isFinite(parsed)) return parsed; - throw new TypeError(`The '${env}' environment variable must be a number`) + throw new TypeError(`The '${env}' environment variable must be a number`); } diff --git a/examples/bigbot/src/gateway/fastify.ts b/examples/bigbot/src/gateway/fastify.ts index 35e6aa159..7c21c0b5b 100644 --- a/examples/bigbot/src/gateway/fastify.ts +++ b/examples/bigbot/src/gateway/fastify.ts @@ -1,17 +1,17 @@ -import fastify, { type FastifyInstance } from 'fastify' -import { GATEWAY_AUTHORIZATION } from '../config.js' +import fastify, { type FastifyInstance } from 'fastify'; +import { GATEWAY_AUTHORIZATION } from '../config.js'; export function buildFastifyApp(): FastifyInstance { - const app = fastify() + const app = fastify(); // Authorization check app.addHook('onRequest', async (req, res) => { if (req.headers.authorization !== GATEWAY_AUTHORIZATION) { res.status(401).send({ message: 'Credentials not valid.', - }) + }); } - }) + }); - return app + return app; } diff --git a/examples/bigbot/src/gateway/gatewayManager.ts b/examples/bigbot/src/gateway/gatewayManager.ts index fb57c2b31..6ba188729 100644 --- a/examples/bigbot/src/gateway/gatewayManager.ts +++ b/examples/bigbot/src/gateway/gatewayManager.ts @@ -1,12 +1,12 @@ -import type { Worker } from 'node:worker_threads' -import { createGatewayManager, createLogger, createRestManager } from '@discordeno/bot' -import { DISCORD_TOKEN, GATEWAY_INTENTS, REST_AUTHORIZATION, REST_URL, SHARDS_PER_WORKER, TOTAL_SHARDS, TOTAL_WORKERS } from '../config.js' -import { promiseWithResolvers } from '../util.js' -import { createWorker } from './worker/createWorker.js' -import type { ManagerMessage, WorkerMessage } from './worker/types.js' +import type { Worker } from 'node:worker_threads'; +import { createGatewayManager, createLogger, createRestManager } from '@discordeno/bot'; +import { DISCORD_TOKEN, GATEWAY_INTENTS, REST_AUTHORIZATION, REST_URL, SHARDS_PER_WORKER, TOTAL_SHARDS, TOTAL_WORKERS } from '../config.js'; +import { promiseWithResolvers } from '../util.js'; +import { createWorker } from './worker/createWorker.js'; +import type { ManagerMessage, WorkerMessage } from './worker/types.js'; -export const workers = new Map() -export const logger = createLogger({ name: 'GATEWAY' }) +export const workers = new Map(); +export const logger = createLogger({ name: 'GATEWAY' }); const restManager = createRestManager({ token: DISCORD_TOKEN, @@ -14,9 +14,9 @@ const restManager = createRestManager({ baseUrl: REST_URL, authorization: REST_AUTHORIZATION, }, -}) +}); -const gatewayBotConfig = await restManager.getGatewayBot() +const gatewayBotConfig = await restManager.getGatewayBot(); const gatewayManager = createGatewayManager({ token: DISCORD_TOKEN, @@ -28,96 +28,96 @@ const gatewayManager = createGatewayManager({ resharding: { getSessionInfo: restManager.getGatewayBot, }, -}) +}); gatewayManager.resharding.tellWorkerToPrepare = async (workerId, shardId, bucketId) => { - logger.info(`Tell worker to prepare, workerId: ${workerId}, shardId: ${shardId}, bucketId: ${bucketId}`) + logger.info(`Tell worker to prepare, workerId: ${workerId}, shardId: ${shardId}, bucketId: ${bucketId}`); - let worker = workers.get(workerId) + let worker = workers.get(workerId); if (!worker) { - worker = createWorker(workerId) - workers.set(workerId, worker) + worker = createWorker(workerId); + workers.set(workerId, worker); } worker.postMessage({ type: 'PrepareShard', shardId, totalShards: gatewayManager.totalShards, - } satisfies WorkerMessage) + } satisfies WorkerMessage); - const { promise, resolve } = promiseWithResolvers() + const { promise, resolve } = promiseWithResolvers(); const waitForShardPrepared = (message: ManagerMessage) => { if (message.type === 'ShardPrepared' && message.shardId === shardId) { - resolve() + resolve(); } - } + }; - worker.on('message', waitForShardPrepared) + worker.on('message', waitForShardPrepared); - await promise + await promise; - worker.off('message', waitForShardPrepared) -} + worker.off('message', waitForShardPrepared); +}; gatewayManager.resharding.onReshardingSwitch = async () => { - logger.info('Resharding switch triggered, telling workers to switch the shards') + logger.info('Resharding switch triggered, telling workers to switch the shards'); for (const worker of workers.values()) { worker.postMessage({ type: 'SwitchShards', - } satisfies WorkerMessage) + } satisfies WorkerMessage); } -} +}; gatewayManager.tellWorkerToIdentify = async (workerId, shardId, bucketId) => { - logger.info(`Tell worker to identify, workerId: ${workerId}, shardId: ${shardId}, bucketId: ${bucketId}`) + logger.info(`Tell worker to identify, workerId: ${workerId}, shardId: ${shardId}, bucketId: ${bucketId}`); - const worker = workers.get(workerId) ?? createWorker(workerId) - workers.set(workerId, worker) + const worker = workers.get(workerId) ?? createWorker(workerId); + workers.set(workerId, worker); worker.postMessage({ type: 'IdentifyShard', shardId, - } satisfies WorkerMessage) + } satisfies WorkerMessage); - const { promise, resolve } = promiseWithResolvers() + const { promise, resolve } = promiseWithResolvers(); const waitForShardIdentified = (message: ManagerMessage) => { if (message.type === 'ShardIdentified' && message.shardId === shardId) { - resolve() + resolve(); } - } + }; - worker.on('message', waitForShardIdentified) + worker.on('message', waitForShardIdentified); - await promise + await promise; - worker.off('message', waitForShardIdentified) -} + worker.off('message', waitForShardIdentified); +}; gatewayManager.sendPayload = async (shardId, payload) => { - const workerId = gatewayManager.calculateWorkerId(shardId) - const worker = workers.get(workerId) + const workerId = gatewayManager.calculateWorkerId(shardId); + const worker = workers.get(workerId); - if (!worker) return + if (!worker) return; worker.postMessage({ type: 'ShardPayload', shardId, payload, - } satisfies WorkerMessage) -} + } satisfies WorkerMessage); +}; gatewayManager.editBotStatus = async (payload) => { - const workersArray = Array.from(workers.values()) + const workersArray = Array.from(workers.values()); for (const worker of workersArray) { worker.postMessage({ type: 'EditShardsPresence', payload, - } satisfies WorkerMessage) + } satisfies WorkerMessage); } -} +}; -export default gatewayManager +export default gatewayManager; diff --git a/examples/bigbot/src/gateway/index.ts b/examples/bigbot/src/gateway/index.ts index d81def825..fb4feb141 100644 --- a/examples/bigbot/src/gateway/index.ts +++ b/examples/bigbot/src/gateway/index.ts @@ -1,72 +1,72 @@ -import { GATEWAY_HOST, GATEWAY_PORT } from '../config.js' -import { promiseWithResolvers } from '../util.js' -import { buildFastifyApp } from './fastify.js' -import gatewayManager, { logger, workers } from './gatewayManager.js' -import { shardInfoRequests } from './worker/createWorker.js' -import type { ManagerGetShardInfoFromGuildId, ShardInfo, WorkerMessage, WorkerPresencesUpdate, WorkerShardPayload } from './worker/types.js' +import { GATEWAY_HOST, GATEWAY_PORT } from '../config.js'; +import { promiseWithResolvers } from '../util.js'; +import { buildFastifyApp } from './fastify.js'; +import gatewayManager, { logger, workers } from './gatewayManager.js'; +import { shardInfoRequests } from './worker/createWorker.js'; +import type { ManagerGetShardInfoFromGuildId, ShardInfo, WorkerMessage, WorkerPresencesUpdate, WorkerShardPayload } from './worker/types.js'; -const app = buildFastifyApp() +const app = buildFastifyApp(); app.get('/timecheck', (_req, res) => { - res.status(200).send({ message: Date.now() }) -}) + res.status(200).send({ message: Date.now() }); +}); app.post('/', async (req, res) => { if (!req.body) { - res.status(400).send({ message: 'Invalid body' }) - return + res.status(400).send({ message: 'Invalid body' }); + return; } - const data = req.body as WorkerShardPayload | WorkerPresencesUpdate | ManagerGetShardInfoFromGuildId + const data = req.body as WorkerShardPayload | WorkerPresencesUpdate | ManagerGetShardInfoFromGuildId; if (data.type === 'ShardPayload') { - await gatewayManager.sendPayload(data.shardId, data.payload) - return + await gatewayManager.sendPayload(data.shardId, data.payload); + return; } if (data.type === 'EditShardsPresence') { - await gatewayManager.editBotStatus(data.payload) - return + await gatewayManager.editBotStatus(data.payload); + return; } if (data.type === 'ShardInfoFromGuild') { // If we don't have a guildId, we use shard 0 - const shardId = data.guildId ? gatewayManager.calculateShardId(data.guildId) : 0 - const workerId = gatewayManager.calculateWorkerId(shardId) - const worker = workers.get(workerId) + const shardId = data.guildId ? gatewayManager.calculateShardId(data.guildId) : 0; + const workerId = gatewayManager.calculateWorkerId(shardId); + const worker = workers.get(workerId); if (!worker) { - await res.status(400).send({ error: `worker for shard ${shardId} not found` }) - return + await res.status(400).send({ error: `worker for shard ${shardId} not found` }); + return; } - const nonce = crypto.randomUUID() + const nonce = crypto.randomUUID(); - const { promise, resolve } = promiseWithResolvers() + const { promise, resolve } = promiseWithResolvers(); - shardInfoRequests.set(nonce, resolve) + shardInfoRequests.set(nonce, resolve); worker.postMessage({ type: 'GetShardInfo', shardId, nonce, - } satisfies WorkerMessage) + } satisfies WorkerMessage); - const shardInfo = await promise + const shardInfo = await promise; await res.status(200).send({ shardId: shardInfo.shardId, rtt: shardInfo.rtt, - } satisfies Omit) - return + } satisfies Omit); + return; } - logger.warn(`Manager - Received unknown data type: ${(data as { type: string }).type}`) -}) + logger.warn(`Manager - Received unknown data type: ${(data as { type: string }).type}`); +}); await app.listen({ host: GATEWAY_HOST, port: GATEWAY_PORT, -}) +}); -logger.info(`Gateway manager listening on port ${GATEWAY_PORT}`) +logger.info(`Gateway manager listening on port ${GATEWAY_PORT}`); -await gatewayManager.spawnShards() +await gatewayManager.spawnShards(); diff --git a/examples/bigbot/src/gateway/worker/createWorker.ts b/examples/bigbot/src/gateway/worker/createWorker.ts index 28055914b..5ac012051 100644 --- a/examples/bigbot/src/gateway/worker/createWorker.ts +++ b/examples/bigbot/src/gateway/worker/createWorker.ts @@ -1,5 +1,5 @@ -import { join as joinPath } from 'node:path' -import { Worker } from 'node:worker_threads' +import { join as joinPath } from 'node:path'; +import { Worker } from 'node:worker_threads'; import { DISCORD_TOKEN, EVENT_HANDLER_AUTHORIZATION, @@ -9,18 +9,18 @@ import { MESSAGEQUEUE_PASSWORD, MESSAGEQUEUE_URL, MESSAGEQUEUE_USERNAME, -} from '../../config.js' -import { getDirnameFromFileUrl } from '../../util.js' -import gatewayManager, { logger } from '../gatewayManager.js' -import type { ManagerMessage, ShardInfo, WorkerCreateData, WorkerMessage } from './types.js' +} from '../../config.js'; +import { getDirnameFromFileUrl } from '../../util.js'; +import gatewayManager, { logger } from '../gatewayManager.js'; +import type { ManagerMessage, ShardInfo, WorkerCreateData, WorkerMessage } from './types.js'; // the string is the nonce of the request -export const shardInfoRequests = new Map void>() +export const shardInfoRequests = new Map void>(); export function createWorker(workerId: number): Worker { // the Worker constructor requires either a relative path compared to the process CWD or an absolute one, so to get one relative we need to use import.meta.url - const currentFolder = getDirnameFromFileUrl(import.meta.url) - const workerFilePath = joinPath(currentFolder, './worker.js') + const currentFolder = getDirnameFromFileUrl(import.meta.url); + const workerFilePath = joinPath(currentFolder, './worker.js'); const worker = new Worker(workerFilePath, { workerData: { @@ -43,32 +43,32 @@ export function createWorker(workerId: number): Worker { url: MESSAGEQUEUE_URL, }, } satisfies WorkerCreateData, - }) + }); worker.on('message', async (message: ManagerMessage) => { if (message.type === 'RequestIdentify') { - logger.info(`Requesting identify for shardId: #${message.shardId}`) - await gatewayManager.requestIdentify(message.shardId) + logger.info(`Requesting identify for shardId: #${message.shardId}`); + await gatewayManager.requestIdentify(message.shardId); worker.postMessage({ type: 'AllowIdentify', shardId: message.shardId, - } satisfies WorkerMessage) + } satisfies WorkerMessage); - return + return; } if (message.type === 'ShardInfo') { - shardInfoRequests.get(message.nonce)?.(message) - shardInfoRequests.delete(message.nonce) - return + shardInfoRequests.get(message.nonce)?.(message); + shardInfoRequests.delete(message.nonce); + return; } if (message.type === 'ShardIdentified') { - logger.info(`Shard #${message.shardId} identified`) - return + logger.info(`Shard #${message.shardId} identified`); + return; } - logger.warn(`Worker - Received unknown message type: ${(message as { type: string }).type}`) - }) + logger.warn(`Worker - Received unknown message type: ${(message as { type: string }).type}`); + }); - return worker + return worker; } diff --git a/examples/bigbot/src/gateway/worker/types.ts b/examples/bigbot/src/gateway/worker/types.ts index fa9c46141..7fdb532ef 100644 --- a/examples/bigbot/src/gateway/worker/types.ts +++ b/examples/bigbot/src/gateway/worker/types.ts @@ -1,6 +1,6 @@ -import type { DiscordUpdatePresence, ShardSocketRequest } from '@discordeno/bot' +import type { DiscordUpdatePresence, ShardSocketRequest } from '@discordeno/bot'; -export type ManagerMessage = ManagerRequestIdentify | ManagerShardIdentified | ManagerShardPrepared | ManagerShardInfo +export type ManagerMessage = ManagerRequestIdentify | ManagerShardIdentified | ManagerShardPrepared | ManagerShardInfo; export type WorkerMessage = | WorkerIdentifyShard | WorkerPrepareShard @@ -8,93 +8,93 @@ export type WorkerMessage = | WorkerAllowIdentify | WorkerShardPayload | WorkerPresencesUpdate - | WorkerShardInfo + | WorkerShardInfo; export interface WorkerIdentifyShard { - type: 'IdentifyShard' - shardId: number + type: 'IdentifyShard'; + shardId: number; } export interface WorkerPrepareShard { - type: 'PrepareShard' - shardId: number - totalShards: number + type: 'PrepareShard'; + shardId: number; + totalShards: number; } export interface WorkerSwitchShards { - type: 'SwitchShards' + type: 'SwitchShards'; } export interface WorkerAllowIdentify { - type: 'AllowIdentify' - shardId: number + type: 'AllowIdentify'; + shardId: number; } export interface ManagerRequestIdentify { - type: 'RequestIdentify' - shardId: number + type: 'RequestIdentify'; + shardId: number; } export interface WorkerShardPayload { - type: 'ShardPayload' - shardId: number - payload: ShardSocketRequest + type: 'ShardPayload'; + shardId: number; + payload: ShardSocketRequest; } export interface WorkerPresencesUpdate { - type: 'EditShardsPresence' - payload: DiscordUpdatePresence + type: 'EditShardsPresence'; + payload: DiscordUpdatePresence; } export interface WorkerShardInfo { - type: 'GetShardInfo' - shardId: number - nonce: string + type: 'GetShardInfo'; + shardId: number; + nonce: string; } export interface WorkerCreateData { connectionData: { - intents: number - token: string - url: string - version: number - totalShards: number - } + intents: number; + token: string; + url: string; + version: number; + totalShards: number; + }; eventHandler: { - urls: string[] - authentication: string - } - workerId: number + urls: string[]; + authentication: string; + }; + workerId: number; messageQueue: { - enabled: boolean - username?: string - password?: string - url?: string - } + enabled: boolean; + username?: string; + password?: string; + url?: string; + }; } export interface ShardInfo { - shardId: number - rtt: number + shardId: number; + rtt: number; // the nonce is to bind to the request - nonce: string + nonce: string; } export interface ManagerShardInfo extends ShardInfo { - type: 'ShardInfo' + type: 'ShardInfo'; } export interface ManagerGetShardInfoFromGuildId { - type: 'ShardInfoFromGuild' - guildId: string | undefined + type: 'ShardInfoFromGuild'; + guildId: string | undefined; } export interface ManagerShardIdentified { - type: 'ShardIdentified' - shardId: number + type: 'ShardIdentified'; + shardId: number; } export interface ManagerShardPrepared { - type: 'ShardPrepared' - shardId: number + type: 'ShardPrepared'; + shardId: number; } diff --git a/examples/bigbot/src/gateway/worker/worker.ts b/examples/bigbot/src/gateway/worker/worker.ts index 43f85e312..ee6ea5818 100644 --- a/examples/bigbot/src/gateway/worker/worker.ts +++ b/examples/bigbot/src/gateway/worker/worker.ts @@ -1,125 +1,125 @@ -import assert from 'node:assert' -import { createHash } from 'node:crypto' -import { workerData as _workerData, parentPort } from 'node:worker_threads' -import { type Camelize, createLogger, DiscordenoShard, type DiscordGatewayPayload, GatewayOpcodes, ShardSocketCloseCodes } from '@discordeno/bot' -import { type Channel as amqpChannel, connect as connectAmqp } from 'amqplib' -import { promiseWithResolvers } from '../../util.js' -import type { ManagerMessage, WorkerCreateData, WorkerMessage } from './types.js' +import assert from 'node:assert'; +import { createHash } from 'node:crypto'; +import { workerData as _workerData, parentPort } from 'node:worker_threads'; +import { type Camelize, createLogger, DiscordenoShard, type DiscordGatewayPayload, GatewayOpcodes, ShardSocketCloseCodes } from '@discordeno/bot'; +import { type Channel as amqpChannel, connect as connectAmqp } from 'amqplib'; +import { promiseWithResolvers } from '../../util.js'; +import type { ManagerMessage, WorkerCreateData, WorkerMessage } from './types.js'; -assert(parentPort) +assert(parentPort); -const workerData: WorkerCreateData = _workerData +const workerData: WorkerCreateData = _workerData; -const logger = createLogger({ name: `Worker #${workerData.workerId}` }) +const logger = createLogger({ name: `Worker #${workerData.workerId}` }); -const identifyPromises = new Map void>() -const shards = new Map() -const pendingShards = new Map() +const identifyPromises = new Map void>(); +const shards = new Map(); +const pendingShards = new Map(); -let totalShards = workerData.connectionData.totalShards +let totalShards = workerData.connectionData.totalShards; -let rabbitMQChannel: amqpChannel | undefined +let rabbitMQChannel: amqpChannel | undefined; if (workerData.messageQueue.enabled) { - await connectToRabbitMQ() + await connectToRabbitMQ(); } parentPort.on('message', async (message: WorkerMessage) => { - assert(parentPort) + assert(parentPort); if (message.type === 'IdentifyShard') { - logger.info(`Starting to identify shard #${message.shardId}`) - const shard = shards.get(message.shardId) ?? createShard(message.shardId) - shards.set(message.shardId, shard) + logger.info(`Starting to identify shard #${message.shardId}`); + const shard = shards.get(message.shardId) ?? createShard(message.shardId); + shards.set(message.shardId, shard); - await shard.identify() + await shard.identify(); parentPort.postMessage({ type: 'ShardIdentified', shardId: message.shardId, - } satisfies ManagerMessage) + } satisfies ManagerMessage); - return + return; } if (message.type === 'PrepareShard') { - logger.info(`Preparing shard #${message.shardId}`) - totalShards = message.totalShards - let shard = pendingShards.get(message.shardId) + logger.info(`Preparing shard #${message.shardId}`); + totalShards = message.totalShards; + let shard = pendingShards.get(message.shardId); if (!shard) { - shard = createShard(message.shardId) - pendingShards.set(message.shardId, shard) + shard = createShard(message.shardId); + pendingShards.set(message.shardId, shard); } // Ignore the events // TODO: If you need 'gateway.resharding.updateGuildsShardId' it you can listen to only the ready event and use the data from that event for the function call - shard.events.message = () => {} + shard.events.message = () => {}; - await shard.identify() + await shard.identify(); parentPort.postMessage({ type: 'ShardPrepared', shardId: message.shardId, - } satisfies ManagerMessage) + } satisfies ManagerMessage); - return + return; } if (message.type === 'SwitchShards') { - logger.info('Switching shards') + logger.info('Switching shards'); // Change the message event for all shards for (const shard of pendingShards.values()) { - shard.events.message = handleShardMessageEvent + shard.events.message = handleShardMessageEvent; } // Old shards stop processing events for (const shard of shards.values()) { - const oldHandler = shard.events.message + const oldHandler = shard.events.message; shard.events.message = async function (_, message) { // Member checks need to continue but others can stop if (message.t === 'GUILD_MEMBERS_CHUNK') { - oldHandler?.(shard, message) + oldHandler?.(shard, message); } - } + }; } // Shutdown the old shards - const shardsToShutdown = Array.from(shards.values()) + const shardsToShutdown = Array.from(shards.values()); // Move the pending shards to the active shards - shards.clear() + shards.clear(); for (const [shardId, shard] of pendingShards.entries()) { - shards.set(shardId, shard) - pendingShards.delete(shardId) + shards.set(shardId, shard); + pendingShards.delete(shardId); } // Shutdown the old shards const promises = shardsToShutdown.map(async (shard) => { - await shard.close(ShardSocketCloseCodes.Resharded, 'Shard is being resharded') - logger.info(`Shard #${shard.id} has been shutdown`) - }) + await shard.close(ShardSocketCloseCodes.Resharded, 'Shard is being resharded'); + logger.info(`Shard #${shard.id} has been shutdown`); + }); - await Promise.all(promises) + await Promise.all(promises); - return + return; } if (message.type === 'AllowIdentify') { - identifyPromises.get(message.shardId)?.() - identifyPromises.delete(message.shardId) + identifyPromises.get(message.shardId)?.(); + identifyPromises.delete(message.shardId); - return + return; } if (message.type === 'ShardPayload') { - const shard = shards.get(message.shardId) + const shard = shards.get(message.shardId); - if (!shard) return + if (!shard) return; - await shard.send(message.payload) + await shard.send(message.payload); - return + return; } if (message.type === 'EditShardsPresence') { - const shardsArray = Array.from(shards.values()) + const shardsArray = Array.from(shards.values()); const promises = shardsArray.map(async (shard) => { await shard.send({ op: GatewayOpcodes.PresenceUpdate, @@ -129,11 +129,11 @@ parentPort.on('message', async (message: WorkerMessage) => { activities: message.payload.activities, status: message.payload.status, }, - }) - }) + }); + }); - await Promise.all(promises) - return + await Promise.all(promises); + return; } if (message.type === 'GetShardInfo') { const status = { @@ -141,15 +141,15 @@ parentPort.on('message', async (message: WorkerMessage) => { shardId: message.shardId, rtt: shards.get(message.shardId)?.heart.rtt ?? -1, nonce: message.nonce, - } satisfies ManagerMessage + } satisfies ManagerMessage; - parentPort?.postMessage(status) + parentPort?.postMessage(status); - return + return; } - logger.warn(`Received unknown message type: ${(message as { type: string }).type}`) -}) + logger.warn(`Received unknown message type: ${(message as { type: string }).type}`); +}); function createShard(shardId: number): DiscordenoShard { const shard = new DiscordenoShard({ @@ -169,62 +169,62 @@ function createShard(shardId: number): DiscordenoShard { version: workerData.connectionData.version, transportCompression: null, }, - }) + }); shard.requestIdentify = async () => { - assert(parentPort) + assert(parentPort); - const { promise, resolve } = promiseWithResolvers() + const { promise, resolve } = promiseWithResolvers(); parentPort.postMessage({ type: 'RequestIdentify', shardId, - } satisfies ManagerMessage) + } satisfies ManagerMessage); - identifyPromises.set(shardId, resolve) + identifyPromises.set(shardId, resolve); - return await promise - } + return await promise; + }; // We do not want to camelize the packet, so we need to override the function as the default behavior is to camelize shard.forwardToBot = (packet) => { - shard.events.message?.(shard, packet) - } + shard.events.message?.(shard, packet); + }; - shard.events.message = handleShardMessageEvent + shard.events.message = handleShardMessageEvent; - return shard + return shard; } async function handleShardMessageEvent(shard: DiscordenoShard, payload: Camelize) { - const body = JSON.stringify({ payload, shardId: shard.id }) + const body = JSON.stringify({ payload, shardId: shard.id }); if (workerData.messageQueue.enabled) { if (!rabbitMQChannel) { - logger.error('The RabbitMQ channel has not been created. The event will be lost') - return + logger.error('The RabbitMQ channel has not been created. The event will be lost'); + return; } - const message = Buffer.from(body) - const discordData = JSON.stringify(payload.d) + const message = Buffer.from(body); + const discordData = JSON.stringify(payload.d); - const deduplicationHash = createHash('sha1') - deduplicationHash.update(discordData) + const deduplicationHash = createHash('sha1'); + deduplicationHash.update(discordData); rabbitMQChannel.publish('gatewayMessage', '', message, { contentType: 'application/json', headers: { 'x-deduplication-header': deduplicationHash.digest('hex'), }, - }) + }); - return + return; } - const url = workerData.eventHandler.urls[shard.id % workerData.eventHandler.urls.length] + const url = workerData.eventHandler.urls[shard.id % workerData.eventHandler.urls.length]; if (!url) { - logger.error('No url found to send events to') - return + logger.error('No url found to send events to'); + return; } await fetch(url, { @@ -234,35 +234,35 @@ async function handleShardMessageEvent(shard: DiscordenoShard, payload: Camelize 'Content-Type': 'application/json', Authorization: workerData.eventHandler.authentication, }, - }).catch((error) => logger.error('Failed to send events to the bot code', error)) + }).catch((error) => logger.error('Failed to send events to the bot code', error)); } async function connectToRabbitMQ(): Promise { - rabbitMQChannel = undefined - const messageQueue = workerData.messageQueue + rabbitMQChannel = undefined; + const messageQueue = workerData.messageQueue; const connection = await connectAmqp(`amqp://${messageQueue.username}:${messageQueue.password}@${messageQueue.url}`).catch((error) => { - logger.error('Failed to connect to RabbitMQ, retrying in 1s.', error) - setTimeout(connectToRabbitMQ, 1000) - }) + logger.error('Failed to connect to RabbitMQ, retrying in 1s.', error); + setTimeout(connectToRabbitMQ, 1000); + }); - if (!connection) return + if (!connection) return; connection.on('close', () => { - rabbitMQChannel = undefined - setTimeout(connectToRabbitMQ, 1000) - }) + rabbitMQChannel = undefined; + setTimeout(connectToRabbitMQ, 1000); + }); connection.on('error', (error) => { - rabbitMQChannel = undefined - logger.error('There was an error in the connection with RabbitMQ, reconnecting in 1s.', error) - setTimeout(connectToRabbitMQ, 1000) - }) + rabbitMQChannel = undefined; + logger.error('There was an error in the connection with RabbitMQ, reconnecting in 1s.', error); + setTimeout(connectToRabbitMQ, 1000); + }); const channel = await connection.createChannel().catch((error) => { - logger.error('There was an error creating the RabbitMQ channel', error) - }) + logger.error('There was an error creating the RabbitMQ channel', error); + }); - if (!channel) return + if (!channel) return; const exchange = await channel .assertExchange('gatewayMessage', 'x-message-deduplication', { @@ -273,10 +273,10 @@ async function connectToRabbitMQ(): Promise { }, }) .catch((error) => { - logger.error('There was an error asserting the exchange', error) - }) + logger.error('There was an error asserting the exchange', error); + }); - if (!exchange) return + if (!exchange) return; - rabbitMQChannel = channel + rabbitMQChannel = channel; } diff --git a/examples/bigbot/src/rest/fastify.ts b/examples/bigbot/src/rest/fastify.ts index b377ddd20..02a9c1fe1 100644 --- a/examples/bigbot/src/rest/fastify.ts +++ b/examples/bigbot/src/rest/fastify.ts @@ -1,39 +1,39 @@ -import fastifyMultipart, { type MultipartFile, type MultipartValue } from '@fastify/multipart' -import fastify, { type FastifyInstance } from 'fastify' -import { REST_AUTHORIZATION } from '../config.js' +import fastifyMultipart, { type MultipartFile, type MultipartValue } from '@fastify/multipart'; +import fastify, { type FastifyInstance } from 'fastify'; +import { REST_AUTHORIZATION } from '../config.js'; export function buildFastifyApp(): FastifyInstance { - const app = fastify() + const app = fastify(); - app.register(fastifyMultipart, { attachFieldsToBody: true }) + app.register(fastifyMultipart, { attachFieldsToBody: true }); // Authorization check app.addHook('onRequest', async (req, res) => { if (req.headers.authorization !== REST_AUTHORIZATION) { res.status(401).send({ message: 'Credentials not valid.', - }) + }); } - }) + }); - return app + return app; } export async function parseMultiformBody(body: unknown): Promise { - const form = new FormData() + const form = new FormData(); - if (typeof body !== 'object' || !body) return form + if (typeof body !== 'object' || !body) return form; for (const objectValue of Object.values(body)) { - const value = objectValue as MultipartFile | MultipartValue + const value = objectValue as MultipartFile | MultipartValue; if (value.type === 'file') { - form.append(value.fieldname, new Blob([await value.toBuffer()]), value.filename) + form.append(value.fieldname, new Blob([await value.toBuffer()]), value.filename); } if (value.type === 'field' && typeof value.value === 'string') { - form.append(value.fieldname, value.value) + form.append(value.fieldname, value.value); } } - return form + return form; } diff --git a/examples/bigbot/src/rest/index.ts b/examples/bigbot/src/rest/index.ts index 50696f958..a58a74d4d 100644 --- a/examples/bigbot/src/rest/index.ts +++ b/examples/bigbot/src/rest/index.ts @@ -1,48 +1,48 @@ -import type { RequestMethods } from '@discordeno/bot' -import { REST_HOST, REST_PORT } from '../config.js' -import { buildFastifyApp, parseMultiformBody } from './fastify.js' -import restManager, { logger } from './restManager.js' +import type { RequestMethods } from '@discordeno/bot'; +import { REST_HOST, REST_PORT } from '../config.js'; +import { buildFastifyApp, parseMultiformBody } from './fastify.js'; +import restManager, { logger } from './restManager.js'; -const app = buildFastifyApp() +const app = buildFastifyApp(); app.get('/timecheck', async (_req, res) => { - res.status(200).send({ message: Date.now() }) -}) + res.status(200).send({ message: Date.now() }); +}); app.all('/*', async (req, res) => { - let url = req.originalUrl + let url = req.originalUrl; if (url.startsWith('/v')) { - url = url.slice(url.indexOf('/', 2)) + url = url.slice(url.indexOf('/', 2)); } - const isMultipart = req.headers['content-type']?.startsWith('multipart/form-data') - const hasBody = req.method !== 'GET' && req.method !== 'DELETE' - const body = hasBody ? (isMultipart ? await parseMultiformBody(req.body) : req.body) : undefined + const isMultipart = req.headers['content-type']?.startsWith('multipart/form-data'); + const hasBody = req.method !== 'GET' && req.method !== 'DELETE'; + const body = hasBody ? (isMultipart ? await parseMultiformBody(req.body) : req.body) : undefined; try { const result = await restManager.makeRequest(req.method as RequestMethods, url, { body, - }) + }); if (result) { - res.status(200).send(result) - return + res.status(200).send(result); + return; } - res.status(204).send({}) + res.status(204).send({}); } catch (error) { - logger.error(error) + logger.error(error); res.status(500).send({ message: error, - }) + }); } -}) +}); await app.listen({ host: REST_HOST, port: REST_PORT, -}) +}); -logger.info(`REST Proxy listening on port ${REST_PORT}`) +logger.info(`REST Proxy listening on port ${REST_PORT}`); diff --git a/examples/bigbot/src/rest/influx.ts b/examples/bigbot/src/rest/influx.ts index 475e70020..c2f0f7ea1 100644 --- a/examples/bigbot/src/rest/influx.ts +++ b/examples/bigbot/src/rest/influx.ts @@ -1,15 +1,15 @@ -import type { RestManager } from '@discordeno/bot' -import { InfluxDB, Point } from '@influxdata/influxdb-client' -import { INFLUX_BUCKET, INFLUX_ENABLED, INFLUX_ORG, INFLUX_TOKEN, INFLUX_URL } from '../config.js' +import type { RestManager } from '@discordeno/bot'; +import { InfluxDB, Point } from '@influxdata/influxdb-client'; +import { INFLUX_BUCKET, INFLUX_ENABLED, INFLUX_ORG, INFLUX_TOKEN, INFLUX_URL } from '../config.js'; -export const influxDB = INFLUX_ENABLED ? new InfluxDB({ url: INFLUX_URL!, token: INFLUX_TOKEN! }) : undefined -export const influx = INFLUX_ENABLED && influxDB ? influxDB.getWriteApi(INFLUX_ORG!, INFLUX_BUCKET!) : undefined +export const influxDB = INFLUX_ENABLED ? new InfluxDB({ url: INFLUX_URL!, token: INFLUX_TOKEN! }) : undefined; +export const influx = INFLUX_ENABLED && influxDB ? influxDB.getWriteApi(INFLUX_ORG!, INFLUX_BUCKET!) : undefined; export const setupRestAnalyticsHooks = (rest: RestManager, logger: RestManager['logger']): void => { // If influxdb data is provided, enable analytics in this proxy. - if (!influx) return + if (!influx) return; - const originalSendRequest = rest.sendRequest + const originalSendRequest = rest.sendRequest; rest.sendRequest = async (options) => { const fetchingPoint = new Point('restEvents') @@ -17,31 +17,31 @@ export const setupRestAnalyticsHooks = (rest: RestManager, logger: RestManager[' .stringField('type', 'REQUEST_FETCHING') .tag('method', options.method) .tag('route', options.route) - .tag('bucket', options.bucketId ?? 'NA') + .tag('bucket', options.bucketId ?? 'NA'); - influx.writePoint(fetchingPoint) + influx.writePoint(fetchingPoint); - await originalSendRequest(options) + await originalSendRequest(options); const fetchedPoint = new Point('restEvents') .timestamp(new Date()) .stringField('type', 'REQUEST_FETCHED') .tag('method', options.method) .tag('route', options.route) - .tag('bucket', options.bucketId ?? 'NA') + .tag('bucket', options.bucketId ?? 'NA'); // FIXME: rest.sendRequest returns Promise, so there is no way currently to get the response status // .intField('status', response.status) - influx.writePoint(fetchedPoint) - } + influx.writePoint(fetchedPoint); + }; setInterval(async () => { - logger.info('Influx - Saving events...') + logger.info('Influx - Saving events...'); try { - await influx.flush() - logger.info('Influx - events saved!') + await influx.flush(); + logger.info('Influx - events saved!'); } catch (error) { - logger.error('Influx - error saving events!', error) + logger.error('Influx - error saving events!', error); } - }, 30_000 /* 30s */) -} + }, 30_000 /* 30s */); +}; diff --git a/examples/bigbot/src/rest/restManager.ts b/examples/bigbot/src/rest/restManager.ts index 625243a08..1e31f50d4 100644 --- a/examples/bigbot/src/rest/restManager.ts +++ b/examples/bigbot/src/rest/restManager.ts @@ -1,13 +1,13 @@ -import { createLogger, createRestManager } from '@discordeno/bot' -import { DISCORD_TOKEN } from '../config.js' -import { setupRestAnalyticsHooks } from './influx.js' +import { createLogger, createRestManager } from '@discordeno/bot'; +import { DISCORD_TOKEN } from '../config.js'; +import { setupRestAnalyticsHooks } from './influx.js'; const manager = createRestManager({ token: DISCORD_TOKEN, -}) +}); -export const logger = createLogger({ name: 'REST' }) +export const logger = createLogger({ name: 'REST' }); -setupRestAnalyticsHooks(manager, logger) +setupRestAnalyticsHooks(manager, logger); -export default manager +export default manager; diff --git a/examples/bigbot/src/util.ts b/examples/bigbot/src/util.ts index 51130370e..1f3ff6b73 100644 --- a/examples/bigbot/src/util.ts +++ b/examples/bigbot/src/util.ts @@ -1,25 +1,25 @@ -import { dirname } from 'node:path' -import { fileURLToPath } from 'node:url' +import { dirname } from 'node:path'; +import { fileURLToPath } from 'node:url'; // This is a "polyfill" for the `Promise.withResolves`, while node 22 does support it, node 18 does not and this template does support node 18 export function promiseWithResolvers(): PromiseWithResolvers { - let resolve!: (data: T | PromiseLike) => void - let reject!: (reason?: any) => void + let resolve!: (data: T | PromiseLike) => void; + let reject!: (reason?: any) => void; const promise = new Promise((_resolve, _reject) => { - resolve = _resolve - reject = _reject - }) + resolve = _resolve; + reject = _reject; + }); - return { promise, resolve, reject } + return { promise, resolve, reject }; } // This re-creates the `__dirname` that exists in CommonJS, in ESM node added `import.meta.dirname` but it is for node 20+, so we need this util to support node 18 export function getDirnameFromFileUrl(url: string): string { - return dirname(fileURLToPath(url)) + return dirname(fileURLToPath(url)); } export interface PromiseWithResolvers { - promise: Promise - resolve: (data: T | PromiseLike) => void - reject: (reason?: any) => void + promise: Promise; + resolve: (data: T | PromiseLike) => void; + reject: (reason?: any) => void; } diff --git a/examples/minimal/src/bot.ts b/examples/minimal/src/bot.ts index e6bda765f..218c80da5 100644 --- a/examples/minimal/src/bot.ts +++ b/examples/minimal/src/bot.ts @@ -1,6 +1,6 @@ -import { Collection, createBot, Intents } from '@discordeno/bot' -import { configs } from './config.js' -import type { Command } from './types/commands.js' +import { Collection, createBot, Intents } from '@discordeno/bot'; +import { configs } from './config.js'; +import type { Command } from './types/commands.js'; const rawBot = createBot({ token: configs.token, @@ -13,11 +13,11 @@ const rawBot = createBot({ token: true, }, }, -}) +}); -export const bot = rawBot as BotWithCommands +export const bot = rawBot as BotWithCommands; // Create the command collection -bot.commands = new Collection() +bot.commands = new Collection(); -export type BotWithCommands = typeof rawBot & { commands: Collection } +export type BotWithCommands = typeof rawBot & { commands: Collection }; diff --git a/examples/minimal/src/commands.ts b/examples/minimal/src/commands.ts index 490f3a81e..b3c19b99e 100644 --- a/examples/minimal/src/commands.ts +++ b/examples/minimal/src/commands.ts @@ -1,6 +1,6 @@ -import { bot } from './bot.js' -import type { Command } from './types/commands.js' +import { bot } from './bot.js'; +import type { Command } from './types/commands.js'; export function createCommand(command: Command): void { - bot.commands.set(command.name, command) + bot.commands.set(command.name, command); } diff --git a/examples/minimal/src/commands/ping.ts b/examples/minimal/src/commands/ping.ts index b293cdfe0..84384d4fa 100644 --- a/examples/minimal/src/commands/ping.ts +++ b/examples/minimal/src/commands/ping.ts @@ -1,13 +1,13 @@ -import { ApplicationCommandTypes, snowflakeToTimestamp } from '@discordeno/bot' -import { createCommand } from '../commands.js' +import { ApplicationCommandTypes, snowflakeToTimestamp } from '@discordeno/bot'; +import { createCommand } from '../commands.js'; createCommand({ name: 'ping', description: 'Ping the Bot!', type: ApplicationCommandTypes.ChatInput, async execute(interaction) { - const ping = Date.now() - snowflakeToTimestamp(interaction.id) + const ping = Date.now() - snowflakeToTimestamp(interaction.id); - await interaction.respond(`🏓 Pong! ${ping}ms`) + await interaction.respond(`🏓 Pong! ${ping}ms`); }, -}) +}); diff --git a/examples/minimal/src/config.ts b/examples/minimal/src/config.ts index 32b9c49c2..7c2d2b55c 100644 --- a/examples/minimal/src/config.ts +++ b/examples/minimal/src/config.ts @@ -1,17 +1,17 @@ -const token = process.env.BOT_TOKEN -const devGuildId = process.env.DEV_GUILD_ID +const token = process.env.BOT_TOKEN; +const devGuildId = process.env.DEV_GUILD_ID; -if (!token) throw new Error('Missing BOT_TOKEN environment variable') -if (!devGuildId) throw new Error('Missing DEV_GUILD_ID environment variable') +if (!token) throw new Error('Missing BOT_TOKEN environment variable'); +if (!devGuildId) throw new Error('Missing DEV_GUILD_ID environment variable'); export const configs: Config = { /** Get token from ENV variable */ token, /** The server id where you develop your bot and want dev commands created. */ devGuildId: BigInt(devGuildId), -} +}; export interface Config { - token: string - devGuildId: bigint + token: string; + devGuildId: bigint; } diff --git a/examples/minimal/src/events/interactionCreate.ts b/examples/minimal/src/events/interactionCreate.ts index bed68eda8..b17516b38 100644 --- a/examples/minimal/src/events/interactionCreate.ts +++ b/examples/minimal/src/events/interactionCreate.ts @@ -1,15 +1,15 @@ -import { InteractionTypes } from '@discordeno/bot' -import { bot } from '../bot.js' -import logger from '../utils/logger.js' +import { InteractionTypes } from '@discordeno/bot'; +import { bot } from '../bot.js'; +import logger from '../utils/logger.js'; bot.events.interactionCreate = (interaction) => { - if (!interaction.data) return + if (!interaction.data) return; switch (interaction.type) { case InteractionTypes.ApplicationCommand: - logger.info(`[Application Command] ${interaction.data.name} command executed.`) + logger.info(`[Application Command] ${interaction.data.name} command executed.`); - bot.commands.get(interaction.data.name)?.execute(interaction) - break + bot.commands.get(interaction.data.name)?.execute(interaction); + break; } -} +}; diff --git a/examples/minimal/src/events/ready.ts b/examples/minimal/src/events/ready.ts index f6f7c3271..664fc9728 100644 --- a/examples/minimal/src/events/ready.ts +++ b/examples/minimal/src/events/ready.ts @@ -1,17 +1,17 @@ -import { bot } from '../bot.js' -import logger from '../utils/logger.js' +import { bot } from '../bot.js'; +import logger from '../utils/logger.js'; bot.events.ready = ({ shardId }) => { - logger.info(`[READY] Shard ${shardId} is ready!`) + logger.info(`[READY] Shard ${shardId} is ready!`); if (shardId === bot.gateway.lastShardId) { - botFullyReady() + botFullyReady(); } -} +}; // This function lets you run custom code when all your bot's shards are online. function botFullyReady(): void { // Do stuff that you want that get execute only when the bot is fully online. - logger.info('[READY] Bot is fully online.') + logger.info('[READY] Bot is fully online.'); } diff --git a/examples/minimal/src/index.ts b/examples/minimal/src/index.ts index b0f5f89cf..30a137aec 100644 --- a/examples/minimal/src/index.ts +++ b/examples/minimal/src/index.ts @@ -1,15 +1,15 @@ -import 'dotenv/config' +import 'dotenv/config'; -import { bot } from './bot.js' -import importDirectory from './utils/loader.js' -import logger from './utils/logger.js' +import { bot } from './bot.js'; +import importDirectory from './utils/loader.js'; +import logger from './utils/logger.js'; -logger.info('Starting bot...') +logger.info('Starting bot...'); -logger.info('Loading commands...') -await importDirectory('./dist/commands') +logger.info('Loading commands...'); +await importDirectory('./dist/commands'); -logger.info('Loading events...') -await importDirectory('./dist/events') +logger.info('Loading events...'); +await importDirectory('./dist/events'); -await bot.start() +await bot.start(); diff --git a/examples/minimal/src/register-commands.ts b/examples/minimal/src/register-commands.ts index d2e9a9474..d464511d5 100644 --- a/examples/minimal/src/register-commands.ts +++ b/examples/minimal/src/register-commands.ts @@ -1,16 +1,16 @@ -import 'dotenv/config' +import 'dotenv/config'; -import importDirectory from './utils/loader.js' -import logger from './utils/logger.js' -import { updateApplicationCommands } from './utils/updateCommands.js' +import importDirectory from './utils/loader.js'; +import logger from './utils/logger.js'; +import { updateApplicationCommands } from './utils/updateCommands.js'; -logger.info('Loading commands...') -await importDirectory('./dist/commands') +logger.info('Loading commands...'); +await importDirectory('./dist/commands'); -logger.info('Updating commands...') -await updateApplicationCommands() +logger.info('Updating commands...'); +await updateApplicationCommands(); -logger.info('Done!') +logger.info('Done!'); // We need to manually exit as the REST Manager has timeouts that will keep NodeJS alive -process.exit() +process.exit(); diff --git a/examples/minimal/src/types/commands.ts b/examples/minimal/src/types/commands.ts index 6276f2423..4d079622d 100644 --- a/examples/minimal/src/types/commands.ts +++ b/examples/minimal/src/types/commands.ts @@ -1,17 +1,17 @@ -import type { ApplicationCommandOption, ApplicationCommandTypes } from '@discordeno/bot' -import type { bot } from '../bot.js' +import type { ApplicationCommandOption, ApplicationCommandTypes } from '@discordeno/bot'; +import type { bot } from '../bot.js'; export interface Command { /** The name of this command. */ - name: string + name: string; /** What does this command do? */ - description: string + description: string; /** The type of command this is. */ - type: ApplicationCommandTypes + type: ApplicationCommandTypes; /** Whether or not this command is for the dev server only. */ - devOnly?: boolean + devOnly?: boolean; /** The options for this command */ - options?: ApplicationCommandOption[] + options?: ApplicationCommandOption[]; /** This will be executed when the command is run. */ - execute: (interaction: typeof bot.transformers.$inferredTypes.interaction) => unknown + execute: (interaction: typeof bot.transformers.$inferredTypes.interaction) => unknown; } diff --git a/examples/minimal/src/utils/loader.ts b/examples/minimal/src/utils/loader.ts index 5b1c6f541..213ceaf16 100644 --- a/examples/minimal/src/utils/loader.ts +++ b/examples/minimal/src/utils/loader.ts @@ -1,15 +1,15 @@ -import { readdir } from 'node:fs/promises' -import logger from './logger.js' +import { readdir } from 'node:fs/promises'; +import logger from './logger.js'; export default async function importDirectory(folder: string): Promise { - const files = await readdir(folder, { recursive: true }) + const files = await readdir(folder, { recursive: true }); for (const filename of files) { - if (!filename.endsWith('.js')) continue + if (!filename.endsWith('.js')) continue; // Using `file://` and `process.cwd()` to avoid weird issues with relative paths and/or Windows await import(`file://${process.cwd()}/${folder}/${filename}`).catch((x) => logger.fatal(`Cannot import file (${folder}/${filename}) for reason:`, x), - ) + ); } } diff --git a/examples/minimal/src/utils/logger.ts b/examples/minimal/src/utils/logger.ts index 4838e581b..47182b8b1 100644 --- a/examples/minimal/src/utils/logger.ts +++ b/examples/minimal/src/utils/logger.ts @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/no-unsafe-argument */ -import chalk from 'chalk' +import chalk from 'chalk'; export enum LogLevels { Debug, @@ -15,70 +15,70 @@ const prefixes = new Map([ [LogLevels.Warn, 'WARN'], [LogLevels.Error, 'ERROR'], [LogLevels.Fatal, 'FATAL'], -]) +]); -const noColor: (str: string) => string = (msg) => msg +const noColor: (str: string) => string = (msg) => msg; const colorFunctions = new Map string>([ [LogLevels.Debug, chalk.gray], [LogLevels.Info, chalk.cyan], [LogLevels.Warn, chalk.yellow], [LogLevels.Error, (str: string) => chalk.red(str)], [LogLevels.Fatal, (str: string) => chalk.red.bold.italic(str)], -]) +]); export function createLogger({ logLevel = LogLevels.Info, name }: { logLevel?: LogLevels; name?: string } = {}): Logger { function log(level: LogLevels, ...args: any[]): void { - if (level < logLevel) return + if (level < logLevel) return; - let color = colorFunctions.get(level) - if (!color) color = noColor + let color = colorFunctions.get(level); + if (!color) color = noColor; - const date = new Date() + const date = new Date(); const log = [ `[${date.toLocaleDateString()} ${date.toLocaleTimeString()}]`, color(prefixes.get(level) ?? 'DEBUG'), name ? `${name} >` : '>', ...args, - ] + ]; switch (level) { case LogLevels.Debug: - return console.debug(...log) + return console.debug(...log); case LogLevels.Info: - return console.info(...log) + return console.info(...log); case LogLevels.Warn: - return console.warn(...log) + return console.warn(...log); case LogLevels.Error: - return console.error(...log) + return console.error(...log); case LogLevels.Fatal: - return console.error(...log) + return console.error(...log); default: - return console.log(...log) + return console.log(...log); } } function setLevel(level: LogLevels): void { - logLevel = level + logLevel = level; } function debug(...args: any[]): void { - log(LogLevels.Debug, ...args) + log(LogLevels.Debug, ...args); } function info(...args: any[]): void { - log(LogLevels.Info, ...args) + log(LogLevels.Info, ...args); } function warn(...args: any[]): void { - log(LogLevels.Warn, ...args) + log(LogLevels.Warn, ...args); } function error(...args: any[]): void { - log(LogLevels.Error, ...args) + log(LogLevels.Error, ...args); } function fatal(...args: any[]): void { - log(LogLevels.Fatal, ...args) + log(LogLevels.Fatal, ...args); } return { @@ -89,18 +89,18 @@ export function createLogger({ logLevel = LogLevels.Info, name }: { logLevel?: L warn, error, fatal, - } + }; } -export const logger = createLogger({ name: 'Main' }) -export default logger +export const logger = createLogger({ name: 'Main' }); +export default logger; export interface Logger { - log: (level: LogLevels, ...args: any[]) => void - debug: (...args: any[]) => void - info: (...args: any[]) => void - warn: (...args: any[]) => void - error: (...args: any[]) => void - fatal: (...args: any[]) => void - setLevel: (level: LogLevels) => void + log: (level: LogLevels, ...args: any[]) => void; + debug: (...args: any[]) => void; + info: (...args: any[]) => void; + warn: (...args: any[]) => void; + error: (...args: any[]) => void; + fatal: (...args: any[]) => void; + setLevel: (level: LogLevels) => void; } diff --git a/examples/minimal/src/utils/updateCommands.ts b/examples/minimal/src/utils/updateCommands.ts index c98d3cc48..c68af612a 100644 --- a/examples/minimal/src/utils/updateCommands.ts +++ b/examples/minimal/src/utils/updateCommands.ts @@ -1,5 +1,5 @@ -import { bot } from '../bot.js' -import { configs } from '../config.js' +import { bot } from '../bot.js'; +import { configs } from '../config.js'; export async function updateApplicationCommands(): Promise { await bot.helpers.upsertGlobalApplicationCommands( @@ -7,7 +7,7 @@ export async function updateApplicationCommands(): Promise { // ONLY GLOBAL COMMANDS .filter((command) => !command.devOnly) .array(), - ) + ); await bot.helpers.upsertGuildApplicationCommands( configs.devGuildId, @@ -15,5 +15,5 @@ export async function updateApplicationCommands(): Promise { // ONLY GLOBAL COMMANDS .filter((command) => !!command.devOnly) .array(), - ) + ); } diff --git a/examples/reaction-roles/src/bot.ts b/examples/reaction-roles/src/bot.ts index 689281aff..ebbbc75d1 100644 --- a/examples/reaction-roles/src/bot.ts +++ b/examples/reaction-roles/src/bot.ts @@ -1,12 +1,12 @@ -import 'dotenv/config' +import 'dotenv/config'; -import { createBot } from '@discordeno/bot' -import events from './events/index.js' +import { createBot } from '@discordeno/bot'; +import events from './events/index.js'; -const token = process.env.TOKEN +const token = process.env.TOKEN; // Ensure the existence of the TOKEN env -if (!token) throw new Error('The TOKEN environment variable needs to be defined.') +if (!token) throw new Error('The TOKEN environment variable needs to be defined.'); export const bot = createBot({ token, @@ -41,6 +41,6 @@ export const bot = createBot({ id: true, }, }, -}) +}); -bot.events = events +bot.events = events; diff --git a/examples/reaction-roles/src/collector.ts b/examples/reaction-roles/src/collector.ts index 42de1aee1..7c76c4292 100644 --- a/examples/reaction-roles/src/collector.ts +++ b/examples/reaction-roles/src/collector.ts @@ -1,12 +1,12 @@ -import { EventEmitter } from 'node:events' +import { EventEmitter } from 'node:events'; // Extremely minimal collector class export default class ItemCollector extends EventEmitter { onItem(callback: (item: T) => unknown): void { - this.on('item', callback) + this.on('item', callback); } collect(item: T): void { - this.emit('item', item) + this.emit('item', item); } } diff --git a/examples/reaction-roles/src/commands/index.ts b/examples/reaction-roles/src/commands/index.ts index 2fcf6c52e..e57006b5b 100644 --- a/examples/reaction-roles/src/commands/index.ts +++ b/examples/reaction-roles/src/commands/index.ts @@ -1,12 +1,12 @@ -import type { CreateSlashApplicationCommand } from '@discordeno/types' -import type { bot } from '../bot.js' -import roles from './roles.js' +import type { CreateSlashApplicationCommand } from '@discordeno/types'; +import type { bot } from '../bot.js'; +import roles from './roles.js'; -export const commands = new Map([roles].map((cmd) => [cmd.name, cmd])) +export const commands = new Map([roles].map((cmd) => [cmd.name, cmd])); -export default commands +export default commands; export interface Command extends CreateSlashApplicationCommand { /** Handler that will be executed when this command is triggered */ - execute: (interaction: typeof bot.transformers.$inferredTypes.interaction, args: Record) => Promise + execute: (interaction: typeof bot.transformers.$inferredTypes.interaction, args: Record) => Promise; } diff --git a/examples/reaction-roles/src/commands/roles.ts b/examples/reaction-roles/src/commands/roles.ts index d8d278f4e..da264b320 100644 --- a/examples/reaction-roles/src/commands/roles.ts +++ b/examples/reaction-roles/src/commands/roles.ts @@ -1,4 +1,4 @@ -import assert from 'node:assert' +import assert from 'node:assert'; import { type ActionRow, type ButtonComponent, @@ -6,12 +6,12 @@ import { MessageComponentTypes, type SelectMenuComponent, TextStyles, -} from '@discordeno/bot' -import { ApplicationCommandOptionTypes, ButtonStyles } from '@discordeno/types' -import { bot } from '../bot.js' -import ItemCollector from '../collector.js' -import { collectors } from '../events/interactionCreate.js' -import type { Command } from './index.js' +} from '@discordeno/bot'; +import { ApplicationCommandOptionTypes, ButtonStyles } from '@discordeno/types'; +import { bot } from '../bot.js'; +import ItemCollector from '../collector.js'; +import { collectors } from '../events/interactionCreate.js'; +import type { Command } from './index.js'; const command: Command = { name: 'roles', @@ -73,22 +73,22 @@ const command: Command = { if (args.reactions?.create) { // Ensure that there is a channelId if (!interaction.channelId) { - await interaction.respond('Could not get the current channel.', { isPrivate: true }) - return + await interaction.respond('Could not get the current channel.', { isPrivate: true }); + return; } // This array is used to store all the roles for this reaction roles - let roles = [args.reactions.create] + let roles = [args.reactions.create]; // Send the message that uses will use to get the role const roleMessage = await bot.helpers.sendMessage(interaction.channelId, { content: 'Pick your roles', components: getRoleButtons(roles), - }) + }); // Create a copy of the actionRow for the main message // NOTE: we use a copy so when we edit this actionRow the edits don't get applied to all the command executions, only this one, for example we do disable some buttons in some conditional cases - const messageActionRow = structuredClone(messageActionRowTemplate) + const messageActionRow = structuredClone(messageActionRowTemplate); const message = await interaction.respond( { @@ -96,230 +96,230 @@ const command: Command = { components: [messageActionRow], }, { isPrivate: true, withResponse: true }, - ) + ); if (!message) { - await interaction.respond('❌ Unable to send the message correctly. Cancelling', { isPrivate: true }) - return + await interaction.respond('❌ Unable to send the message correctly. Cancelling', { isPrivate: true }); + return; } - assert('resource' in message && message.resource?.message) + assert('resource' in message && message.resource?.message); // Create the collector for the menu - const itemCollector = new ItemCollector() - collectors.add(itemCollector) + const itemCollector = new ItemCollector(); + collectors.add(itemCollector); // For the new reaction role, we need to keep track of what the user gave us - let partialRoleInfo: Partial<(typeof roles)[number]> | undefined + let partialRoleInfo: Partial<(typeof roles)[number]> | undefined; itemCollector.onItem(async (i) => { // We need to verify the interaction is for us. if (i.message?.id !== message.resource?.message?.id) { - return + return; } // Save button if (i.data?.customId === 'reactionRoles-save') { // Remove this item collector from the list of collectors (we aren't correcting anymore) - collectors.delete(itemCollector) + collectors.delete(itemCollector); // Delete the edit message - await i.deferEdit() - await i.delete() + await i.deferEdit(); + await i.delete(); - return + return; } // New button if (i.data?.customId === 'reactionRoles-add') { - partialRoleInfo = {} + partialRoleInfo = {}; // Ask the user for the role - await i.edit({ content: 'Pick a role for the new reaction role', components: [selectRoleActionRow] }) - return + await i.edit({ content: 'Pick a role for the new reaction role', components: [selectRoleActionRow] }); + return; } // New button - role select menu if (partialRoleInfo && i.data?.customId === 'reactionRoles-add-role') { - const roleToAdd = i.data?.resolved?.roles?.first() + const roleToAdd = i.data?.resolved?.roles?.first(); // Verify that we could get the role from discord if (!roleToAdd) { - throw new Error('Unable to get the information for the role to add') + throw new Error('Unable to get the information for the role to add'); } // Save it to our partial role information - partialRoleInfo.role = roleToAdd + partialRoleInfo.role = roleToAdd; // Ask the user for the color of the button await i.edit({ content: 'Pick a color for the reaction role', components: [selectColorActionRow], - }) + }); - return + return; } // New button - color select menu if (partialRoleInfo && i.data?.customId === 'reactionRoles-add-color') { - const color = parseInt(i.data?.values?.[0] ?? 'NaN') + const color = parseInt(i.data?.values?.[0] ?? 'NaN'); // Verify that we could get the color information if (isNaN(color)) { - throw new Error('Unable to get the information for the role to add') + throw new Error('Unable to get the information for the role to add'); } // Save the color to our partial - partialRoleInfo.color = color + partialRoleInfo.color = color; // Ask the user to input the emoji and optionally a label for the button await i.respond({ title: 'Pick an emoji and label for the reaction role', components: [selectEmojiActionRow, selectLabelActionRow], customId: 'reactionRoles-add-modal', - }) + }); - return + return; } // New button - emoji & label modal if (partialRoleInfo && i.data?.customId === 'reactionRoles-add-modal') { // Ensure that we can get the channelId from the interaction if (!interaction.channelId) { - throw new Error('Unable to get current channel') + throw new Error('Unable to get current channel'); } // Get the data from discord - const emoji = i.data.components?.[0]?.components?.[0].value - const label = i.data.components?.[1]?.components?.[0].value + const emoji = i.data.components?.[0]?.components?.[0].value; + const label = i.data.components?.[1]?.components?.[0].value; // Verify that the emoji was given if (!emoji) { - throw new Error('Unable to get the information for the role to add') + throw new Error('Unable to get the information for the role to add'); } // Save them to our partial - partialRoleInfo.emoji = emoji - partialRoleInfo.label = label + partialRoleInfo.emoji = emoji; + partialRoleInfo.label = label; // Save role and display the new message editing the old one // We are sure that in this place the entire object has been assembled - roles.push(partialRoleInfo as (typeof roles)[number]) + roles.push(partialRoleInfo as (typeof roles)[number]); await bot.helpers.editMessage(interaction.channelId, roleMessage.id, { components: getRoleButtons(roles), - }) + }); // Clear our partial roleInfo, we are done with it - partialRoleInfo = undefined + partialRoleInfo = undefined; // In case the delete button was disabled (all the roles were deleted) re-enable it - messageActionRow.components[1]!.disabled = false + messageActionRow.components[1]!.disabled = false; // Discord imposes a limit of 5 action rows and 5 buttons for actionRow = 25 buttons max // more than 25 will give an error, so we disable the new button if (roles.length === 25) { - const button = messageActionRow.components[0] as ButtonComponent - button.disabled = true + const button = messageActionRow.components[0] as ButtonComponent; + button.disabled = true; } // Show again the main edit menu await interaction.edit({ content: 'Use the buttons in this message to edit the message below.', components: [messageActionRow], - }) + }); // Respond to the modal. A modal submit (type 5) interaction can't edit the original response - await i.respond('Reaction role created successfully. You can use the message above to add/remove a role', { isPrivate: true }) + await i.respond('Reaction role created successfully. You can use the message above to add/remove a role', { isPrivate: true }); - return + return; } // Remove button if (i.data?.customId === 'reactionRoles-remove') { // Clone the actionRow for the remove select menu, this is to prevent unwanted data to appear to other users - const removeActionRow = structuredClone(removeActionRowTemplate) - const selectMenu = removeActionRow.components[0] as SelectMenuComponent + const removeActionRow = structuredClone(removeActionRowTemplate); + const selectMenu = removeActionRow.components[0] as SelectMenuComponent; // Add the possible values for this select menu for (const roleInfo of roles) { selectMenu.options.push({ label: `${roleInfo.emoji} ${roleInfo.label ?? ''}`, value: roleInfo.role.id.toString(), - }) + }); } // Ask the user for what reaction role they want to remove await i.edit({ content: 'Select what reaction role to remove', components: [removeActionRow], - }) + }); - return + return; } // Remove button - role select menu if (i.data?.customId === 'reactionRoles-remove-selectMenu') { // Ensure that we can get the channelId from the interaction if (!interaction.channelId) { - throw new Error('Unable to get current channel') + throw new Error('Unable to get current channel'); } // Get the role to delete from discord - const roleToRemove = i.data?.values?.[0] + const roleToRemove = i.data?.values?.[0]; // Ensure we got it if (!roleToRemove) { - throw new Error('Unable to get the role to remove') + throw new Error('Unable to get the role to remove'); } - await i.deferEdit() + await i.deferEdit(); // Remove the role from the list - roles = roles.filter((roleInfo) => roleInfo.role.id.toString() !== roleToRemove) + roles = roles.filter((roleInfo) => roleInfo.role.id.toString() !== roleToRemove); // Edit the main button await bot.helpers.editMessage(interaction.channelId, roleMessage.id, { components: getRoleButtons(roles), - }) + }); // If the new button was disabled (we were at 25 buttons) we re-enable it - const button = messageActionRow.components[0] as ButtonComponent - button.disabled = false + const button = messageActionRow.components[0] as ButtonComponent; + button.disabled = false; // If we are at 0 roles, and the user tried to delete a role they will get locked in the menu, so we disable it if (roles.length === 0) { - messageActionRow.components[1]!.disabled = true + messageActionRow.components[1]!.disabled = true; } // Show the main edit ui (new, remove, save) await i.edit({ content: 'Use the buttons in this message to edit the message below.', components: [messageActionRow], - }) + }); - return + return; } // We don't know what code to run for this interaction - throw new Error('Unknown button') - }) + throw new Error('Unknown button'); + }); } }, -} +}; -export default command +export default command; // Interface to type the arguments that we receive from discord interface CommandArgs { reactions?: { create?: { - role: typeof bot.transformers.$inferredTypes.role - emoji: string - color: ButtonStyles - label?: string - } - } + role: typeof bot.transformers.$inferredTypes.role; + emoji: string; + color: ButtonStyles; + label?: string; + }; + }; } // Templates/ActionRows for the command to then be referenced in the various part of the code @@ -357,7 +357,7 @@ const messageActionRowTemplate: ActionRow = { label: 'Save', }, ], -} as const +} as const; const removeActionRowTemplate: ActionRow = { type: MessageComponentTypes.ActionRow, @@ -371,7 +371,7 @@ const removeActionRowTemplate: ActionRow = { options: [], }, ], -} as const +} as const; const selectRoleActionRow: ActionRow = { type: MessageComponentTypes.ActionRow, @@ -384,7 +384,7 @@ const selectRoleActionRow: ActionRow = { placeholder: 'Select a role', }, ], -} as const +} as const; const selectColorActionRow: ActionRow = { type: MessageComponentTypes.ActionRow, @@ -400,7 +400,7 @@ const selectColorActionRow: ActionRow = { ], }, ], -} as const +} as const; const selectEmojiActionRow: ActionRow = { type: MessageComponentTypes.ActionRow, @@ -413,7 +413,7 @@ const selectEmojiActionRow: ActionRow = { required: true, }, ], -} as const +} as const; const selectLabelActionRow: ActionRow = { type: MessageComponentTypes.ActionRow, @@ -427,37 +427,37 @@ const selectLabelActionRow: ActionRow = { maxLength: 80, }, ], -} as const +} as const; // Function to get all the actionRows with buttons for the reaction roles message function getRoleButtons( roles: Array<{ - role: typeof bot.transformers.$inferredTypes.role - emoji: string - color: ButtonStyles - label?: string | undefined + role: typeof bot.transformers.$inferredTypes.role; + emoji: string; + color: ButtonStyles; + label?: string | undefined; }>, ): ActionRow[] { - const actionRows: ActionRow[] = [] + const actionRows: ActionRow[] = []; // If there aren't any roles, we don't need any buttons - if (roles.length === 0) return actionRows + if (roles.length === 0) return actionRows; // We add the components later, so we need to make typescript know that we are sure that it will be a compatibile components array - actionRows.push({ type: MessageComponentTypes.ActionRow, components: [] as unknown as ActionRow['components'] }) + actionRows.push({ type: MessageComponentTypes.ActionRow, components: [] as unknown as ActionRow['components'] }); for (const roleInfo of roles) { - let actionRow = actionRows.at(-1) + let actionRow = actionRows.at(-1); // Ensure that we were able to get the actionRow if (!actionRow) { - throw new Error('Unable to get actionRow') + throw new Error('Unable to get actionRow'); } // If the actionRow is full (has 5 buttons) add a new one if (actionRow.components.length === 5) { - actionRow = { type: MessageComponentTypes.ActionRow, components: [] as unknown as ActionRow['components'] } - actionRows.push(actionRow) + actionRow = { type: MessageComponentTypes.ActionRow, components: [] as unknown as ActionRow['components'] }; + actionRows.push(actionRow); } // Add the new button to this actionRow @@ -469,8 +469,8 @@ function getRoleButtons( }, label: roleInfo.label, customId: `reactionRoles-role-${roleInfo.role.id}`, - }) + }); } - return actionRows + return actionRows; } diff --git a/examples/reaction-roles/src/events/index.ts b/examples/reaction-roles/src/events/index.ts index c7b5585ec..3d4cb5bb8 100644 --- a/examples/reaction-roles/src/events/index.ts +++ b/examples/reaction-roles/src/events/index.ts @@ -1,10 +1,10 @@ -import type { bot } from '../bot.js' -import { event as interactionCreateEvent } from './interactionCreate.js' -import { event as readyEvent } from './ready.js' +import type { bot } from '../bot.js'; +import { event as interactionCreateEvent } from './interactionCreate.js'; +import { event as readyEvent } from './ready.js'; export const events = { interactionCreate: interactionCreateEvent, ready: readyEvent, -} as typeof bot.events +} as typeof bot.events; -export default events +export default events; diff --git a/examples/reaction-roles/src/events/interactionCreate.ts b/examples/reaction-roles/src/events/interactionCreate.ts index a8f9aaf49..5136beba8 100644 --- a/examples/reaction-roles/src/events/interactionCreate.ts +++ b/examples/reaction-roles/src/events/interactionCreate.ts @@ -1,59 +1,59 @@ -import { commandOptionsParser, InteractionTypes, MessageComponentTypes } from '@discordeno/bot' -import { bot } from '../bot.js' -import type ItemCollector from '../collector.js' -import commands from '../commands/index.js' +import { commandOptionsParser, InteractionTypes, MessageComponentTypes } from '@discordeno/bot'; +import { bot } from '../bot.js'; +import type ItemCollector from '../collector.js'; +import commands from '../commands/index.js'; -export const collectors = new Set>() +export const collectors = new Set>(); export const event: typeof bot.events.interactionCreate = async (interaction) => { // Give to all the collectors the interaction to use for (const collector of collectors) { - collector.collect(interaction) + collector.collect(interaction); } // If the interaction is a command check if it is a command and run it if (interaction.type === InteractionTypes.ApplicationCommand) { - if (!interaction.data) return + if (!interaction.data) return; - const command = commands.get(interaction.data.name) - if (!command) return + const command = commands.get(interaction.data.name); + if (!command) return; try { - await command.execute(interaction, commandOptionsParser(interaction)) + await command.execute(interaction, commandOptionsParser(interaction)); } catch (error) { - console.error(error) + console.error(error); } } // If the interaction is a button it might be the button press on our reaction role message if (interaction.type === InteractionTypes.MessageComponent && interaction.data?.componentType === MessageComponentTypes.Button) { // The interaction is not a button press on the role button - if (!interaction.data?.customId?.startsWith('reactionRoles-role-')) return - if (!interaction.guildId || !interaction.member) return + if (!interaction.data?.customId?.startsWith('reactionRoles-role-')) return; + if (!interaction.guildId || !interaction.member) return; // Remove the prefix and get the roleId - const roleId = BigInt(interaction.data.customId.slice('reactionRoles-role-'.length)) + const roleId = BigInt(interaction.data.customId.slice('reactionRoles-role-'.length)); // Check if we need to remove or add the role to the user - const alreadyHasRole = !!interaction.member.roles.find((role) => role === roleId) + const alreadyHasRole = !!interaction.member.roles.find((role) => role === roleId); try { if (alreadyHasRole) { - await bot.helpers.removeRole(interaction.guildId, interaction.user.id, roleId, `Reaction role button for role id ${roleId}`) - await interaction.respond(`I removed from you the <@&${roleId}> role.`, { isPrivate: true }) - return + await bot.helpers.removeRole(interaction.guildId, interaction.user.id, roleId, `Reaction role button for role id ${roleId}`); + await interaction.respond(`I removed from you the <@&${roleId}> role.`, { isPrivate: true }); + return; } // You will get an invalid request made if the bot attempts to give a bot role, a role higher then him hightest role, a link role or if it does not have the Manage Roles permission // This could be prevented by checking for the roles that the bot owns and the role that the bot is trying to add - await bot.helpers.addRole(interaction.guildId, interaction.user.id, roleId, `Reaction role button for role id ${roleId}`) - await interaction.respond(`I added to you the <@&${roleId}> role.`, { isPrivate: true }) + await bot.helpers.addRole(interaction.guildId, interaction.user.id, roleId, `Reaction role button for role id ${roleId}`); + await interaction.respond(`I added to you the <@&${roleId}> role.`, { isPrivate: true }); } catch { // Respond with an error message await interaction.respond( 'I could not give you the role. Possible reasons are:\n- My permissions are not configured correctly, make sure i have the `Manage Roles` permission\n- The role is **above** my hightest role in the server setup\n- The role does not exist or is non-manageable (for example: bot roles, link roles or @everyone)', { isPrivate: true }, - ) + ); } } -} +}; diff --git a/examples/reaction-roles/src/events/ready.ts b/examples/reaction-roles/src/events/ready.ts index 5b883adad..18f686b08 100644 --- a/examples/reaction-roles/src/events/ready.ts +++ b/examples/reaction-roles/src/events/ready.ts @@ -1,6 +1,6 @@ -import { bot } from '../bot.js' +import { bot } from '../bot.js'; export const event: typeof bot.events.ready = () => { // Print to the console when the bot has connected to discord and is ready to handle the events - bot.logger.info('The bot is ready!') -} + bot.logger.info('The bot is ready!'); +}; diff --git a/examples/reaction-roles/src/index.ts b/examples/reaction-roles/src/index.ts index ffe24c1a4..058da016c 100644 --- a/examples/reaction-roles/src/index.ts +++ b/examples/reaction-roles/src/index.ts @@ -1,5 +1,5 @@ -import { bot } from './bot.js' +import { bot } from './bot.js'; -await bot.start() +await bot.start(); -process.on('unhandledRejection', bot.logger.error) +process.on('unhandledRejection', bot.logger.error); diff --git a/examples/reaction-roles/src/register-commands.ts b/examples/reaction-roles/src/register-commands.ts index c289dba44..dc8d88fb2 100644 --- a/examples/reaction-roles/src/register-commands.ts +++ b/examples/reaction-roles/src/register-commands.ts @@ -1,12 +1,12 @@ -import 'dotenv/config' +import 'dotenv/config'; -import { bot } from './bot.js' -import commands from './commands/index.js' +import { bot } from './bot.js'; +import commands from './commands/index.js'; -const guildId = 'REPLACE WITH YOUR GUILD ID' +const guildId = 'REPLACE WITH YOUR GUILD ID'; await bot.rest .upsertGuildApplicationCommands(guildId, [...commands.values()]) - .catch((e) => bot.logger.error('There was an error when updating the global commands', e)) + .catch((e) => bot.logger.error('There was an error when updating the global commands', e)); -process.exit(0) +process.exit(0); diff --git a/packages/bot/src/bot.ts b/packages/bot/src/bot.ts index cb394bedc..46feedb6c 100644 --- a/packages/bot/src/bot.ts +++ b/packages/bot/src/bot.ts @@ -1,20 +1,20 @@ -import type { CreateGatewayManagerOptions, GatewayManager } from '@discordeno/gateway' -import { createGatewayManager, ShardSocketCloseCodes } from '@discordeno/gateway' -import type { CreateRestManagerOptions, RestManager } from '@discordeno/rest' -import { createRestManager } from '@discordeno/rest' -import type { BigString, GatewayDispatchEventNames, GatewayIntents, RecursivePartial } from '@discordeno/types' -import { createLogger, getBotIdFromToken, type logger } from '@discordeno/utils' +import type { CreateGatewayManagerOptions, GatewayManager } from '@discordeno/gateway'; +import { createGatewayManager, ShardSocketCloseCodes } from '@discordeno/gateway'; +import type { CreateRestManagerOptions, RestManager } from '@discordeno/rest'; +import { createRestManager } from '@discordeno/rest'; +import type { BigString, GatewayDispatchEventNames, GatewayIntents, RecursivePartial } from '@discordeno/types'; +import { createLogger, getBotIdFromToken, type logger } from '@discordeno/utils'; import type { CompleteDesiredProperties, DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties, TransformersObjects, -} from './desiredProperties.js' -import type { EventHandlers } from './events.js' -import { type BotGatewayHandler, createBotGatewayHandlers, type GatewayHandlers } from './handlers.js' -import { type BotHelpers, createBotHelpers } from './helpers.js' -import { createTransformers, type Transformers } from './transformers.js' +} from './desiredProperties.js'; +import type { EventHandlers } from './events.js'; +import { type BotGatewayHandler, createBotGatewayHandlers, type GatewayHandlers } from './handlers.js'; +import { type BotHelpers, createBotHelpers } from './helpers.js'; +import { createTransformers, type Transformers } from './transformers.js'; /** * Create a bot object that will maintain the rest and gateway connection. @@ -27,44 +27,44 @@ import { createTransformers, type Transformers } from './transformers.js' export function createBot< TProps extends TransformersDesiredProperties, TBehavior extends DesiredPropertiesBehavior = DesiredPropertiesBehavior.RemoveKey, ->(options: CreateBotOptions): Bot +>(options: CreateBotOptions): Bot; export function createBot< TProps extends RecursivePartial, TBehavior extends DesiredPropertiesBehavior = DesiredPropertiesBehavior.RemoveKey, ->(options: CreateBotOptions): Bot, TBehavior> +>(options: CreateBotOptions): Bot, TBehavior>; export function createBot< TProps extends RecursivePartial, TBehavior extends DesiredPropertiesBehavior = DesiredPropertiesBehavior.RemoveKey, >(options: CreateBotOptions): Bot, TBehavior> { - type CompleteProps = CompleteDesiredProperties - type TypedBot = Bot + type CompleteProps = CompleteDesiredProperties; + type TypedBot = Bot; - if (!options.transformers) options.transformers = {} - if (!options.rest) options.rest = { token: options.token, applicationId: options.applicationId } - if (!options.rest.token) options.rest.token = options.token - if (!options.rest.logger && options.loggerFactory) options.rest.logger = options.loggerFactory('REST') - if (!options.gateway) options.gateway = { token: options.token } - if (!options.gateway.token) options.gateway.token = options.token - if (!options.gateway.events) options.gateway.events = {} - if (!options.gateway.logger && options.loggerFactory) options.gateway.logger = options.loggerFactory('GATEWAY') + if (!options.transformers) options.transformers = {}; + if (!options.rest) options.rest = { token: options.token, applicationId: options.applicationId }; + if (!options.rest.token) options.rest.token = options.token; + if (!options.rest.logger && options.loggerFactory) options.rest.logger = options.loggerFactory('REST'); + if (!options.gateway) options.gateway = { token: options.token }; + if (!options.gateway.token) options.gateway.token = options.token; + if (!options.gateway.events) options.gateway.events = {}; + if (!options.gateway.logger && options.loggerFactory) options.gateway.logger = options.loggerFactory('GATEWAY'); if (!options.gateway.events.message) { options.gateway.events.message = async (shard, data) => { // TRIGGER RAW EVENT - bot.events.raw?.(data, shard.id) + bot.events.raw?.(data, shard.id); - if (!data.t) return + if (!data.t) return; // RUN DISPATCH CHECK - await bot.events.dispatchRequirements?.(data, shard.id) - bot.handlers[data.t as GatewayDispatchEventNames]?.(bot, data, shard.id) - } + await bot.events.dispatchRequirements?.(data, shard.id); + bot.handlers[data.t as GatewayDispatchEventNames]?.(bot, data, shard.id); + }; } - options.gateway.intents = options.intents - ;(options.transformers as Transformers).desiredProperties = options.desiredProperties as CompleteProps + options.gateway.intents = options.intents; + (options.transformers as Transformers).desiredProperties = options.desiredProperties as CompleteProps; - const id = getBotIdFromToken(options.token) + const id = getBotIdFromToken(options.token); const bot: TypedBot = { id, @@ -79,63 +79,63 @@ export function createBot< helpers: {} as BotHelpers, async start() { if (!options.gateway?.connection) { - bot.gateway.connection = await bot.rest.getSessionInfo() + bot.gateway.connection = await bot.rest.getSessionInfo(); // Check for overrides in the configuration - if (!options.gateway?.url) bot.gateway.url = bot.gateway.connection.url + if (!options.gateway?.url) bot.gateway.url = bot.gateway.connection.url; - if (!options.gateway?.totalShards) bot.gateway.totalShards = bot.gateway.connection.shards + if (!options.gateway?.totalShards) bot.gateway.totalShards = bot.gateway.connection.shards; - if (!options.gateway?.lastShardId && !options.gateway?.totalShards) bot.gateway.lastShardId = bot.gateway.connection.shards - 1 + if (!options.gateway?.lastShardId && !options.gateway?.totalShards) bot.gateway.lastShardId = bot.gateway.connection.shards - 1; } if (!bot.gateway.resharding.getSessionInfo) { bot.gateway.resharding.getSessionInfo = async () => { - return await bot.rest.getGatewayBot() - } + return await bot.rest.getGatewayBot(); + }; } - await bot.gateway.spawnShards() + await bot.gateway.spawnShards(); }, async shutdown() { - return await bot.gateway.shutdown(ShardSocketCloseCodes.Shutdown, 'User requested bot stop') + return await bot.gateway.shutdown(ShardSocketCloseCodes.Shutdown, 'User requested bot stop'); }, - } + }; - bot.helpers = createBotHelpers(bot) - if (options.applicationId) bot.applicationId = bot.transformers.snowflake(options.applicationId) + bot.helpers = createBotHelpers(bot); + if (options.applicationId) bot.applicationId = bot.transformers.snowflake(options.applicationId); - return bot + return bot; } export interface CreateBotOptions, TBehavior extends DesiredPropertiesBehavior> { /** The bot's token. */ - token: string + token: string; /** Application Id of the bot incase it is an old bot token. */ - applicationId?: BigString + applicationId?: BigString; /** The bot's intents that will be used to make a connection with discords gateway. */ - intents?: GatewayIntents + intents?: GatewayIntents; /** Any options you wish to provide to the rest manager. */ - rest?: Omit & Partial> + rest?: Omit & Partial>; /** Any options you wish to provide to the gateway manager. */ - gateway?: Omit & Partial> + gateway?: Omit & Partial>; /** The event handlers. */ - events?: Partial>, TBehavior>> + events?: Partial>, TBehavior>>; /** The functions that should transform discord objects to discordeno shaped objects. */ - transformers?: RecursivePartial>, TBehavior>, 'desiredProperties'>> + transformers?: RecursivePartial>, TBehavior>, 'desiredProperties'>>; /** The handler functions that should handle incoming discord payloads from gateway and call an event. */ - handlers?: Partial>, TBehavior>>> + handlers?: Partial>, TBehavior>>>; /** * Set the desired properties for the bot */ - desiredProperties: TProps + desiredProperties: TProps; /** * Set the desired properties behavior for undesired properties * * @default DesiredPropertiesBehavior.RemoveKey */ - desiredPropertiesBehavior?: TBehavior + desiredPropertiesBehavior?: TBehavior; /** * This factory will be invoked to create the logger for gateway, rest and bot * @@ -144,7 +144,7 @@ export interface CreateBotOptions Pick + loggerFactory?: (name: 'REST' | 'GATEWAY' | 'BOT') => Pick; } export interface Bot< @@ -152,28 +152,28 @@ export interface Bot< TBehavior extends DesiredPropertiesBehavior = DesiredPropertiesBehavior.RemoveKey, > { /** The id of the bot. */ - id: bigint + id: bigint; /** The application id of the bot. This is usually the same as id but in the case of old bots can be different. */ - applicationId: bigint + applicationId: bigint; /** The rest manager. */ - rest: RestManager + rest: RestManager; /** The gateway manager. */ - gateway: GatewayManager + gateway: GatewayManager; /** The event handlers. */ - events: Partial> + events: Partial>; /** A logger utility to make it easy to log nice and useful things in the bot code. */ - logger: Pick + logger: Pick; /** The functions that should transform discord objects to discordeno shaped objects. */ transformers: Transformers & { $inferredTypes: { - [K in keyof TransformersObjects]: SetupDesiredProps - } - } + [K in keyof TransformersObjects]: SetupDesiredProps; + }; + }; /** The handler functions that should handle incoming discord payloads from gateway and call an event. */ - handlers: GatewayHandlers - helpers: BotHelpers + handlers: GatewayHandlers; + helpers: BotHelpers; /** Start the bot connection to the gateway. */ - start: () => Promise + start: () => Promise; /** Shuts down all the bot connections to the gateway. */ - shutdown: () => Promise + shutdown: () => Promise; } diff --git a/packages/bot/src/commandOptionsParser.ts b/packages/bot/src/commandOptionsParser.ts index a902b1b3e..0bd0bb6fd 100644 --- a/packages/bot/src/commandOptionsParser.ts +++ b/packages/bot/src/commandOptionsParser.ts @@ -1,6 +1,6 @@ -import { ApplicationCommandOptionTypes } from '@discordeno/types' -import type { CompleteDesiredProperties, DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from './desiredProperties.js' -import type { Attachment, Channel, Interaction, InteractionDataOption, Member, Role, User } from './transformers/types.js' +import { ApplicationCommandOptionTypes } from '@discordeno/types'; +import type { CompleteDesiredProperties, DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from './desiredProperties.js'; +import type { Attachment, Channel, Interaction, InteractionDataOption, Member, Role, User } from './transformers/types.js'; export function commandOptionsParser< TProps extends TransformersDesiredProperties & { interaction: { data: true } }, @@ -11,51 +11,51 @@ export function commandOptionsParser< Interaction, CompleteDesiredProperties<{ interaction: { data: true } }>, DesiredPropertiesBehavior.RemoveKey - > + >; - if (!interaction.data) return {} - if (!options) options = interaction.data.options ?? [] + if (!interaction.data) return {}; + if (!options) options = interaction.data.options ?? []; - const args: ParsedInteractionOption = {} + const args: ParsedInteractionOption = {}; for (const option of options) { switch (option.type) { case ApplicationCommandOptionTypes.SubCommandGroup: case ApplicationCommandOptionTypes.SubCommand: - args[option.name] = commandOptionsParser(interaction, option.options) as InteractionResolvedData - break + args[option.name] = commandOptionsParser(interaction, option.options) as InteractionResolvedData; + break; case ApplicationCommandOptionTypes.Channel: - args[option.name] = interaction.data.resolved?.channels?.get(BigInt(option.value!)) as InteractionResolvedData - break + args[option.name] = interaction.data.resolved?.channels?.get(BigInt(option.value!)) as InteractionResolvedData; + break; case ApplicationCommandOptionTypes.Role: - args[option.name] = interaction.data.resolved?.roles?.get(BigInt(option.value!)) as InteractionResolvedData - break + args[option.name] = interaction.data.resolved?.roles?.get(BigInt(option.value!)) as InteractionResolvedData; + break; case ApplicationCommandOptionTypes.User: args[option.name] = { user: interaction.data.resolved?.users?.get(BigInt(option.value!)) as InteractionResolvedData, member: interaction.data.resolved?.members?.get(BigInt(option.value!)) as InteractionResolvedData, - } - break + }; + break; case ApplicationCommandOptionTypes.Attachment: - args[option.name] = interaction.data.resolved?.attachments?.get(BigInt(option.value!)) as InteractionResolvedData - break + args[option.name] = interaction.data.resolved?.attachments?.get(BigInt(option.value!)) as InteractionResolvedData; + break; case ApplicationCommandOptionTypes.Mentionable: // Mentionable are roles or users args[option.name] = (interaction.data.resolved?.roles?.get(BigInt(option.value!)) as ParsedInteractionOption[string]) ?? { user: interaction.data.resolved?.users?.get(BigInt(option.value!)) as InteractionResolvedData, member: interaction.data.resolved?.members?.get(BigInt(option.value!)) as InteractionResolvedData, - } - break + }; + break; default: - args[option.name] = option.value as InteractionResolvedData + args[option.name] = option.value as InteractionResolvedData; } } - return args + return args; } export interface ParsedInteractionOption { - [key: string]: InteractionResolvedData + [key: string]: InteractionResolvedData; } export type InteractionResolvedData = @@ -66,11 +66,11 @@ export type InteractionResolvedData | SetupDesiredProps | SetupDesiredProps - | ParsedInteractionOption + | ParsedInteractionOption; export interface InteractionResolvedDataUser { - user: SetupDesiredProps - member: InteractionResolvedDataMember + user: SetupDesiredProps; + member: InteractionResolvedDataMember; } export type InteractionResolvedDataChannel = Pick< @@ -92,17 +92,17 @@ export type InteractionResolvedDataChannel -> +>; export type InteractionResolvedDataMember = Omit< SetupDesiredProps, 'user' | 'deaf' | 'mute' -> +>; /** @deprecated Use {@link InteractionResolvedDataUser} */ export interface InteractionResolvedUser { - user: User - member: InteractionResolvedMember + user: User; + member: InteractionResolvedMember; } /** @deprecated Use {@link InteractionResolvedDataChannel} */ @@ -122,7 +122,7 @@ export type InteractionResolvedChannel = Pick< | 'topic' | 'position' | 'threadMetadata' -> +>; /** @deprecated Use {@link InteractionResolvedDataMember} */ -export type InteractionResolvedMember = Omit +export type InteractionResolvedMember = Omit; diff --git a/packages/bot/src/constants.ts b/packages/bot/src/constants.ts index b9bbf617f..c5334e730 100644 --- a/packages/bot/src/constants.ts +++ b/packages/bot/src/constants.ts @@ -1,4 +1,4 @@ -export const SLASH_COMMANDS_NAME_REGEX = /^[-_ʼ\p{L}\p{N}\p{sc=Deva}\p{sc=Thai}]{1,32}$/u -export const CONTEXT_MENU_COMMANDS_NAME_REGEX = /^[\w-\s]{1,32}$/ -export const CHANNEL_MENTION_REGEX = /<#[0-9]+>/g -export const DISCORD_SNOWFLAKE_REGEX = /^(?\d{17,19})$/ +export const SLASH_COMMANDS_NAME_REGEX = /^[-_ʼ\p{L}\p{N}\p{sc=Deva}\p{sc=Thai}]{1,32}$/u; +export const CONTEXT_MENU_COMMANDS_NAME_REGEX = /^[\w-\s]{1,32}$/; +export const CHANNEL_MENTION_REGEX = /<#[0-9]+>/g; +export const DISCORD_SNOWFLAKE_REGEX = /^(?\d{17,19})$/; diff --git a/packages/bot/src/desiredProperties.ts b/packages/bot/src/desiredProperties.ts index 9c2aba4c1..fa62181aa 100644 --- a/packages/bot/src/desiredProperties.ts +++ b/packages/bot/src/desiredProperties.ts @@ -1,7 +1,7 @@ -import type { RecursivePartial } from '@discordeno/types' -import type { Collection } from '@discordeno/utils' -import type { Bot } from './bot.js' -import type { InteractionResolvedDataChannel, InteractionResolvedDataMember } from './commandOptionsParser.js' +import type { RecursivePartial } from '@discordeno/types'; +import type { Collection } from '@discordeno/utils'; +import type { Bot } from './bot.js'; +import type { InteractionResolvedDataChannel, InteractionResolvedDataMember } from './commandOptionsParser.js'; import type { ActivityInstance, ActivityLocation, @@ -56,7 +56,7 @@ import type { UserPrimaryGuild, VoiceState, Webhook, -} from './transformers/types.js' +} from './transformers/types.js'; /** * All the objects that support desired properties @@ -64,59 +64,59 @@ import type { * @private This is subject to breaking changes at any time */ export interface TransformersObjects { - activityInstance: ActivityInstance - activityLocation: ActivityLocation - attachment: Attachment - avatarDecorationData: AvatarDecorationData - channel: Channel - collectibles: Collectibles - component: Component - defaultReactionEmoji: DefaultReactionEmoji - emoji: Emoji - entitlement: Entitlement - forumTag: ForumTag - guild: Guild - guildOnboarding: GuildOnboarding - guildOnboardingPrompt: GuildOnboardingPrompt - guildOnboardingPromptOption: GuildOnboardingPromptOption - incidentsData: IncidentsData - interaction: Interaction - interactionCallback: InteractionCallback - interactionCallbackResponse: InteractionCallbackResponse - interactionResource: InteractionResource - invite: Invite - inviteStageInstance: InviteStageInstance - lobby: Lobby - lobbyMember: LobbyMember - mediaGalleryItem: MediaGalleryItem - member: Member - message: Message - messageCall: MessageCall - messageInteraction: MessageInteraction - messageInteractionMetadata: MessageInteractionMetadata - messagePin: MessagePin - messageReference: MessageReference - messageSnapshot: MessageSnapshot - nameplate: Nameplate - poll: Poll - pollAnswer: PollAnswer - pollAnswerCount: PollAnswerCount - pollMedia: PollMedia - pollResult: PollResult - role: Role - roleColors: RoleColors - scheduledEvent: ScheduledEvent - scheduledEventRecurrenceRule: ScheduledEventRecurrenceRule - sku: Sku - soundboardSound: SoundboardSound - stageInstance: StageInstance - sticker: Sticker - subscription: Subscription - unfurledMediaItem: UnfurledMediaItem - user: User - userPrimaryGuild: UserPrimaryGuild - voiceState: VoiceState - webhook: Webhook + activityInstance: ActivityInstance; + activityLocation: ActivityLocation; + attachment: Attachment; + avatarDecorationData: AvatarDecorationData; + channel: Channel; + collectibles: Collectibles; + component: Component; + defaultReactionEmoji: DefaultReactionEmoji; + emoji: Emoji; + entitlement: Entitlement; + forumTag: ForumTag; + guild: Guild; + guildOnboarding: GuildOnboarding; + guildOnboardingPrompt: GuildOnboardingPrompt; + guildOnboardingPromptOption: GuildOnboardingPromptOption; + incidentsData: IncidentsData; + interaction: Interaction; + interactionCallback: InteractionCallback; + interactionCallbackResponse: InteractionCallbackResponse; + interactionResource: InteractionResource; + invite: Invite; + inviteStageInstance: InviteStageInstance; + lobby: Lobby; + lobbyMember: LobbyMember; + mediaGalleryItem: MediaGalleryItem; + member: Member; + message: Message; + messageCall: MessageCall; + messageInteraction: MessageInteraction; + messageInteractionMetadata: MessageInteractionMetadata; + messagePin: MessagePin; + messageReference: MessageReference; + messageSnapshot: MessageSnapshot; + nameplate: Nameplate; + poll: Poll; + pollAnswer: PollAnswer; + pollAnswerCount: PollAnswerCount; + pollMedia: PollMedia; + pollResult: PollResult; + role: Role; + roleColors: RoleColors; + scheduledEvent: ScheduledEvent; + scheduledEventRecurrenceRule: ScheduledEventRecurrenceRule; + sku: Sku; + soundboardSound: SoundboardSound; + stageInstance: StageInstance; + sticker: Sticker; + subscription: Subscription; + unfurledMediaItem: UnfurledMediaItem; + user: User; + userPrimaryGuild: UserPrimaryGuild; + voiceState: VoiceState; + webhook: Webhook; } /** @@ -228,7 +228,7 @@ export const transformersDesiredPropertiesMetadata = { }, alwaysPresents: ['toggles'], }, -} as const satisfies DesiredPropertiesMetadata +} as const satisfies DesiredPropertiesMetadata; /** * Metadata for typescript to create the correct types for desired properties @@ -239,7 +239,7 @@ type TransformersDesiredPropertiesMetadata = CompleteByKeys< typeof transformersDesiredPropertiesMetadata, keyof DesiredPropertiesMetadata, { dependencies: {}; alwaysPresents: [] } -> +>; export function createDesiredPropertiesObject, TDefault extends boolean = false>( desiredProperties: T, @@ -867,43 +867,43 @@ export function createDesiredPropertiesObject + } satisfies TransformersDesiredProperties as CompleteDesiredProperties; } /** @private This is subject to breaking changes without notices */ -export type Equals = Required extends Required ? (Required extends Required ? true : false) : false +export type Equals = Required extends Required ? (Required extends Required ? true : false) : false; /** @private This is subject to breaking changes without notices */ export type KeyByValue = { - [Key in keyof TObj]: Equals extends true ? Key : never -}[keyof TObj] + [Key in keyof TObj]: Equals extends true ? Key : never; +}[keyof TObj]; /** @private This is subject to breaking changes without notices */ export type Complete = { - [K in keyof TObj]-?: undefined extends TObj[K] ? TDefault : Exclude -} + [K in keyof TObj]-?: undefined extends TObj[K] ? TDefault : Exclude; +}; /** @private This is subject to breaking changes without notices */ export type CompleteByKeys = { - [K in Keys]-?: K extends keyof TObj ? (undefined extends TObj[K] ? TDefault : Exclude) : TDefault -} + [K in Keys]-?: K extends keyof TObj ? (undefined extends TObj[K] ? TDefault : Exclude) : TDefault; +}; /** @private This is subject to breaking changes without notices */ export type JoinTuple = T extends readonly [infer F extends string, ...infer R extends string[]] ? R['length'] extends 0 ? F : `${F}${TDelimiter}${JoinTuple}` - : '' + : ''; /** @private This is subject to breaking changes without notices */ export type DesiredPropertiesMetadata = { [K in keyof TransformersObjects]?: { dependencies: { - [Key in keyof TransformersObjects[K]]?: (keyof TransformersObjects[K])[] - } - alwaysPresents: (keyof TransformersObjects[K])[] - } -} + [Key in keyof TransformersObjects[K]]?: (keyof TransformersObjects[K])[]; + }; + alwaysPresents: (keyof TransformersObjects[K])[]; + }; +}; /** @private This is subject to breaking changes without notices */ export type DesirableProperties = Exclude< @@ -912,24 +912,24 @@ export type DesirableProperties]['dependencies'] // Exclude the props that are always present | TransformersDesiredPropertiesMetadata[KeyByValue]['alwaysPresents'][number] -> +>; /** @private This is subject to breaking changes without notices */ export type DesiredPropertiesMapper = { - [Key in DesirableProperties]: boolean -} + [Key in DesirableProperties]: boolean; +}; -declare const TypeErrorSymbol: unique symbol +declare const TypeErrorSymbol: unique symbol; /** @private This is subject to breaking changes without notices */ export interface DesiredPropertiesError { - [TypeErrorSymbol]: T + [TypeErrorSymbol]: T; } /** @private This is subject to breaking changes without notices */ export type AreDependenciesSatisfied | undefined, TProps> = { - [K in keyof T]: IsKeyDesired extends true ? true : false -} + [K in keyof T]: IsKeyDesired extends true ? true : false; +}; /** @private This is subject to breaking changes without notices */ export type IsKeyDesired | undefined, TProps> = TProps extends never // If the props are never, all props are allowed @@ -950,7 +950,7 @@ export type IsKeyDesired | : // No, this is a key to not include DesiredPropertiesError<`This property depends on the following properties: ${JoinTuple[TKey], ', '>}. Not all of these props are set as desired in desiredProperties option in createBot(), so you can't use it. More info here: https://discordeno.js.org/desired-props`> : // No, we include it but it does not have neither props nor dependencies - true + true; /** The behavior it should be used when resolving an undesired property */ export enum DesiredPropertiesBehavior { @@ -967,7 +967,7 @@ export type RemoveKeyIfUndesired] > extends true ? Key - : never + : never; /** @private This is subject to breaking changes without notices */ export type GetErrorWhenUndesired< @@ -981,10 +981,10 @@ export type GetErrorWhenUndesired< TransformersDesiredPropertiesMetadata[KeyByValue]['dependencies'], TProps[KeyByValue] >, -> = TIsDesired extends true ? TransformProperty : TIsDesired +> = TIsDesired extends true ? TransformProperty : TIsDesired; /** @private This is subject to breaking changes without notices */ -export type IsObject = T extends object ? (T extends Function ? false : true) : false +export type IsObject = T extends object ? (T extends Function ? false : true) : false; // If the object is a transformed object, a collection of transformed object or an array of transformed objects we need to apply the desired props to them as well // NOTE: changing the order of these ternaries can cause bugs, for this reason we check in this order: @@ -1028,7 +1028,7 @@ export type TransformProperty } : // No, this is a normal value such as string / bigint / number - T + T; /** * Apply desired properties to an object. @@ -1047,17 +1047,17 @@ export type SetupDesiredProps< : Key]: // When the behavior is to change the type we use the GetErrorWhenUndesired type helper else apply the desired props to the key and return TBehavior extends DesiredPropertiesBehavior.ChangeType ? GetErrorWhenUndesired - : TransformProperty -} + : TransformProperty; +}; /** * The desired properties for each transformer object. */ export type TransformersDesiredProperties = { - [Key in keyof TransformersObjects]: DesiredPropertiesMapper -} + [Key in keyof TransformersObjects]: DesiredPropertiesMapper; +}; /** @private This is subject to breaking changes without notices */ export type CompleteDesiredProperties, TTDefault extends boolean = false> = { - [K in keyof TransformersDesiredProperties]: Complete & T[K], TTDefault> -} + [K in keyof TransformersDesiredProperties]: Complete & T[K], TTDefault>; +}; diff --git a/packages/bot/src/events.ts b/packages/bot/src/events.ts index 0369940fa..f22a42493 100644 --- a/packages/bot/src/events.ts +++ b/packages/bot/src/events.ts @@ -1,6 +1,6 @@ -import type { DiscordGatewayPayload, DiscordRateLimited, DiscordReady, DiscordVoiceChannelEffectAnimationType } from '@discordeno/types' -import type { Collection } from '@discordeno/utils' -import type { DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from './desiredProperties.js' +import type { DiscordGatewayPayload, DiscordRateLimited, DiscordReady, DiscordVoiceChannelEffectAnimationType } from '@discordeno/types'; +import type { Collection } from '@discordeno/utils'; +import type { DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from './desiredProperties.js'; import type { AuditLogEntry, AutoModerationActionExecution, @@ -24,142 +24,142 @@ import type { ThreadMember, User, VoiceState, -} from './transformers/types.js' +} from './transformers/types.js'; export type EventHandlers = { - applicationCommandPermissionsUpdate: (command: SetupDesiredProps) => unknown - guildAuditLogEntryCreate: (log: SetupDesiredProps, guildId: bigint) => unknown - automodRuleCreate: (rule: SetupDesiredProps) => unknown - automodRuleUpdate: (rule: SetupDesiredProps) => unknown - automodRuleDelete: (rule: SetupDesiredProps) => unknown - automodActionExecution: (payload: SetupDesiredProps) => unknown - threadCreate: (thread: SetupDesiredProps) => unknown - threadDelete: (thread: SetupDesiredProps) => unknown + applicationCommandPermissionsUpdate: (command: SetupDesiredProps) => unknown; + guildAuditLogEntryCreate: (log: SetupDesiredProps, guildId: bigint) => unknown; + automodRuleCreate: (rule: SetupDesiredProps) => unknown; + automodRuleUpdate: (rule: SetupDesiredProps) => unknown; + automodRuleDelete: (rule: SetupDesiredProps) => unknown; + automodActionExecution: (payload: SetupDesiredProps) => unknown; + threadCreate: (thread: SetupDesiredProps) => unknown; + threadDelete: (thread: SetupDesiredProps) => unknown; threadListSync: (payload: { - guildId: bigint - channelIds?: bigint[] - threads: SetupDesiredProps[] - members: SetupDesiredProps[] - }) => unknown - threadMemberUpdate: (payload: { id: bigint; guildId: bigint; joinedTimestamp: number; flags: number }) => unknown + guildId: bigint; + channelIds?: bigint[]; + threads: SetupDesiredProps[]; + members: SetupDesiredProps[]; + }) => unknown; + threadMemberUpdate: (payload: { id: bigint; guildId: bigint; joinedTimestamp: number; flags: number }) => unknown; threadMembersUpdate: (payload: { - id: bigint - guildId: bigint - addedMembers?: SetupDesiredProps[] - removedMemberIds?: bigint[] - }) => unknown - threadUpdate: (thread: SetupDesiredProps) => unknown - scheduledEventCreate: (event: SetupDesiredProps) => unknown - scheduledEventUpdate: (event: SetupDesiredProps) => unknown - scheduledEventDelete: (event: SetupDesiredProps) => unknown - scheduledEventUserAdd: (payload: { guildScheduledEventId: bigint; guildId: bigint; userId: bigint }) => unknown - scheduledEventUserRemove: (payload: { guildScheduledEventId: bigint; guildId: bigint; userId: bigint }) => unknown + id: bigint; + guildId: bigint; + addedMembers?: SetupDesiredProps[]; + removedMemberIds?: bigint[]; + }) => unknown; + threadUpdate: (thread: SetupDesiredProps) => unknown; + scheduledEventCreate: (event: SetupDesiredProps) => unknown; + scheduledEventUpdate: (event: SetupDesiredProps) => unknown; + scheduledEventDelete: (event: SetupDesiredProps) => unknown; + scheduledEventUserAdd: (payload: { guildScheduledEventId: bigint; guildId: bigint; userId: bigint }) => unknown; + scheduledEventUserRemove: (payload: { guildScheduledEventId: bigint; guildId: bigint; userId: bigint }) => unknown; ready: ( payload: { - shardId: number - v: number - user: SetupDesiredProps - guilds: bigint[] - sessionId: string - shard?: number[] - applicationId: bigint + shardId: number; + v: number; + user: SetupDesiredProps; + guilds: bigint[]; + sessionId: string; + shard?: number[]; + applicationId: bigint; }, rawPayload: DiscordReady, - ) => unknown - resumed: (shardId: number) => unknown - rateLimited: (data: DiscordRateLimited, shardId: number) => unknown - interactionCreate: (interaction: SetupDesiredProps) => unknown - integrationCreate: (integration: SetupDesiredProps) => unknown - integrationDelete: (payload: { id: bigint; guildId: bigint; applicationId?: bigint }) => unknown - integrationUpdate: (payload: { guildId: bigint }) => unknown - inviteCreate: (invite: SetupDesiredProps) => unknown - inviteDelete: (payload: { channelId: bigint; guildId?: bigint; code: string }) => unknown - guildMemberAdd: (member: SetupDesiredProps, user: SetupDesiredProps) => unknown - guildMemberRemove: (user: SetupDesiredProps, guildId: bigint) => unknown - guildMemberUpdate: (member: SetupDesiredProps, user: SetupDesiredProps) => unknown - guildStickersUpdate: (payload: { guildId: bigint; stickers: SetupDesiredProps[] }) => unknown - messageCreate: (message: SetupDesiredProps) => unknown - messageDelete: (payload: { id: bigint; channelId: bigint; guildId?: bigint }, message?: SetupDesiredProps) => unknown - messageDeleteBulk: (payload: { ids: bigint[]; channelId: bigint; guildId?: bigint }) => unknown - messageUpdate: (message: SetupDesiredProps) => unknown + ) => unknown; + resumed: (shardId: number) => unknown; + rateLimited: (data: DiscordRateLimited, shardId: number) => unknown; + interactionCreate: (interaction: SetupDesiredProps) => unknown; + integrationCreate: (integration: SetupDesiredProps) => unknown; + integrationDelete: (payload: { id: bigint; guildId: bigint; applicationId?: bigint }) => unknown; + integrationUpdate: (payload: { guildId: bigint }) => unknown; + inviteCreate: (invite: SetupDesiredProps) => unknown; + inviteDelete: (payload: { channelId: bigint; guildId?: bigint; code: string }) => unknown; + guildMemberAdd: (member: SetupDesiredProps, user: SetupDesiredProps) => unknown; + guildMemberRemove: (user: SetupDesiredProps, guildId: bigint) => unknown; + guildMemberUpdate: (member: SetupDesiredProps, user: SetupDesiredProps) => unknown; + guildStickersUpdate: (payload: { guildId: bigint; stickers: SetupDesiredProps[] }) => unknown; + messageCreate: (message: SetupDesiredProps) => unknown; + messageDelete: (payload: { id: bigint; channelId: bigint; guildId?: bigint }, message?: SetupDesiredProps) => unknown; + messageDeleteBulk: (payload: { ids: bigint[]; channelId: bigint; guildId?: bigint }) => unknown; + messageUpdate: (message: SetupDesiredProps) => unknown; reactionAdd: (payload: { - userId: bigint - channelId: bigint - messageId: bigint - guildId?: bigint - member?: SetupDesiredProps - user?: SetupDesiredProps - emoji: SetupDesiredProps - messageAuthorId?: bigint - burst: boolean - burstColors?: string[] - }) => unknown + userId: bigint; + channelId: bigint; + messageId: bigint; + guildId?: bigint; + member?: SetupDesiredProps; + user?: SetupDesiredProps; + emoji: SetupDesiredProps; + messageAuthorId?: bigint; + burst: boolean; + burstColors?: string[]; + }) => unknown; reactionRemove: (payload: { - userId: bigint - channelId: bigint - messageId: bigint - guildId?: bigint - emoji: SetupDesiredProps - burst: boolean - }) => unknown + userId: bigint; + channelId: bigint; + messageId: bigint; + guildId?: bigint; + emoji: SetupDesiredProps; + burst: boolean; + }) => unknown; reactionRemoveEmoji: (payload: { - channelId: bigint - messageId: bigint - guildId?: bigint - emoji: SetupDesiredProps - }) => unknown - reactionRemoveAll: (payload: { channelId: bigint; messageId: bigint; guildId?: bigint }) => unknown - presenceUpdate: (presence: SetupDesiredProps) => unknown + channelId: bigint; + messageId: bigint; + guildId?: bigint; + emoji: SetupDesiredProps; + }) => unknown; + reactionRemoveAll: (payload: { channelId: bigint; messageId: bigint; guildId?: bigint }) => unknown; + presenceUpdate: (presence: SetupDesiredProps) => unknown; voiceChannelEffectSend: (payload: { - channelId: bigint - guildId: bigint - userId: bigint - emoji?: SetupDesiredProps - animationType?: DiscordVoiceChannelEffectAnimationType - animationId?: number - soundId?: bigint | number - soundVolume?: number - }) => unknown - voiceServerUpdate: (payload: { token: string; endpoint?: string; guildId: bigint }) => unknown - voiceStateUpdate: (voiceState: SetupDesiredProps) => unknown - channelCreate: (channel: SetupDesiredProps) => unknown - dispatchRequirements: (data: DiscordGatewayPayload, shardId: number) => unknown - channelDelete: (channel: SetupDesiredProps) => unknown - channelPinsUpdate: (data: { guildId?: bigint; channelId: bigint; lastPinTimestamp?: number }) => unknown - channelUpdate: (channel: SetupDesiredProps) => unknown - stageInstanceCreate: (data: { id: bigint; guildId: bigint; channelId: bigint; topic: string }) => unknown - stageInstanceDelete: (data: { id: bigint; guildId: bigint; channelId: bigint; topic: string }) => unknown - stageInstanceUpdate: (data: { id: bigint; guildId: bigint; channelId: bigint; topic: string }) => unknown - guildEmojisUpdate: (payload: { guildId: bigint; emojis: Collection> }) => unknown - guildBanAdd: (user: SetupDesiredProps, guildId: bigint) => unknown - guildBanRemove: (user: SetupDesiredProps, guildId: bigint) => unknown - guildCreate: (guild: SetupDesiredProps) => unknown - guildDelete: (data: { id: bigint; unavailable: boolean }, shardId: number) => unknown - guildUpdate: (guild: SetupDesiredProps) => unknown - raw: (data: DiscordGatewayPayload, shardId: number) => unknown - roleCreate: (role: SetupDesiredProps) => unknown - roleDelete: (payload: { guildId: bigint; roleId: bigint }) => unknown - roleUpdate: (role: SetupDesiredProps) => unknown - webhooksUpdate: (payload: { channelId: bigint; guildId: bigint }) => unknown - botUpdate: (user: SetupDesiredProps) => unknown + channelId: bigint; + guildId: bigint; + userId: bigint; + emoji?: SetupDesiredProps; + animationType?: DiscordVoiceChannelEffectAnimationType; + animationId?: number; + soundId?: bigint | number; + soundVolume?: number; + }) => unknown; + voiceServerUpdate: (payload: { token: string; endpoint?: string; guildId: bigint }) => unknown; + voiceStateUpdate: (voiceState: SetupDesiredProps) => unknown; + channelCreate: (channel: SetupDesiredProps) => unknown; + dispatchRequirements: (data: DiscordGatewayPayload, shardId: number) => unknown; + channelDelete: (channel: SetupDesiredProps) => unknown; + channelPinsUpdate: (data: { guildId?: bigint; channelId: bigint; lastPinTimestamp?: number }) => unknown; + channelUpdate: (channel: SetupDesiredProps) => unknown; + stageInstanceCreate: (data: { id: bigint; guildId: bigint; channelId: bigint; topic: string }) => unknown; + stageInstanceDelete: (data: { id: bigint; guildId: bigint; channelId: bigint; topic: string }) => unknown; + stageInstanceUpdate: (data: { id: bigint; guildId: bigint; channelId: bigint; topic: string }) => unknown; + guildEmojisUpdate: (payload: { guildId: bigint; emojis: Collection> }) => unknown; + guildBanAdd: (user: SetupDesiredProps, guildId: bigint) => unknown; + guildBanRemove: (user: SetupDesiredProps, guildId: bigint) => unknown; + guildCreate: (guild: SetupDesiredProps) => unknown; + guildDelete: (data: { id: bigint; unavailable: boolean }, shardId: number) => unknown; + guildUpdate: (guild: SetupDesiredProps) => unknown; + raw: (data: DiscordGatewayPayload, shardId: number) => unknown; + roleCreate: (role: SetupDesiredProps) => unknown; + roleDelete: (payload: { guildId: bigint; roleId: bigint }) => unknown; + roleUpdate: (role: SetupDesiredProps) => unknown; + webhooksUpdate: (payload: { channelId: bigint; guildId: bigint }) => unknown; + botUpdate: (user: SetupDesiredProps) => unknown; typingStart: (payload: { - guildId: bigint | undefined - channelId: bigint - userId: bigint - timestamp: number - member: SetupDesiredProps | undefined - }) => unknown - entitlementCreate: (entitlement: SetupDesiredProps) => unknown - entitlementUpdate: (entitlement: SetupDesiredProps) => unknown - entitlementDelete: (entitlement: SetupDesiredProps) => unknown - subscriptionCreate: (subscription: SetupDesiredProps) => unknown - subscriptionUpdate: (subscription: SetupDesiredProps) => unknown - subscriptionDelete: (subscription: SetupDesiredProps) => unknown - messagePollVoteAdd: (payload: { userId: bigint; channelId: bigint; messageId: bigint; guildId?: bigint; answerId: number }) => unknown - messagePollVoteRemove: (payload: { userId: bigint; channelId: bigint; messageId: bigint; guildId?: bigint; answerId: number }) => unknown - soundboardSoundCreate: (payload: SetupDesiredProps) => unknown - soundboardSoundUpdate: (payload: SetupDesiredProps) => unknown - soundboardSoundDelete: (payload: { soundId: bigint; guildId: bigint }) => unknown - soundboardSoundsUpdate: (payload: { soundboardSounds: SetupDesiredProps[]; guildId: bigint }) => unknown - soundboardSounds: (payload: { soundboardSounds: SetupDesiredProps[]; guildId: bigint }) => unknown -} + guildId: bigint | undefined; + channelId: bigint; + userId: bigint; + timestamp: number; + member: SetupDesiredProps | undefined; + }) => unknown; + entitlementCreate: (entitlement: SetupDesiredProps) => unknown; + entitlementUpdate: (entitlement: SetupDesiredProps) => unknown; + entitlementDelete: (entitlement: SetupDesiredProps) => unknown; + subscriptionCreate: (subscription: SetupDesiredProps) => unknown; + subscriptionUpdate: (subscription: SetupDesiredProps) => unknown; + subscriptionDelete: (subscription: SetupDesiredProps) => unknown; + messagePollVoteAdd: (payload: { userId: bigint; channelId: bigint; messageId: bigint; guildId?: bigint; answerId: number }) => unknown; + messagePollVoteRemove: (payload: { userId: bigint; channelId: bigint; messageId: bigint; guildId?: bigint; answerId: number }) => unknown; + soundboardSoundCreate: (payload: SetupDesiredProps) => unknown; + soundboardSoundUpdate: (payload: SetupDesiredProps) => unknown; + soundboardSoundDelete: (payload: { soundId: bigint; guildId: bigint }) => unknown; + soundboardSoundsUpdate: (payload: { soundboardSounds: SetupDesiredProps[]; guildId: bigint }) => unknown; + soundboardSounds: (payload: { soundboardSounds: SetupDesiredProps[]; guildId: bigint }) => unknown; +}; diff --git a/packages/bot/src/handlers.ts b/packages/bot/src/handlers.ts index e55e3ab49..5fc4c6e85 100644 --- a/packages/bot/src/handlers.ts +++ b/packages/bot/src/handlers.ts @@ -1,12 +1,12 @@ -import type { DiscordGatewayPayload, GatewayDispatchEventNames } from '@discordeno/types' -import type { Bot } from './bot.js' -import type { DesiredPropertiesBehavior, TransformersDesiredProperties } from './desiredProperties.js' -import * as handlers from './handlers/index.js' +import type { DiscordGatewayPayload, GatewayDispatchEventNames } from '@discordeno/types'; +import type { Bot } from './bot.js'; +import type { DesiredPropertiesBehavior, TransformersDesiredProperties } from './desiredProperties.js'; +import * as handlers from './handlers/index.js'; export function createBotGatewayHandlers( options: Partial>, ): GatewayHandlers { - const _options = options as Partial> + const _options = options as Partial>; return { APPLICATION_COMMAND_PERMISSIONS_UPDATE: _options.APPLICATION_COMMAND_PERMISSIONS_UPDATE ?? handlers.handleApplicationCommandPermissionsUpdate, @@ -85,16 +85,16 @@ export function createBotGatewayHandlers as unknown as GatewayHandlers + } satisfies GatewayHandlers as unknown as GatewayHandlers; } export type GatewayHandlers = Record< GatewayDispatchEventNames, BotGatewayHandler -> +>; export type BotGatewayHandler = ( bot: Bot, data: DiscordGatewayPayload, shardId: number, -) => unknown +) => unknown; diff --git a/packages/bot/src/handlers/channels/CHANNEL_CREATE.ts b/packages/bot/src/handlers/channels/CHANNEL_CREATE.ts index 5f9115c56..ddc1f24ec 100644 --- a/packages/bot/src/handlers/channels/CHANNEL_CREATE.ts +++ b/packages/bot/src/handlers/channels/CHANNEL_CREATE.ts @@ -1,11 +1,11 @@ -import type { DiscordChannel, DiscordGatewayPayload } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordChannel, DiscordGatewayPayload } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleChannelCreate(bot: Bot, payload: DiscordGatewayPayload, _shardId: number): Promise { - if (!bot.events.channelCreate) return + if (!bot.events.channelCreate) return; - const data = payload.d as DiscordChannel - const channel = bot.transformers.channel(bot, data, { guildId: data.guild_id }) + const data = payload.d as DiscordChannel; + const channel = bot.transformers.channel(bot, data, { guildId: data.guild_id }); - bot.events.channelCreate(channel) + bot.events.channelCreate(channel); } diff --git a/packages/bot/src/handlers/channels/CHANNEL_DELETE.ts b/packages/bot/src/handlers/channels/CHANNEL_DELETE.ts index cbf477771..53891a1e2 100644 --- a/packages/bot/src/handlers/channels/CHANNEL_DELETE.ts +++ b/packages/bot/src/handlers/channels/CHANNEL_DELETE.ts @@ -1,10 +1,10 @@ -import type { DiscordChannel, DiscordGatewayPayload } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordChannel, DiscordGatewayPayload } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleChannelDelete(bot: Bot, data: DiscordGatewayPayload): Promise { - if (!bot.events.channelDelete) return + if (!bot.events.channelDelete) return; - const payload = data.d as DiscordChannel + const payload = data.d as DiscordChannel; - bot.events.channelDelete(bot.transformers.channel(bot, payload, { guildId: payload.guild_id })) + bot.events.channelDelete(bot.transformers.channel(bot, payload, { guildId: payload.guild_id })); } diff --git a/packages/bot/src/handlers/channels/CHANNEL_PINS_UPDATE.ts b/packages/bot/src/handlers/channels/CHANNEL_PINS_UPDATE.ts index e85131fd9..cf345b5c5 100644 --- a/packages/bot/src/handlers/channels/CHANNEL_PINS_UPDATE.ts +++ b/packages/bot/src/handlers/channels/CHANNEL_PINS_UPDATE.ts @@ -1,14 +1,14 @@ -import type { DiscordChannelPinsUpdate, DiscordGatewayPayload } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordChannelPinsUpdate, DiscordGatewayPayload } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleChannelPinsUpdate(bot: Bot, data: DiscordGatewayPayload): Promise { - if (!bot.events.channelPinsUpdate) return + if (!bot.events.channelPinsUpdate) return; - const payload = data.d as DiscordChannelPinsUpdate + const payload = data.d as DiscordChannelPinsUpdate; bot.events.channelPinsUpdate({ guildId: payload.guild_id ? bot.transformers.snowflake(payload.guild_id) : undefined, channelId: bot.transformers.snowflake(payload.channel_id), lastPinTimestamp: payload.last_pin_timestamp ? Date.parse(payload.last_pin_timestamp) : undefined, - }) + }); } diff --git a/packages/bot/src/handlers/channels/CHANNEL_UPDATE.ts b/packages/bot/src/handlers/channels/CHANNEL_UPDATE.ts index e787b10e7..942a9f219 100644 --- a/packages/bot/src/handlers/channels/CHANNEL_UPDATE.ts +++ b/packages/bot/src/handlers/channels/CHANNEL_UPDATE.ts @@ -1,11 +1,11 @@ -import type { DiscordChannel, DiscordGatewayPayload } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordChannel, DiscordGatewayPayload } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleChannelUpdate(bot: Bot, data: DiscordGatewayPayload): Promise { - if (!bot.events.channelUpdate) return + if (!bot.events.channelUpdate) return; - const payload = data.d as DiscordChannel - const channel = bot.transformers.channel(bot, payload) + const payload = data.d as DiscordChannel; + const channel = bot.transformers.channel(bot, payload); - bot.events.channelUpdate(channel) + bot.events.channelUpdate(channel); } diff --git a/packages/bot/src/handlers/channels/STAGE_INSTANCE_CREATE.ts b/packages/bot/src/handlers/channels/STAGE_INSTANCE_CREATE.ts index 13371637f..16df8f90d 100644 --- a/packages/bot/src/handlers/channels/STAGE_INSTANCE_CREATE.ts +++ b/packages/bot/src/handlers/channels/STAGE_INSTANCE_CREATE.ts @@ -1,15 +1,15 @@ -import type { DiscordGatewayPayload, DiscordStageInstance } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordGatewayPayload, DiscordStageInstance } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleStageInstanceCreate(bot: Bot, data: DiscordGatewayPayload): Promise { - if (!bot.events.stageInstanceCreate) return + if (!bot.events.stageInstanceCreate) return; - const payload = data.d as DiscordStageInstance + const payload = data.d as DiscordStageInstance; bot.events.stageInstanceCreate({ id: bot.transformers.snowflake(payload.id), guildId: bot.transformers.snowflake(payload.guild_id), channelId: bot.transformers.snowflake(payload.channel_id), topic: payload.topic, - }) + }); } diff --git a/packages/bot/src/handlers/channels/STAGE_INSTANCE_DELETE.ts b/packages/bot/src/handlers/channels/STAGE_INSTANCE_DELETE.ts index 85ffce523..39db4c8bd 100644 --- a/packages/bot/src/handlers/channels/STAGE_INSTANCE_DELETE.ts +++ b/packages/bot/src/handlers/channels/STAGE_INSTANCE_DELETE.ts @@ -1,15 +1,15 @@ -import type { DiscordGatewayPayload, DiscordStageInstance } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordGatewayPayload, DiscordStageInstance } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleStageInstanceDelete(bot: Bot, data: DiscordGatewayPayload): Promise { - if (!bot.events.stageInstanceDelete) return + if (!bot.events.stageInstanceDelete) return; - const payload = data.d as DiscordStageInstance + const payload = data.d as DiscordStageInstance; bot.events.stageInstanceDelete({ id: bot.transformers.snowflake(payload.id), guildId: bot.transformers.snowflake(payload.guild_id), channelId: bot.transformers.snowflake(payload.channel_id), topic: payload.topic, - }) + }); } diff --git a/packages/bot/src/handlers/channels/STAGE_INSTANCE_UPDATE.ts b/packages/bot/src/handlers/channels/STAGE_INSTANCE_UPDATE.ts index febad080b..814b4f115 100644 --- a/packages/bot/src/handlers/channels/STAGE_INSTANCE_UPDATE.ts +++ b/packages/bot/src/handlers/channels/STAGE_INSTANCE_UPDATE.ts @@ -1,15 +1,15 @@ -import type { DiscordGatewayPayload, DiscordStageInstance } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordGatewayPayload, DiscordStageInstance } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleStageInstanceUpdate(bot: Bot, data: DiscordGatewayPayload): Promise { - if (!bot.events.stageInstanceUpdate) return + if (!bot.events.stageInstanceUpdate) return; - const payload = data.d as DiscordStageInstance + const payload = data.d as DiscordStageInstance; bot.events.stageInstanceUpdate({ id: bot.transformers.snowflake(payload.id), guildId: bot.transformers.snowflake(payload.guild_id), channelId: bot.transformers.snowflake(payload.channel_id), topic: payload.topic, - }) + }); } diff --git a/packages/bot/src/handlers/channels/THREAD_CREATE.ts b/packages/bot/src/handlers/channels/THREAD_CREATE.ts index 5942694cd..c91f96ba7 100644 --- a/packages/bot/src/handlers/channels/THREAD_CREATE.ts +++ b/packages/bot/src/handlers/channels/THREAD_CREATE.ts @@ -1,10 +1,10 @@ -import type { DiscordChannel, DiscordGatewayPayload } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordChannel, DiscordGatewayPayload } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleThreadCreate(bot: Bot, data: DiscordGatewayPayload): Promise { - if (!bot.events.threadCreate) return + if (!bot.events.threadCreate) return; - const payload = data.d as DiscordChannel + const payload = data.d as DiscordChannel; - bot.events.threadCreate(bot.transformers.channel(bot, payload)) + bot.events.threadCreate(bot.transformers.channel(bot, payload)); } diff --git a/packages/bot/src/handlers/channels/THREAD_DELETE.ts b/packages/bot/src/handlers/channels/THREAD_DELETE.ts index 0aa66f008..d05da8f35 100644 --- a/packages/bot/src/handlers/channels/THREAD_DELETE.ts +++ b/packages/bot/src/handlers/channels/THREAD_DELETE.ts @@ -1,10 +1,10 @@ -import type { DiscordChannel, DiscordGatewayPayload } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordChannel, DiscordGatewayPayload } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleThreadDelete(bot: Bot, data: DiscordGatewayPayload): Promise { - if (!bot.events.threadDelete) return + if (!bot.events.threadDelete) return; - const payload = data.d as DiscordChannel + const payload = data.d as DiscordChannel; - bot.events.threadDelete(bot.transformers.channel(bot, payload)) + bot.events.threadDelete(bot.transformers.channel(bot, payload)); } diff --git a/packages/bot/src/handlers/channels/THREAD_LIST_SYNC.ts b/packages/bot/src/handlers/channels/THREAD_LIST_SYNC.ts index 49210d3d1..4ac4680b5 100644 --- a/packages/bot/src/handlers/channels/THREAD_LIST_SYNC.ts +++ b/packages/bot/src/handlers/channels/THREAD_LIST_SYNC.ts @@ -1,12 +1,12 @@ -import type { DiscordGatewayPayload, DiscordThreadListSync } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordGatewayPayload, DiscordThreadListSync } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleThreadListSync(bot: Bot, data: DiscordGatewayPayload): Promise { - if (!bot.events.threadListSync) return + if (!bot.events.threadListSync) return; - const payload = data.d as DiscordThreadListSync + const payload = data.d as DiscordThreadListSync; - const guildId = bot.transformers.snowflake(payload.guild_id) + const guildId = bot.transformers.snowflake(payload.guild_id); bot.events.threadListSync({ guildId, @@ -18,5 +18,5 @@ export async function handleThreadListSync(bot: Bot, data: DiscordGatewayPayload joinTimestamp: Date.parse(member.join_timestamp), flags: member.flags, })), - }) + }); } diff --git a/packages/bot/src/handlers/channels/THREAD_MEMBERS_UPDATE.ts b/packages/bot/src/handlers/channels/THREAD_MEMBERS_UPDATE.ts index 1b246df09..8d34b735d 100644 --- a/packages/bot/src/handlers/channels/THREAD_MEMBERS_UPDATE.ts +++ b/packages/bot/src/handlers/channels/THREAD_MEMBERS_UPDATE.ts @@ -1,15 +1,15 @@ -import type { DiscordGatewayPayload, DiscordThreadMembersUpdate } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordGatewayPayload, DiscordThreadMembersUpdate } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleThreadMembersUpdate(bot: Bot, data: DiscordGatewayPayload, _shardId: number): Promise { - if (!bot.events.threadMembersUpdate) return + if (!bot.events.threadMembersUpdate) return; - const payload = data.d as DiscordThreadMembersUpdate + const payload = data.d as DiscordThreadMembersUpdate; bot.events.threadMembersUpdate({ id: bot.transformers.snowflake(payload.id), guildId: bot.transformers.snowflake(payload.guild_id), addedMembers: payload.added_members?.map((member) => bot.transformers.threadMember(bot, member, { guildId: payload.guild_id })), removedMemberIds: payload.removed_member_ids?.map((id) => bot.transformers.snowflake(id)), - }) + }); } diff --git a/packages/bot/src/handlers/channels/THREAD_MEMBER_UPDATE.ts b/packages/bot/src/handlers/channels/THREAD_MEMBER_UPDATE.ts index 3591e299e..67d081c46 100644 --- a/packages/bot/src/handlers/channels/THREAD_MEMBER_UPDATE.ts +++ b/packages/bot/src/handlers/channels/THREAD_MEMBER_UPDATE.ts @@ -1,15 +1,15 @@ -import type { DiscordGatewayPayload, DiscordThreadMemberUpdate } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordGatewayPayload, DiscordThreadMemberUpdate } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleThreadMemberUpdate(bot: Bot, data: DiscordGatewayPayload, _shardId: number): Promise { - if (!bot.events.threadMemberUpdate) return + if (!bot.events.threadMemberUpdate) return; - const payload = data.d as DiscordThreadMemberUpdate + const payload = data.d as DiscordThreadMemberUpdate; bot.events.threadMemberUpdate({ id: bot.transformers.snowflake(payload.id), guildId: bot.transformers.snowflake(payload.guild_id), joinedTimestamp: Date.parse(payload.join_timestamp), flags: payload.flags, - }) + }); } diff --git a/packages/bot/src/handlers/channels/THREAD_UPDATE.ts b/packages/bot/src/handlers/channels/THREAD_UPDATE.ts index 2b5e0031c..5ef9da56c 100644 --- a/packages/bot/src/handlers/channels/THREAD_UPDATE.ts +++ b/packages/bot/src/handlers/channels/THREAD_UPDATE.ts @@ -1,10 +1,10 @@ -import type { DiscordChannel, DiscordGatewayPayload } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordChannel, DiscordGatewayPayload } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleThreadUpdate(bot: Bot, data: DiscordGatewayPayload): Promise { - if (!bot.events.threadUpdate) return + if (!bot.events.threadUpdate) return; - const payload = data.d as DiscordChannel + const payload = data.d as DiscordChannel; - bot.events.threadUpdate(bot.transformers.channel(bot, payload)) + bot.events.threadUpdate(bot.transformers.channel(bot, payload)); } diff --git a/packages/bot/src/handlers/channels/index.ts b/packages/bot/src/handlers/channels/index.ts index 5e61f52d1..cfdceab2a 100644 --- a/packages/bot/src/handlers/channels/index.ts +++ b/packages/bot/src/handlers/channels/index.ts @@ -1,13 +1,13 @@ -export * from './CHANNEL_CREATE.js' -export * from './CHANNEL_DELETE.js' -export * from './CHANNEL_PINS_UPDATE.js' -export * from './CHANNEL_UPDATE.js' -export * from './STAGE_INSTANCE_CREATE.js' -export * from './STAGE_INSTANCE_DELETE.js' -export * from './STAGE_INSTANCE_UPDATE.js' -export * from './THREAD_CREATE.js' -export * from './THREAD_DELETE.js' -export * from './THREAD_LIST_SYNC.js' -export * from './THREAD_MEMBER_UPDATE.js' -export * from './THREAD_MEMBERS_UPDATE.js' -export * from './THREAD_UPDATE.js' +export * from './CHANNEL_CREATE.js'; +export * from './CHANNEL_DELETE.js'; +export * from './CHANNEL_PINS_UPDATE.js'; +export * from './CHANNEL_UPDATE.js'; +export * from './STAGE_INSTANCE_CREATE.js'; +export * from './STAGE_INSTANCE_DELETE.js'; +export * from './STAGE_INSTANCE_UPDATE.js'; +export * from './THREAD_CREATE.js'; +export * from './THREAD_DELETE.js'; +export * from './THREAD_LIST_SYNC.js'; +export * from './THREAD_MEMBER_UPDATE.js'; +export * from './THREAD_MEMBERS_UPDATE.js'; +export * from './THREAD_UPDATE.js'; diff --git a/packages/bot/src/handlers/emojis/GUILD_EMOJIS_UPDATE.ts b/packages/bot/src/handlers/emojis/GUILD_EMOJIS_UPDATE.ts index 42869208f..24e1b4f5e 100644 --- a/packages/bot/src/handlers/emojis/GUILD_EMOJIS_UPDATE.ts +++ b/packages/bot/src/handlers/emojis/GUILD_EMOJIS_UPDATE.ts @@ -1,14 +1,14 @@ -import type { DiscordGatewayPayload, DiscordGuildEmojisUpdate } from '@discordeno/types' -import { Collection } from '@discordeno/utils' -import type { Bot } from '../../bot.js' +import type { DiscordGatewayPayload, DiscordGuildEmojisUpdate } from '@discordeno/types'; +import { Collection } from '@discordeno/utils'; +import type { Bot } from '../../bot.js'; export async function handleGuildEmojisUpdate(bot: Bot, data: DiscordGatewayPayload): Promise { - if (!bot.events.guildEmojisUpdate) return + if (!bot.events.guildEmojisUpdate) return; - const payload = data.d as DiscordGuildEmojisUpdate + const payload = data.d as DiscordGuildEmojisUpdate; bot.events.guildEmojisUpdate({ guildId: bot.transformers.snowflake(payload.guild_id), emojis: new Collection(payload.emojis.map((emoji) => [bot.transformers.snowflake(emoji.id!), bot.transformers.emoji(bot, emoji)])), - }) + }); } diff --git a/packages/bot/src/handlers/emojis/index.ts b/packages/bot/src/handlers/emojis/index.ts index f98466c7d..8a01f0aee 100644 --- a/packages/bot/src/handlers/emojis/index.ts +++ b/packages/bot/src/handlers/emojis/index.ts @@ -1 +1 @@ -export * from './GUILD_EMOJIS_UPDATE.js' +export * from './GUILD_EMOJIS_UPDATE.js'; diff --git a/packages/bot/src/handlers/entitlements/ENTITLEMENT_CREATE.ts b/packages/bot/src/handlers/entitlements/ENTITLEMENT_CREATE.ts index 24c701e2a..a19bd4fa9 100644 --- a/packages/bot/src/handlers/entitlements/ENTITLEMENT_CREATE.ts +++ b/packages/bot/src/handlers/entitlements/ENTITLEMENT_CREATE.ts @@ -1,9 +1,9 @@ -import type { DiscordEntitlement, DiscordGatewayPayload } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordEntitlement, DiscordGatewayPayload } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleEntitlementCreate(bot: Bot, data: DiscordGatewayPayload): Promise { - if (!bot.events.entitlementCreate) return + if (!bot.events.entitlementCreate) return; - const payload = data.d as DiscordEntitlement - bot.events.entitlementCreate(bot.transformers.entitlement(bot, payload)) + const payload = data.d as DiscordEntitlement; + bot.events.entitlementCreate(bot.transformers.entitlement(bot, payload)); } diff --git a/packages/bot/src/handlers/entitlements/ENTITLEMENT_DELETE.ts b/packages/bot/src/handlers/entitlements/ENTITLEMENT_DELETE.ts index 742296dfc..05fe5d074 100644 --- a/packages/bot/src/handlers/entitlements/ENTITLEMENT_DELETE.ts +++ b/packages/bot/src/handlers/entitlements/ENTITLEMENT_DELETE.ts @@ -1,9 +1,9 @@ -import type { DiscordEntitlement, DiscordGatewayPayload } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordEntitlement, DiscordGatewayPayload } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleEntitlementDelete(bot: Bot, data: DiscordGatewayPayload): Promise { - if (!bot.events.entitlementDelete) return + if (!bot.events.entitlementDelete) return; - const payload = data.d as DiscordEntitlement - bot.events.entitlementDelete(bot.transformers.entitlement(bot, payload)) + const payload = data.d as DiscordEntitlement; + bot.events.entitlementDelete(bot.transformers.entitlement(bot, payload)); } diff --git a/packages/bot/src/handlers/entitlements/ENTITLEMENT_UPDATE.ts b/packages/bot/src/handlers/entitlements/ENTITLEMENT_UPDATE.ts index fe9c764f4..b72200f2d 100644 --- a/packages/bot/src/handlers/entitlements/ENTITLEMENT_UPDATE.ts +++ b/packages/bot/src/handlers/entitlements/ENTITLEMENT_UPDATE.ts @@ -1,9 +1,9 @@ -import type { DiscordEntitlement, DiscordGatewayPayload } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordEntitlement, DiscordGatewayPayload } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleEntitlementUpdate(bot: Bot, data: DiscordGatewayPayload): Promise { - if (!bot.events.entitlementUpdate) return + if (!bot.events.entitlementUpdate) return; - const payload = data.d as DiscordEntitlement - bot.events.entitlementUpdate(bot.transformers.entitlement(bot, payload)) + const payload = data.d as DiscordEntitlement; + bot.events.entitlementUpdate(bot.transformers.entitlement(bot, payload)); } diff --git a/packages/bot/src/handlers/entitlements/index.ts b/packages/bot/src/handlers/entitlements/index.ts index 920971554..47f0f2d86 100644 --- a/packages/bot/src/handlers/entitlements/index.ts +++ b/packages/bot/src/handlers/entitlements/index.ts @@ -1,3 +1,3 @@ -export * from './ENTITLEMENT_CREATE.js' -export * from './ENTITLEMENT_DELETE.js' -export * from './ENTITLEMENT_UPDATE.js' +export * from './ENTITLEMENT_CREATE.js'; +export * from './ENTITLEMENT_DELETE.js'; +export * from './ENTITLEMENT_UPDATE.js'; diff --git a/packages/bot/src/handlers/guilds/GUILD_AUDIT_LOG_ENTRY_CREATE.ts b/packages/bot/src/handlers/guilds/GUILD_AUDIT_LOG_ENTRY_CREATE.ts index 7c058d881..90cf6bce9 100644 --- a/packages/bot/src/handlers/guilds/GUILD_AUDIT_LOG_ENTRY_CREATE.ts +++ b/packages/bot/src/handlers/guilds/GUILD_AUDIT_LOG_ENTRY_CREATE.ts @@ -1,10 +1,10 @@ -import type { DiscordAuditLogEntry, DiscordGatewayPayload } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordAuditLogEntry, DiscordGatewayPayload } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleGuildAuditLogEntryCreate(bot: Bot, data: DiscordGatewayPayload): Promise { - if (!bot.events.guildAuditLogEntryCreate) return + if (!bot.events.guildAuditLogEntryCreate) return; // TODO: better type here - const payload = data.d as DiscordAuditLogEntry & { guild_id: string } - bot.events.guildAuditLogEntryCreate(bot.transformers.auditLogEntry(bot, payload), bot.transformers.snowflake(payload.guild_id)) + const payload = data.d as DiscordAuditLogEntry & { guild_id: string }; + bot.events.guildAuditLogEntryCreate(bot.transformers.auditLogEntry(bot, payload), bot.transformers.snowflake(payload.guild_id)); } diff --git a/packages/bot/src/handlers/guilds/GUILD_BAN_ADD.ts b/packages/bot/src/handlers/guilds/GUILD_BAN_ADD.ts index 5e81c85b0..392685b70 100644 --- a/packages/bot/src/handlers/guilds/GUILD_BAN_ADD.ts +++ b/packages/bot/src/handlers/guilds/GUILD_BAN_ADD.ts @@ -1,9 +1,9 @@ -import type { DiscordGatewayPayload, DiscordGuildBanAddRemove } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordGatewayPayload, DiscordGuildBanAddRemove } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleGuildBanAdd(bot: Bot, data: DiscordGatewayPayload): Promise { - if (!bot.events.guildBanAdd) return + if (!bot.events.guildBanAdd) return; - const payload = data.d as DiscordGuildBanAddRemove - bot.events.guildBanAdd(bot.transformers.user(bot, payload.user), bot.transformers.snowflake(payload.guild_id)) + const payload = data.d as DiscordGuildBanAddRemove; + bot.events.guildBanAdd(bot.transformers.user(bot, payload.user), bot.transformers.snowflake(payload.guild_id)); } diff --git a/packages/bot/src/handlers/guilds/GUILD_BAN_REMOVE.ts b/packages/bot/src/handlers/guilds/GUILD_BAN_REMOVE.ts index 91d7488fd..be309e559 100644 --- a/packages/bot/src/handlers/guilds/GUILD_BAN_REMOVE.ts +++ b/packages/bot/src/handlers/guilds/GUILD_BAN_REMOVE.ts @@ -1,10 +1,10 @@ -import type { DiscordGatewayPayload, DiscordGuildBanAddRemove } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordGatewayPayload, DiscordGuildBanAddRemove } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleGuildBanRemove(bot: Bot, data: DiscordGatewayPayload): Promise { - if (!bot.events.guildBanRemove) return + if (!bot.events.guildBanRemove) return; - const payload = data.d as DiscordGuildBanAddRemove + const payload = data.d as DiscordGuildBanAddRemove; - await bot.events.guildBanRemove(bot.transformers.user(bot, payload.user), bot.transformers.snowflake(payload.guild_id)) + await bot.events.guildBanRemove(bot.transformers.user(bot, payload.user), bot.transformers.snowflake(payload.guild_id)); } diff --git a/packages/bot/src/handlers/guilds/GUILD_CREATE.ts b/packages/bot/src/handlers/guilds/GUILD_CREATE.ts index aad323629..f07ea89e1 100644 --- a/packages/bot/src/handlers/guilds/GUILD_CREATE.ts +++ b/packages/bot/src/handlers/guilds/GUILD_CREATE.ts @@ -1,9 +1,9 @@ -import type { DiscordGatewayPayload, DiscordGuild } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordGatewayPayload, DiscordGuild } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleGuildCreate(bot: Bot, data: DiscordGatewayPayload, shardId: number): Promise { - if (!bot.events.guildCreate) return + if (!bot.events.guildCreate) return; - const payload = data.d as DiscordGuild - bot.events.guildCreate(bot.transformers.guild(bot, payload, { shardId })) + const payload = data.d as DiscordGuild; + bot.events.guildCreate(bot.transformers.guild(bot, payload, { shardId })); } diff --git a/packages/bot/src/handlers/guilds/GUILD_DELETE.ts b/packages/bot/src/handlers/guilds/GUILD_DELETE.ts index 9c540955a..4d068f141 100644 --- a/packages/bot/src/handlers/guilds/GUILD_DELETE.ts +++ b/packages/bot/src/handlers/guilds/GUILD_DELETE.ts @@ -1,10 +1,10 @@ -import type { DiscordGatewayPayload, DiscordUnavailableGuild } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordGatewayPayload, DiscordUnavailableGuild } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleGuildDelete(bot: Bot, data: DiscordGatewayPayload, shardId: number): Promise { - if (!bot.events.guildDelete) return + if (!bot.events.guildDelete) return; - const payload = data.d as DiscordUnavailableGuild + const payload = data.d as DiscordUnavailableGuild; bot.events.guildDelete( { @@ -12,5 +12,5 @@ export async function handleGuildDelete(bot: Bot, data: DiscordGatewayPayload, s unavailable: payload.unavailable ?? false, }, shardId, - ) + ); } diff --git a/packages/bot/src/handlers/guilds/GUILD_INTEGRATIONS_UPDATE.ts b/packages/bot/src/handlers/guilds/GUILD_INTEGRATIONS_UPDATE.ts index b40cd8928..0e23b72ef 100644 --- a/packages/bot/src/handlers/guilds/GUILD_INTEGRATIONS_UPDATE.ts +++ b/packages/bot/src/handlers/guilds/GUILD_INTEGRATIONS_UPDATE.ts @@ -1,12 +1,12 @@ -import type { DiscordGatewayPayload, DiscordGuildIntegrationsUpdate } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordGatewayPayload, DiscordGuildIntegrationsUpdate } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleGuildIntegrationsUpdate(bot: Bot, data: DiscordGatewayPayload): Promise { - if (!bot.events.integrationUpdate) return + if (!bot.events.integrationUpdate) return; - const payload = data.d as DiscordGuildIntegrationsUpdate + const payload = data.d as DiscordGuildIntegrationsUpdate; bot.events.integrationUpdate({ guildId: bot.transformers.snowflake(payload.guild_id), - }) + }); } diff --git a/packages/bot/src/handlers/guilds/GUILD_STICKERS_UPDATE.ts b/packages/bot/src/handlers/guilds/GUILD_STICKERS_UPDATE.ts index d03cc3a13..ab3f14ca1 100644 --- a/packages/bot/src/handlers/guilds/GUILD_STICKERS_UPDATE.ts +++ b/packages/bot/src/handlers/guilds/GUILD_STICKERS_UPDATE.ts @@ -1,16 +1,16 @@ -import type { DiscordGatewayPayload, DiscordGuildStickersUpdate } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordGatewayPayload, DiscordGuildStickersUpdate } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleGuildStickersUpdate(bot: Bot, data: DiscordGatewayPayload, _shardId: number): Promise { - if (!bot.events.guildStickersUpdate) return + if (!bot.events.guildStickersUpdate) return; - const payload = data.d as DiscordGuildStickersUpdate + const payload = data.d as DiscordGuildStickersUpdate; bot.events.guildStickersUpdate({ guildId: bot.transformers.snowflake(payload.guild_id), stickers: payload.stickers.map((sticker) => { - sticker.guild_id = payload.guild_id - return bot.transformers.sticker(bot, sticker) + sticker.guild_id = payload.guild_id; + return bot.transformers.sticker(bot, sticker); }), - }) + }); } diff --git a/packages/bot/src/handlers/guilds/GUILD_UPDATE.ts b/packages/bot/src/handlers/guilds/GUILD_UPDATE.ts index 18fe12855..7e42ce17a 100644 --- a/packages/bot/src/handlers/guilds/GUILD_UPDATE.ts +++ b/packages/bot/src/handlers/guilds/GUILD_UPDATE.ts @@ -1,10 +1,10 @@ -import type { DiscordGatewayPayload, DiscordGuild } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordGatewayPayload, DiscordGuild } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleGuildUpdate(bot: Bot, data: DiscordGatewayPayload, shardId: number): Promise { - if (!bot.events.guildUpdate) return + if (!bot.events.guildUpdate) return; - const payload = data.d as DiscordGuild + const payload = data.d as DiscordGuild; - bot.events.guildUpdate(bot.transformers.guild(bot, payload, { shardId })) + bot.events.guildUpdate(bot.transformers.guild(bot, payload, { shardId })); } diff --git a/packages/bot/src/handlers/guilds/automod/AUTO_MODERATION_ACTION_EXECUTION.ts b/packages/bot/src/handlers/guilds/automod/AUTO_MODERATION_ACTION_EXECUTION.ts index ad153f126..776466c88 100644 --- a/packages/bot/src/handlers/guilds/automod/AUTO_MODERATION_ACTION_EXECUTION.ts +++ b/packages/bot/src/handlers/guilds/automod/AUTO_MODERATION_ACTION_EXECUTION.ts @@ -1,10 +1,10 @@ -import type { DiscordAutoModerationActionExecution, DiscordGatewayPayload } from '@discordeno/types' -import type { Bot } from '../../../bot.js' +import type { DiscordAutoModerationActionExecution, DiscordGatewayPayload } from '@discordeno/types'; +import type { Bot } from '../../../bot.js'; /** Requires the MANAGE_GUILD permission. */ export async function handleAutoModerationActionExecution(bot: Bot, data: DiscordGatewayPayload, _shardId: number): Promise { - if (!bot.events.automodActionExecution) return + if (!bot.events.automodActionExecution) return; - const payload = data.d as DiscordAutoModerationActionExecution - bot.events.automodActionExecution(bot.transformers.automodActionExecution(bot, payload)) + const payload = data.d as DiscordAutoModerationActionExecution; + bot.events.automodActionExecution(bot.transformers.automodActionExecution(bot, payload)); } diff --git a/packages/bot/src/handlers/guilds/automod/AUTO_MODERATION_RULE_CREATE.ts b/packages/bot/src/handlers/guilds/automod/AUTO_MODERATION_RULE_CREATE.ts index 56b8307a6..3abe3c7aa 100644 --- a/packages/bot/src/handlers/guilds/automod/AUTO_MODERATION_RULE_CREATE.ts +++ b/packages/bot/src/handlers/guilds/automod/AUTO_MODERATION_RULE_CREATE.ts @@ -1,10 +1,10 @@ -import type { DiscordAutoModerationRule, DiscordGatewayPayload } from '@discordeno/types' -import type { Bot } from '../../../bot.js' +import type { DiscordAutoModerationRule, DiscordGatewayPayload } from '@discordeno/types'; +import type { Bot } from '../../../bot.js'; /** Requires the MANAGE_GUILD permission. */ export async function handleAutoModerationRuleCreate(bot: Bot, data: DiscordGatewayPayload, _shardId: number): Promise { - if (!bot.events.automodRuleCreate) return + if (!bot.events.automodRuleCreate) return; - const payload = data.d as DiscordAutoModerationRule - bot.events.automodRuleCreate(bot.transformers.automodRule(bot, payload)) + const payload = data.d as DiscordAutoModerationRule; + bot.events.automodRuleCreate(bot.transformers.automodRule(bot, payload)); } diff --git a/packages/bot/src/handlers/guilds/automod/AUTO_MODERATION_RULE_DELETE.ts b/packages/bot/src/handlers/guilds/automod/AUTO_MODERATION_RULE_DELETE.ts index 1b32764da..076ef4211 100644 --- a/packages/bot/src/handlers/guilds/automod/AUTO_MODERATION_RULE_DELETE.ts +++ b/packages/bot/src/handlers/guilds/automod/AUTO_MODERATION_RULE_DELETE.ts @@ -1,10 +1,10 @@ -import type { DiscordAutoModerationRule, DiscordGatewayPayload } from '@discordeno/types' -import type { Bot } from '../../../bot.js' +import type { DiscordAutoModerationRule, DiscordGatewayPayload } from '@discordeno/types'; +import type { Bot } from '../../../bot.js'; /** Requires the MANAGE_GUILD permission. */ export async function handleAutoModerationRuleDelete(bot: Bot, data: DiscordGatewayPayload, _shardId: number): Promise { - if (!bot.events.automodRuleDelete) return + if (!bot.events.automodRuleDelete) return; - const payload = data.d as DiscordAutoModerationRule - bot.events.automodRuleDelete(bot.transformers.automodRule(bot, payload)) + const payload = data.d as DiscordAutoModerationRule; + bot.events.automodRuleDelete(bot.transformers.automodRule(bot, payload)); } diff --git a/packages/bot/src/handlers/guilds/automod/AUTO_MODERATION_RULE_UPDATE.ts b/packages/bot/src/handlers/guilds/automod/AUTO_MODERATION_RULE_UPDATE.ts index 8e84211cf..74d9b40bd 100644 --- a/packages/bot/src/handlers/guilds/automod/AUTO_MODERATION_RULE_UPDATE.ts +++ b/packages/bot/src/handlers/guilds/automod/AUTO_MODERATION_RULE_UPDATE.ts @@ -1,10 +1,10 @@ -import type { DiscordAutoModerationRule, DiscordGatewayPayload } from '@discordeno/types' -import type { Bot } from '../../../bot.js' +import type { DiscordAutoModerationRule, DiscordGatewayPayload } from '@discordeno/types'; +import type { Bot } from '../../../bot.js'; /** Requires the MANAGE_GUILD permission. */ export async function handleAutoModerationRuleUpdate(bot: Bot, data: DiscordGatewayPayload, _shardId: number): Promise { - if (!bot.events.automodRuleUpdate) return + if (!bot.events.automodRuleUpdate) return; - const payload = data.d as DiscordAutoModerationRule - bot.events.automodRuleUpdate(bot.transformers.automodRule(bot, payload)) + const payload = data.d as DiscordAutoModerationRule; + bot.events.automodRuleUpdate(bot.transformers.automodRule(bot, payload)); } diff --git a/packages/bot/src/handlers/guilds/automod/index.ts b/packages/bot/src/handlers/guilds/automod/index.ts index c47db435f..44694afae 100644 --- a/packages/bot/src/handlers/guilds/automod/index.ts +++ b/packages/bot/src/handlers/guilds/automod/index.ts @@ -1,4 +1,4 @@ -export * from './AUTO_MODERATION_ACTION_EXECUTION.js' -export * from './AUTO_MODERATION_RULE_CREATE.js' -export * from './AUTO_MODERATION_RULE_DELETE.js' -export * from './AUTO_MODERATION_RULE_UPDATE.js' +export * from './AUTO_MODERATION_ACTION_EXECUTION.js'; +export * from './AUTO_MODERATION_RULE_CREATE.js'; +export * from './AUTO_MODERATION_RULE_DELETE.js'; +export * from './AUTO_MODERATION_RULE_UPDATE.js'; diff --git a/packages/bot/src/handlers/guilds/index.ts b/packages/bot/src/handlers/guilds/index.ts index a67ad513b..4c5341e58 100644 --- a/packages/bot/src/handlers/guilds/index.ts +++ b/packages/bot/src/handlers/guilds/index.ts @@ -1,10 +1,10 @@ -export * from './automod/index.js' -export * from './GUILD_AUDIT_LOG_ENTRY_CREATE.js' -export * from './GUILD_BAN_ADD.js' -export * from './GUILD_BAN_REMOVE.js' -export * from './GUILD_CREATE.js' -export * from './GUILD_DELETE.js' -export * from './GUILD_INTEGRATIONS_UPDATE.js' -export * from './GUILD_STICKERS_UPDATE.js' -export * from './GUILD_UPDATE.js' -export * from './scheduledEvents/index.js' +export * from './automod/index.js'; +export * from './GUILD_AUDIT_LOG_ENTRY_CREATE.js'; +export * from './GUILD_BAN_ADD.js'; +export * from './GUILD_BAN_REMOVE.js'; +export * from './GUILD_CREATE.js'; +export * from './GUILD_DELETE.js'; +export * from './GUILD_INTEGRATIONS_UPDATE.js'; +export * from './GUILD_STICKERS_UPDATE.js'; +export * from './GUILD_UPDATE.js'; +export * from './scheduledEvents/index.js'; diff --git a/packages/bot/src/handlers/guilds/scheduledEvents/GUILD_SCHEDULED_EVENT_CREATE.ts b/packages/bot/src/handlers/guilds/scheduledEvents/GUILD_SCHEDULED_EVENT_CREATE.ts index 2e63d7c96..766c8a33d 100644 --- a/packages/bot/src/handlers/guilds/scheduledEvents/GUILD_SCHEDULED_EVENT_CREATE.ts +++ b/packages/bot/src/handlers/guilds/scheduledEvents/GUILD_SCHEDULED_EVENT_CREATE.ts @@ -1,9 +1,9 @@ -import type { DiscordGatewayPayload, DiscordScheduledEvent } from '@discordeno/types' -import type { Bot } from '../../../bot.js' +import type { DiscordGatewayPayload, DiscordScheduledEvent } from '@discordeno/types'; +import type { Bot } from '../../../bot.js'; export async function handleGuildScheduledEventCreate(bot: Bot, data: DiscordGatewayPayload, _shardId: number): Promise { - if (!bot.events.scheduledEventCreate) return + if (!bot.events.scheduledEventCreate) return; - const payload = data.d as DiscordScheduledEvent - bot.events.scheduledEventCreate(bot.transformers.scheduledEvent(bot, payload)) + const payload = data.d as DiscordScheduledEvent; + bot.events.scheduledEventCreate(bot.transformers.scheduledEvent(bot, payload)); } diff --git a/packages/bot/src/handlers/guilds/scheduledEvents/GUILD_SCHEDULED_EVENT_DELETE.ts b/packages/bot/src/handlers/guilds/scheduledEvents/GUILD_SCHEDULED_EVENT_DELETE.ts index ea51d6bac..7f70b4f12 100644 --- a/packages/bot/src/handlers/guilds/scheduledEvents/GUILD_SCHEDULED_EVENT_DELETE.ts +++ b/packages/bot/src/handlers/guilds/scheduledEvents/GUILD_SCHEDULED_EVENT_DELETE.ts @@ -1,9 +1,9 @@ -import type { DiscordGatewayPayload, DiscordScheduledEvent } from '@discordeno/types' -import type { Bot } from '../../../bot.js' +import type { DiscordGatewayPayload, DiscordScheduledEvent } from '@discordeno/types'; +import type { Bot } from '../../../bot.js'; export async function handleGuildScheduledEventDelete(bot: Bot, data: DiscordGatewayPayload): Promise { - if (!bot.events.scheduledEventDelete) return + if (!bot.events.scheduledEventDelete) return; - const payload = data.d as DiscordScheduledEvent - bot.events.scheduledEventDelete(bot.transformers.scheduledEvent(bot, payload)) + const payload = data.d as DiscordScheduledEvent; + bot.events.scheduledEventDelete(bot.transformers.scheduledEvent(bot, payload)); } diff --git a/packages/bot/src/handlers/guilds/scheduledEvents/GUILD_SCHEDULED_EVENT_UPDATE.ts b/packages/bot/src/handlers/guilds/scheduledEvents/GUILD_SCHEDULED_EVENT_UPDATE.ts index 3dac5cf3d..f193a39eb 100644 --- a/packages/bot/src/handlers/guilds/scheduledEvents/GUILD_SCHEDULED_EVENT_UPDATE.ts +++ b/packages/bot/src/handlers/guilds/scheduledEvents/GUILD_SCHEDULED_EVENT_UPDATE.ts @@ -1,9 +1,9 @@ -import type { DiscordGatewayPayload, DiscordScheduledEvent } from '@discordeno/types' -import type { Bot } from '../../../bot.js' +import type { DiscordGatewayPayload, DiscordScheduledEvent } from '@discordeno/types'; +import type { Bot } from '../../../bot.js'; export async function handleGuildScheduledEventUpdate(bot: Bot, data: DiscordGatewayPayload): Promise { - if (!bot.events.scheduledEventUpdate) return + if (!bot.events.scheduledEventUpdate) return; - const payload = data.d as DiscordScheduledEvent - bot.events.scheduledEventUpdate(bot.transformers.scheduledEvent(bot, payload)) + const payload = data.d as DiscordScheduledEvent; + bot.events.scheduledEventUpdate(bot.transformers.scheduledEvent(bot, payload)); } diff --git a/packages/bot/src/handlers/guilds/scheduledEvents/GUILD_SCHEDULED_EVENT_USER_ADD.ts b/packages/bot/src/handlers/guilds/scheduledEvents/GUILD_SCHEDULED_EVENT_USER_ADD.ts index 0d8395458..d7ac08876 100644 --- a/packages/bot/src/handlers/guilds/scheduledEvents/GUILD_SCHEDULED_EVENT_USER_ADD.ts +++ b/packages/bot/src/handlers/guilds/scheduledEvents/GUILD_SCHEDULED_EVENT_USER_ADD.ts @@ -1,14 +1,14 @@ -import type { DiscordGatewayPayload, DiscordScheduledEventUserAdd } from '@discordeno/types' -import type { Bot } from '../../../bot.js' +import type { DiscordGatewayPayload, DiscordScheduledEventUserAdd } from '@discordeno/types'; +import type { Bot } from '../../../bot.js'; export async function handleGuildScheduledEventUserAdd(bot: Bot, data: DiscordGatewayPayload): Promise { - if (!bot.events.scheduledEventUserAdd) return + if (!bot.events.scheduledEventUserAdd) return; - const payload = data.d as DiscordScheduledEventUserAdd + const payload = data.d as DiscordScheduledEventUserAdd; bot.events.scheduledEventUserAdd({ guildScheduledEventId: bot.transformers.snowflake(payload.guild_scheduled_event_id), userId: bot.transformers.snowflake(payload.user_id), guildId: bot.transformers.snowflake(payload.guild_id), - }) + }); } diff --git a/packages/bot/src/handlers/guilds/scheduledEvents/GUILD_SCHEDULED_EVENT_USER_REMOVE.ts b/packages/bot/src/handlers/guilds/scheduledEvents/GUILD_SCHEDULED_EVENT_USER_REMOVE.ts index 0fe50d865..e2b011079 100644 --- a/packages/bot/src/handlers/guilds/scheduledEvents/GUILD_SCHEDULED_EVENT_USER_REMOVE.ts +++ b/packages/bot/src/handlers/guilds/scheduledEvents/GUILD_SCHEDULED_EVENT_USER_REMOVE.ts @@ -1,14 +1,14 @@ -import type { DiscordGatewayPayload, DiscordScheduledEventUserRemove } from '@discordeno/types' -import type { Bot } from '../../../bot.js' +import type { DiscordGatewayPayload, DiscordScheduledEventUserRemove } from '@discordeno/types'; +import type { Bot } from '../../../bot.js'; export async function handleGuildScheduledEventUserRemove(bot: Bot, data: DiscordGatewayPayload): Promise { - if (!bot.events.scheduledEventUserRemove) return + if (!bot.events.scheduledEventUserRemove) return; - const payload = data.d as DiscordScheduledEventUserRemove + const payload = data.d as DiscordScheduledEventUserRemove; bot.events.scheduledEventUserRemove({ guildScheduledEventId: bot.transformers.snowflake(payload.guild_scheduled_event_id), userId: bot.transformers.snowflake(payload.user_id), guildId: bot.transformers.snowflake(payload.guild_id), - }) + }); } diff --git a/packages/bot/src/handlers/guilds/scheduledEvents/index.ts b/packages/bot/src/handlers/guilds/scheduledEvents/index.ts index 7c4d5397a..27c7048f9 100644 --- a/packages/bot/src/handlers/guilds/scheduledEvents/index.ts +++ b/packages/bot/src/handlers/guilds/scheduledEvents/index.ts @@ -1,5 +1,5 @@ -export * from './GUILD_SCHEDULED_EVENT_CREATE.js' -export * from './GUILD_SCHEDULED_EVENT_DELETE.js' -export * from './GUILD_SCHEDULED_EVENT_UPDATE.js' -export * from './GUILD_SCHEDULED_EVENT_USER_ADD.js' -export * from './GUILD_SCHEDULED_EVENT_USER_REMOVE.js' +export * from './GUILD_SCHEDULED_EVENT_CREATE.js'; +export * from './GUILD_SCHEDULED_EVENT_DELETE.js'; +export * from './GUILD_SCHEDULED_EVENT_UPDATE.js'; +export * from './GUILD_SCHEDULED_EVENT_USER_ADD.js'; +export * from './GUILD_SCHEDULED_EVENT_USER_REMOVE.js'; diff --git a/packages/bot/src/handlers/index.ts b/packages/bot/src/handlers/index.ts index cac7dbfaa..c919559a1 100644 --- a/packages/bot/src/handlers/index.ts +++ b/packages/bot/src/handlers/index.ts @@ -1,16 +1,16 @@ -export * from './channels/index.js' -export * from './emojis/index.js' -export * from './entitlements/index.js' -export * from './guilds/index.js' -export * from './integrations/index.js' -export * from './interactions/index.js' -export * from './invites/index.js' -export * from './members/index.js' -export * from './messages/index.js' -export * from './misc/index.js' -export * from './poll/index.js' -export * from './roles/index.js' -export * from './soundboard/index.js' -export * from './subscriptions/index.js' -export * from './voice/index.js' -export * from './webhooks/index.js' +export * from './channels/index.js'; +export * from './emojis/index.js'; +export * from './entitlements/index.js'; +export * from './guilds/index.js'; +export * from './integrations/index.js'; +export * from './interactions/index.js'; +export * from './invites/index.js'; +export * from './members/index.js'; +export * from './messages/index.js'; +export * from './misc/index.js'; +export * from './poll/index.js'; +export * from './roles/index.js'; +export * from './soundboard/index.js'; +export * from './subscriptions/index.js'; +export * from './voice/index.js'; +export * from './webhooks/index.js'; diff --git a/packages/bot/src/handlers/integrations/INTEGRATION_CREATE.ts b/packages/bot/src/handlers/integrations/INTEGRATION_CREATE.ts index 4f804e96e..599d62efa 100644 --- a/packages/bot/src/handlers/integrations/INTEGRATION_CREATE.ts +++ b/packages/bot/src/handlers/integrations/INTEGRATION_CREATE.ts @@ -1,8 +1,8 @@ -import type { DiscordGatewayPayload, DiscordIntegrationCreateUpdate } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordGatewayPayload, DiscordIntegrationCreateUpdate } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleIntegrationCreate(bot: Bot, data: DiscordGatewayPayload): Promise { - if (!bot.events.integrationCreate) return + if (!bot.events.integrationCreate) return; - bot.events.integrationCreate(bot.transformers.integration(bot, data.d as DiscordIntegrationCreateUpdate)) + bot.events.integrationCreate(bot.transformers.integration(bot, data.d as DiscordIntegrationCreateUpdate)); } diff --git a/packages/bot/src/handlers/integrations/INTEGRATION_DELETE.ts b/packages/bot/src/handlers/integrations/INTEGRATION_DELETE.ts index 6eb85be96..4aa62b0cb 100644 --- a/packages/bot/src/handlers/integrations/INTEGRATION_DELETE.ts +++ b/packages/bot/src/handlers/integrations/INTEGRATION_DELETE.ts @@ -1,14 +1,14 @@ -import type { DiscordGatewayPayload, DiscordIntegrationDelete } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordGatewayPayload, DiscordIntegrationDelete } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleIntegrationDelete(bot: Bot, data: DiscordGatewayPayload): Promise { - if (!bot.events.integrationDelete) return + if (!bot.events.integrationDelete) return; - const payload = data.d as DiscordIntegrationDelete + const payload = data.d as DiscordIntegrationDelete; bot.events.integrationDelete({ id: bot.transformers.snowflake(payload.id), guildId: bot.transformers.snowflake(payload.guild_id), applicationId: payload.application_id ? bot.transformers.snowflake(payload.application_id) : undefined, - }) + }); } diff --git a/packages/bot/src/handlers/integrations/INTEGRATION_UPDATE.ts b/packages/bot/src/handlers/integrations/INTEGRATION_UPDATE.ts index 534999bba..f75554329 100644 --- a/packages/bot/src/handlers/integrations/INTEGRATION_UPDATE.ts +++ b/packages/bot/src/handlers/integrations/INTEGRATION_UPDATE.ts @@ -1,8 +1,8 @@ -import type { DiscordGatewayPayload, DiscordIntegrationCreateUpdate } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordGatewayPayload, DiscordIntegrationCreateUpdate } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleIntegrationUpdate(bot: Bot, data: DiscordGatewayPayload): Promise { - if (!bot.events.integrationUpdate) return + if (!bot.events.integrationUpdate) return; - bot.events.integrationUpdate(bot.transformers.integration(bot, data.d as DiscordIntegrationCreateUpdate)) + bot.events.integrationUpdate(bot.transformers.integration(bot, data.d as DiscordIntegrationCreateUpdate)); } diff --git a/packages/bot/src/handlers/integrations/index.ts b/packages/bot/src/handlers/integrations/index.ts index 9cffc13bd..efcbdc49c 100644 --- a/packages/bot/src/handlers/integrations/index.ts +++ b/packages/bot/src/handlers/integrations/index.ts @@ -1,3 +1,3 @@ -export * from './INTEGRATION_CREATE.js' -export * from './INTEGRATION_DELETE.js' -export * from './INTEGRATION_UPDATE.js' +export * from './INTEGRATION_CREATE.js'; +export * from './INTEGRATION_DELETE.js'; +export * from './INTEGRATION_UPDATE.js'; diff --git a/packages/bot/src/handlers/interactions/APPLICATION_COMMAND_PERMISSIONS_UPDATE.ts b/packages/bot/src/handlers/interactions/APPLICATION_COMMAND_PERMISSIONS_UPDATE.ts index 3c3a19ab7..c3d21bb3e 100644 --- a/packages/bot/src/handlers/interactions/APPLICATION_COMMAND_PERMISSIONS_UPDATE.ts +++ b/packages/bot/src/handlers/interactions/APPLICATION_COMMAND_PERMISSIONS_UPDATE.ts @@ -1,9 +1,9 @@ -import type { DiscordGatewayPayload, DiscordGuildApplicationCommandPermissions } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordGatewayPayload, DiscordGuildApplicationCommandPermissions } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleApplicationCommandPermissionsUpdate(bot: Bot, data: DiscordGatewayPayload, _shardId: number): Promise { - if (!bot.events.applicationCommandPermissionsUpdate) return + if (!bot.events.applicationCommandPermissionsUpdate) return; - const payload = data.d as DiscordGuildApplicationCommandPermissions - bot.events.applicationCommandPermissionsUpdate(bot.transformers.applicationCommandPermission(bot, payload)) + const payload = data.d as DiscordGuildApplicationCommandPermissions; + bot.events.applicationCommandPermissionsUpdate(bot.transformers.applicationCommandPermission(bot, payload)); } diff --git a/packages/bot/src/handlers/interactions/INTERACTION_CREATE.ts b/packages/bot/src/handlers/interactions/INTERACTION_CREATE.ts index a3083640f..83eaaeebc 100644 --- a/packages/bot/src/handlers/interactions/INTERACTION_CREATE.ts +++ b/packages/bot/src/handlers/interactions/INTERACTION_CREATE.ts @@ -1,10 +1,10 @@ -import type { DiscordGatewayPayload, DiscordInteraction } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordGatewayPayload, DiscordInteraction } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleInteractionCreate(bot: Bot, data: DiscordGatewayPayload, shardId: number): Promise { - if (!bot.events.interactionCreate) return + if (!bot.events.interactionCreate) return; - const payload = data.d as DiscordInteraction + const payload = data.d as DiscordInteraction; - bot.events.interactionCreate(bot.transformers.interaction(bot, payload, { shardId })) + bot.events.interactionCreate(bot.transformers.interaction(bot, payload, { shardId })); } diff --git a/packages/bot/src/handlers/interactions/index.ts b/packages/bot/src/handlers/interactions/index.ts index 224d68b0e..557e607a2 100644 --- a/packages/bot/src/handlers/interactions/index.ts +++ b/packages/bot/src/handlers/interactions/index.ts @@ -1,2 +1,2 @@ -export * from './APPLICATION_COMMAND_PERMISSIONS_UPDATE.js' -export * from './INTERACTION_CREATE.js' +export * from './APPLICATION_COMMAND_PERMISSIONS_UPDATE.js'; +export * from './INTERACTION_CREATE.js'; diff --git a/packages/bot/src/handlers/invites/INVITE_CREATE.ts b/packages/bot/src/handlers/invites/INVITE_CREATE.ts index e1b971eb8..7243c9752 100644 --- a/packages/bot/src/handlers/invites/INVITE_CREATE.ts +++ b/packages/bot/src/handlers/invites/INVITE_CREATE.ts @@ -1,10 +1,10 @@ -import type { DiscordGatewayPayload, DiscordInviteCreate } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordGatewayPayload, DiscordInviteCreate } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleInviteCreate(bot: Bot, data: DiscordGatewayPayload, shardId: number): Promise { - if (!bot.events.inviteCreate) return + if (!bot.events.inviteCreate) return; - const payload = data.d as DiscordInviteCreate + const payload = data.d as DiscordInviteCreate; - bot.events.inviteCreate(bot.transformers.invite(bot, payload, { shardId })) + bot.events.inviteCreate(bot.transformers.invite(bot, payload, { shardId })); } diff --git a/packages/bot/src/handlers/invites/INVITE_DELETE.ts b/packages/bot/src/handlers/invites/INVITE_DELETE.ts index 569d70263..37918ed1b 100644 --- a/packages/bot/src/handlers/invites/INVITE_DELETE.ts +++ b/packages/bot/src/handlers/invites/INVITE_DELETE.ts @@ -1,10 +1,10 @@ -import type { DiscordGatewayPayload, DiscordInviteDelete } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordGatewayPayload, DiscordInviteDelete } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleInviteDelete(bot: Bot, data: DiscordGatewayPayload): Promise { - if (!bot.events.inviteDelete) return + if (!bot.events.inviteDelete) return; - const payload = data.d as DiscordInviteDelete + const payload = data.d as DiscordInviteDelete; bot.events.inviteDelete({ /** The channel of the invite */ @@ -13,5 +13,5 @@ export async function handleInviteDelete(bot: Bot, data: DiscordGatewayPayload): guildId: payload.guild_id ? bot.transformers.snowflake(payload.guild_id) : undefined, /** The unique invite code */ code: payload.code, - }) + }); } diff --git a/packages/bot/src/handlers/invites/index.ts b/packages/bot/src/handlers/invites/index.ts index 34e4fb5df..43ce3bb75 100644 --- a/packages/bot/src/handlers/invites/index.ts +++ b/packages/bot/src/handlers/invites/index.ts @@ -1,2 +1,2 @@ -export * from './INVITE_CREATE.js' -export * from './INVITE_DELETE.js' +export * from './INVITE_CREATE.js'; +export * from './INVITE_DELETE.js'; diff --git a/packages/bot/src/handlers/members/GUILD_MEMBERS_CHUNK.ts b/packages/bot/src/handlers/members/GUILD_MEMBERS_CHUNK.ts index 04814a9e0..4aff83ae3 100644 --- a/packages/bot/src/handlers/members/GUILD_MEMBERS_CHUNK.ts +++ b/packages/bot/src/handlers/members/GUILD_MEMBERS_CHUNK.ts @@ -1,29 +1,29 @@ -import type { DiscordGatewayPayload, DiscordGuildMembersChunk } from '@discordeno/types' -import { camelize } from '@discordeno/utils' -import type { Bot } from '../../bot.js' +import type { DiscordGatewayPayload, DiscordGuildMembersChunk } from '@discordeno/types'; +import { camelize } from '@discordeno/utils'; +import type { Bot } from '../../bot.js'; export async function handleGuildMembersChunk(bot: Bot, data: DiscordGatewayPayload): Promise { - const payload = data.d as DiscordGuildMembersChunk + const payload = data.d as DiscordGuildMembersChunk; // If it's not enabled skip checks. - if (!bot.gateway.cache.requestMembers.enabled) return + if (!bot.gateway.cache.requestMembers.enabled) return; // If this request has no nonce, skip checks. - if (!payload.nonce) return + if (!payload.nonce) return; - const pending = bot.gateway.cache.requestMembers.pending.get(payload.nonce) + const pending = bot.gateway.cache.requestMembers.pending.get(payload.nonce); - if (!pending) return + if (!pending) return; - if (payload.chunk_count === 1) pending.members = payload.members - else pending.members.push(...payload.members) + if (payload.chunk_count === 1) pending.members = payload.members; + else pending.members.push(...payload.members); // If this is not the final chunk, just save to cache. - if (payload.chunk_index + 1 < payload.chunk_count) return + if (payload.chunk_index + 1 < payload.chunk_count) return; // Resolve the promise that all requests are done. - pending.resolve(camelize(pending.members)) + pending.resolve(camelize(pending.members)); // Delete the cache to clean up once its done. - bot.gateway.cache.requestMembers.pending.delete(payload.nonce) + bot.gateway.cache.requestMembers.pending.delete(payload.nonce); } diff --git a/packages/bot/src/handlers/members/GUILD_MEMBER_ADD.ts b/packages/bot/src/handlers/members/GUILD_MEMBER_ADD.ts index 22706f21a..285074b38 100644 --- a/packages/bot/src/handlers/members/GUILD_MEMBER_ADD.ts +++ b/packages/bot/src/handlers/members/GUILD_MEMBER_ADD.ts @@ -1,12 +1,12 @@ -import type { DiscordGatewayPayload, DiscordGuildMemberAdd } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordGatewayPayload, DiscordGuildMemberAdd } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleGuildMemberAdd(bot: Bot, data: DiscordGatewayPayload): Promise { - if (!bot.events.guildMemberAdd) return + if (!bot.events.guildMemberAdd) return; - const payload = data.d as DiscordGuildMemberAdd - const guildId = bot.transformers.snowflake(payload.guild_id) - const user = bot.transformers.user(bot, payload.user) - const member = bot.transformers.member(bot, payload, { guildId, userId: payload.user.id }) - bot.events.guildMemberAdd(member, user) + const payload = data.d as DiscordGuildMemberAdd; + const guildId = bot.transformers.snowflake(payload.guild_id); + const user = bot.transformers.user(bot, payload.user); + const member = bot.transformers.member(bot, payload, { guildId, userId: payload.user.id }); + bot.events.guildMemberAdd(member, user); } diff --git a/packages/bot/src/handlers/members/GUILD_MEMBER_REMOVE.ts b/packages/bot/src/handlers/members/GUILD_MEMBER_REMOVE.ts index c4f08837d..bd8038932 100644 --- a/packages/bot/src/handlers/members/GUILD_MEMBER_REMOVE.ts +++ b/packages/bot/src/handlers/members/GUILD_MEMBER_REMOVE.ts @@ -1,12 +1,12 @@ -import type { DiscordGatewayPayload, DiscordGuildMemberRemove } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordGatewayPayload, DiscordGuildMemberRemove } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleGuildMemberRemove(bot: Bot, data: DiscordGatewayPayload): Promise { - if (!bot.events.guildMemberRemove) return + if (!bot.events.guildMemberRemove) return; - const payload = data.d as DiscordGuildMemberRemove - const guildId = bot.transformers.snowflake(payload.guild_id) - const user = bot.transformers.user(bot, payload.user) + const payload = data.d as DiscordGuildMemberRemove; + const guildId = bot.transformers.snowflake(payload.guild_id); + const user = bot.transformers.user(bot, payload.user); - bot.events.guildMemberRemove(user, guildId) + bot.events.guildMemberRemove(user, guildId); } diff --git a/packages/bot/src/handlers/members/GUILD_MEMBER_UPDATE.ts b/packages/bot/src/handlers/members/GUILD_MEMBER_UPDATE.ts index 23431ff70..52b37264a 100644 --- a/packages/bot/src/handlers/members/GUILD_MEMBER_UPDATE.ts +++ b/packages/bot/src/handlers/members/GUILD_MEMBER_UPDATE.ts @@ -1,15 +1,15 @@ -import type { DiscordGatewayPayload, DiscordGuildMemberUpdate } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordGatewayPayload, DiscordGuildMemberUpdate } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleGuildMemberUpdate(bot: Bot, data: DiscordGatewayPayload): Promise { - if (!bot.events.guildMemberUpdate) return + if (!bot.events.guildMemberUpdate) return; - const payload = data.d as DiscordGuildMemberUpdate + const payload = data.d as DiscordGuildMemberUpdate; - const user = bot.transformers.user(bot, payload.user) + const user = bot.transformers.user(bot, payload.user); bot.events.guildMemberUpdate( // @ts-expect-error Flags in the update are nullable, while on the member they are be always present bot.transformers.member(bot, payload, { guildId: payload.guild_id, userId: payload.user.id }), user, - ) + ); } diff --git a/packages/bot/src/handlers/members/index.ts b/packages/bot/src/handlers/members/index.ts index a0921f465..206966bc6 100644 --- a/packages/bot/src/handlers/members/index.ts +++ b/packages/bot/src/handlers/members/index.ts @@ -1,4 +1,4 @@ -export * from './GUILD_MEMBER_ADD.js' -export * from './GUILD_MEMBER_REMOVE.js' -export * from './GUILD_MEMBER_UPDATE.js' -export * from './GUILD_MEMBERS_CHUNK.js' +export * from './GUILD_MEMBER_ADD.js'; +export * from './GUILD_MEMBER_REMOVE.js'; +export * from './GUILD_MEMBER_UPDATE.js'; +export * from './GUILD_MEMBERS_CHUNK.js'; diff --git a/packages/bot/src/handlers/messages/MESSAGE_CREATE.ts b/packages/bot/src/handlers/messages/MESSAGE_CREATE.ts index efd1400e1..cb76c1141 100644 --- a/packages/bot/src/handlers/messages/MESSAGE_CREATE.ts +++ b/packages/bot/src/handlers/messages/MESSAGE_CREATE.ts @@ -1,10 +1,10 @@ -import type { DiscordGatewayPayload, DiscordMessage } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordGatewayPayload, DiscordMessage } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleMessageCreate(bot: Bot, data: DiscordGatewayPayload, shardId: number): Promise { - if (!bot.events.messageCreate) return + if (!bot.events.messageCreate) return; - const payload = data.d as DiscordMessage + const payload = data.d as DiscordMessage; - bot.events.messageCreate(bot.transformers.message(bot, payload, { shardId })) + bot.events.messageCreate(bot.transformers.message(bot, payload, { shardId })); } diff --git a/packages/bot/src/handlers/messages/MESSAGE_DELETE.ts b/packages/bot/src/handlers/messages/MESSAGE_DELETE.ts index 8215f7b2b..9a2572409 100644 --- a/packages/bot/src/handlers/messages/MESSAGE_DELETE.ts +++ b/packages/bot/src/handlers/messages/MESSAGE_DELETE.ts @@ -1,14 +1,14 @@ -import type { DiscordGatewayPayload, DiscordMessageDelete } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordGatewayPayload, DiscordMessageDelete } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleMessageDelete(bot: Bot, data: DiscordGatewayPayload): Promise { - if (!bot.events.messageDelete) return + if (!bot.events.messageDelete) return; - const payload = data.d as DiscordMessageDelete + const payload = data.d as DiscordMessageDelete; bot.events.messageDelete({ id: bot.transformers.snowflake(payload.id), channelId: bot.transformers.snowflake(payload.channel_id), guildId: payload.guild_id ? bot.transformers.snowflake(payload.guild_id) : undefined, - }) + }); } diff --git a/packages/bot/src/handlers/messages/MESSAGE_DELETE_BULK.ts b/packages/bot/src/handlers/messages/MESSAGE_DELETE_BULK.ts index 435ef96d1..3150278f2 100644 --- a/packages/bot/src/handlers/messages/MESSAGE_DELETE_BULK.ts +++ b/packages/bot/src/handlers/messages/MESSAGE_DELETE_BULK.ts @@ -1,17 +1,17 @@ -import type { DiscordGatewayPayload, DiscordMessageDeleteBulk } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordGatewayPayload, DiscordMessageDeleteBulk } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleMessageDeleteBulk(bot: Bot, data: DiscordGatewayPayload): Promise { - if (!bot.events.messageDeleteBulk) return + if (!bot.events.messageDeleteBulk) return; - const payload = data.d as DiscordMessageDeleteBulk + const payload = data.d as DiscordMessageDeleteBulk; - const channelId = bot.transformers.snowflake(payload.channel_id) - const guildId = payload.guild_id ? bot.transformers.snowflake(payload.guild_id) : undefined + const channelId = bot.transformers.snowflake(payload.channel_id); + const guildId = payload.guild_id ? bot.transformers.snowflake(payload.guild_id) : undefined; bot.events.messageDeleteBulk({ ids: payload.ids.map((id) => bot.transformers.snowflake(id)), channelId, guildId, - }) + }); } diff --git a/packages/bot/src/handlers/messages/MESSAGE_REACTION_ADD.ts b/packages/bot/src/handlers/messages/MESSAGE_REACTION_ADD.ts index 36a71bd02..4f06f09f5 100644 --- a/packages/bot/src/handlers/messages/MESSAGE_REACTION_ADD.ts +++ b/packages/bot/src/handlers/messages/MESSAGE_REACTION_ADD.ts @@ -1,13 +1,13 @@ -import type { DiscordGatewayPayload, DiscordMessageReactionAdd } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordGatewayPayload, DiscordMessageReactionAdd } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleMessageReactionAdd(bot: Bot, data: DiscordGatewayPayload): Promise { - if (!bot.events.reactionAdd) return + if (!bot.events.reactionAdd) return; - const payload = data.d as DiscordMessageReactionAdd + const payload = data.d as DiscordMessageReactionAdd; - const guildId = payload.guild_id ? bot.transformers.snowflake(payload.guild_id) : undefined - const userId = bot.transformers.snowflake(payload.user_id) + const guildId = payload.guild_id ? bot.transformers.snowflake(payload.guild_id) : undefined; + const userId = bot.transformers.snowflake(payload.user_id); bot.events.reactionAdd({ userId, channelId: bot.transformers.snowflake(payload.channel_id), @@ -20,5 +20,5 @@ export async function handleMessageReactionAdd(bot: Bot, data: DiscordGatewayPay messageAuthorId: payload.message_author_id ? bot.transformers.snowflake(payload.message_author_id) : undefined, burst: payload.burst, burstColors: payload.burst_colors, - }) + }); } diff --git a/packages/bot/src/handlers/messages/MESSAGE_REACTION_REMOVE.ts b/packages/bot/src/handlers/messages/MESSAGE_REACTION_REMOVE.ts index 39492f2ab..727a2805a 100644 --- a/packages/bot/src/handlers/messages/MESSAGE_REACTION_REMOVE.ts +++ b/packages/bot/src/handlers/messages/MESSAGE_REACTION_REMOVE.ts @@ -1,10 +1,10 @@ -import type { DiscordGatewayPayload, DiscordMessageReactionRemove } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordGatewayPayload, DiscordMessageReactionRemove } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleMessageReactionRemove(bot: Bot, data: DiscordGatewayPayload): Promise { - if (!bot.events.reactionRemove) return + if (!bot.events.reactionRemove) return; - const payload = data.d as DiscordMessageReactionRemove + const payload = data.d as DiscordMessageReactionRemove; bot.events.reactionRemove({ userId: bot.transformers.snowflake(payload.user_id), @@ -14,5 +14,5 @@ export async function handleMessageReactionRemove(bot: Bot, data: DiscordGateway // @ts-expect-error TODO: Deal with partials emoji: bot.transformers.emoji(bot, payload.emoji), burst: payload.burst, - }) + }); } diff --git a/packages/bot/src/handlers/messages/MESSAGE_REACTION_REMOVE_ALL.ts b/packages/bot/src/handlers/messages/MESSAGE_REACTION_REMOVE_ALL.ts index 006d145ec..4eefa6a0a 100644 --- a/packages/bot/src/handlers/messages/MESSAGE_REACTION_REMOVE_ALL.ts +++ b/packages/bot/src/handlers/messages/MESSAGE_REACTION_REMOVE_ALL.ts @@ -1,14 +1,14 @@ -import type { DiscordGatewayPayload, DiscordMessageReactionRemoveAll } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordGatewayPayload, DiscordMessageReactionRemoveAll } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleMessageReactionRemoveAll(bot: Bot, data: DiscordGatewayPayload): Promise { - if (!bot.events.reactionRemoveAll) return + if (!bot.events.reactionRemoveAll) return; - const payload = data.d as DiscordMessageReactionRemoveAll + const payload = data.d as DiscordMessageReactionRemoveAll; bot.events.reactionRemoveAll({ channelId: bot.transformers.snowflake(payload.channel_id), messageId: bot.transformers.snowflake(payload.message_id), guildId: payload.guild_id ? bot.transformers.snowflake(payload.guild_id) : undefined, - }) + }); } diff --git a/packages/bot/src/handlers/messages/MESSAGE_REACTION_REMOVE_EMOJI.ts b/packages/bot/src/handlers/messages/MESSAGE_REACTION_REMOVE_EMOJI.ts index efa3cb4a0..07e87fbe6 100644 --- a/packages/bot/src/handlers/messages/MESSAGE_REACTION_REMOVE_EMOJI.ts +++ b/packages/bot/src/handlers/messages/MESSAGE_REACTION_REMOVE_EMOJI.ts @@ -1,10 +1,10 @@ -import type { DiscordGatewayPayload, DiscordMessageReactionRemoveEmoji } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordGatewayPayload, DiscordMessageReactionRemoveEmoji } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleMessageReactionRemoveEmoji(bot: Bot, data: DiscordGatewayPayload): Promise { - if (!bot.events.reactionRemoveEmoji) return + if (!bot.events.reactionRemoveEmoji) return; - const payload = data.d as DiscordMessageReactionRemoveEmoji + const payload = data.d as DiscordMessageReactionRemoveEmoji; bot.events.reactionRemoveEmoji({ channelId: bot.transformers.snowflake(payload.channel_id), @@ -12,5 +12,5 @@ export async function handleMessageReactionRemoveEmoji(bot: Bot, data: DiscordGa guildId: payload.guild_id ? bot.transformers.snowflake(payload.guild_id) : undefined, // @ts-expect-error TODO: Deal with partials emoji: bot.transformers.emoji(bot, payload.emoji), - }) + }); } diff --git a/packages/bot/src/handlers/messages/MESSAGE_UPDATE.ts b/packages/bot/src/handlers/messages/MESSAGE_UPDATE.ts index 5e976d2fe..0bd13ff36 100644 --- a/packages/bot/src/handlers/messages/MESSAGE_UPDATE.ts +++ b/packages/bot/src/handlers/messages/MESSAGE_UPDATE.ts @@ -1,11 +1,11 @@ -import type { DiscordGatewayPayload, DiscordMessage } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordGatewayPayload, DiscordMessage } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleMessageUpdate(bot: Bot, data: DiscordGatewayPayload, shardId: number): Promise { - if (!bot.events.messageUpdate) return + if (!bot.events.messageUpdate) return; - const payload = data.d as DiscordMessage - if (!payload.edited_timestamp) return + const payload = data.d as DiscordMessage; + if (!payload.edited_timestamp) return; - bot.events.messageUpdate(bot.transformers.message(bot, payload, { shardId })) + bot.events.messageUpdate(bot.transformers.message(bot, payload, { shardId })); } diff --git a/packages/bot/src/handlers/messages/index.ts b/packages/bot/src/handlers/messages/index.ts index 4668f7827..66327f971 100644 --- a/packages/bot/src/handlers/messages/index.ts +++ b/packages/bot/src/handlers/messages/index.ts @@ -1,8 +1,8 @@ -export * from './MESSAGE_CREATE.js' -export * from './MESSAGE_DELETE.js' -export * from './MESSAGE_DELETE_BULK.js' -export * from './MESSAGE_REACTION_ADD.js' -export * from './MESSAGE_REACTION_REMOVE.js' -export * from './MESSAGE_REACTION_REMOVE_ALL.js' -export * from './MESSAGE_REACTION_REMOVE_EMOJI.js' -export * from './MESSAGE_UPDATE.js' +export * from './MESSAGE_CREATE.js'; +export * from './MESSAGE_DELETE.js'; +export * from './MESSAGE_DELETE_BULK.js'; +export * from './MESSAGE_REACTION_ADD.js'; +export * from './MESSAGE_REACTION_REMOVE.js'; +export * from './MESSAGE_REACTION_REMOVE_ALL.js'; +export * from './MESSAGE_REACTION_REMOVE_EMOJI.js'; +export * from './MESSAGE_UPDATE.js'; diff --git a/packages/bot/src/handlers/misc/PRESENCE_UPDATE.ts b/packages/bot/src/handlers/misc/PRESENCE_UPDATE.ts index eec7cda04..a3427e0fb 100644 --- a/packages/bot/src/handlers/misc/PRESENCE_UPDATE.ts +++ b/packages/bot/src/handlers/misc/PRESENCE_UPDATE.ts @@ -1,8 +1,8 @@ -import type { DiscordGatewayPayload, DiscordPresenceUpdate } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordGatewayPayload, DiscordPresenceUpdate } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handlePresenceUpdate(bot: Bot, data: DiscordGatewayPayload): Promise { - if (!bot.events.presenceUpdate) return + if (!bot.events.presenceUpdate) return; - bot.events.presenceUpdate(bot.transformers.presence(bot, data.d as DiscordPresenceUpdate)) + bot.events.presenceUpdate(bot.transformers.presence(bot, data.d as DiscordPresenceUpdate)); } diff --git a/packages/bot/src/handlers/misc/RATE_LIMITED.ts b/packages/bot/src/handlers/misc/RATE_LIMITED.ts index e2843ae77..0aab79dc3 100644 --- a/packages/bot/src/handlers/misc/RATE_LIMITED.ts +++ b/packages/bot/src/handlers/misc/RATE_LIMITED.ts @@ -1,9 +1,9 @@ -import type { DiscordGatewayPayload, DiscordRateLimited } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordGatewayPayload, DiscordRateLimited } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleRateLimited(bot: Bot, data: DiscordGatewayPayload, shardId: number): Promise { - if (!bot.events.rateLimited) return + if (!bot.events.rateLimited) return; - const payload = data.d as DiscordRateLimited - bot.events.rateLimited(payload, shardId) + const payload = data.d as DiscordRateLimited; + bot.events.rateLimited(payload, shardId); } diff --git a/packages/bot/src/handlers/misc/READY.ts b/packages/bot/src/handlers/misc/READY.ts index ebed8231c..2e03d3a2f 100644 --- a/packages/bot/src/handlers/misc/READY.ts +++ b/packages/bot/src/handlers/misc/READY.ts @@ -1,10 +1,10 @@ -import type { DiscordGatewayPayload, DiscordReady } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordGatewayPayload, DiscordReady } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleReady(bot: Bot, data: DiscordGatewayPayload, shardId: number): Promise { - if (!bot.events.ready) return + if (!bot.events.ready) return; - const payload = data.d as DiscordReady + const payload = data.d as DiscordReady; // Triggered on each shard bot.events.ready( { @@ -17,8 +17,8 @@ export async function handleReady(bot: Bot, data: DiscordGatewayPayload, shardId applicationId: bot.transformers.snowflake(payload.application.id), }, payload, - ) + ); - bot.id = bot.transformers.snowflake(payload.user.id) - bot.applicationId = bot.transformers.snowflake(payload.application.id) + bot.id = bot.transformers.snowflake(payload.user.id); + bot.applicationId = bot.transformers.snowflake(payload.application.id); } diff --git a/packages/bot/src/handlers/misc/RESUMED.ts b/packages/bot/src/handlers/misc/RESUMED.ts index f8935e1b6..0281ee3d0 100644 --- a/packages/bot/src/handlers/misc/RESUMED.ts +++ b/packages/bot/src/handlers/misc/RESUMED.ts @@ -1,8 +1,8 @@ -import type { DiscordGatewayPayload } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordGatewayPayload } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleResumed(bot: Bot, _data: DiscordGatewayPayload, shardId: number): Promise { - if (!bot.events.resumed) return + if (!bot.events.resumed) return; - bot.events.resumed(shardId) + bot.events.resumed(shardId); } diff --git a/packages/bot/src/handlers/misc/TYPING_START.ts b/packages/bot/src/handlers/misc/TYPING_START.ts index 58329bf4a..f46672340 100644 --- a/packages/bot/src/handlers/misc/TYPING_START.ts +++ b/packages/bot/src/handlers/misc/TYPING_START.ts @@ -1,13 +1,13 @@ -import type { DiscordGatewayPayload, DiscordTypingStart } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordGatewayPayload, DiscordTypingStart } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleTypingStart(bot: Bot, data: DiscordGatewayPayload): Promise { - if (!bot.events.typingStart) return + if (!bot.events.typingStart) return; - const payload = data.d as DiscordTypingStart + const payload = data.d as DiscordTypingStart; - const guildId = payload.guild_id ? bot.transformers.snowflake(payload.guild_id) : undefined - const userId = bot.transformers.snowflake(payload.user_id) + const guildId = payload.guild_id ? bot.transformers.snowflake(payload.guild_id) : undefined; + const userId = bot.transformers.snowflake(payload.user_id); bot.events.typingStart({ guildId, @@ -15,5 +15,5 @@ export async function handleTypingStart(bot: Bot, data: DiscordGatewayPayload): userId, timestamp: payload.timestamp, member: payload.member && guildId ? bot.transformers.member(bot, payload.member, { guildId, userId }) : undefined, - }) + }); } diff --git a/packages/bot/src/handlers/misc/USER_UPDATE.ts b/packages/bot/src/handlers/misc/USER_UPDATE.ts index 8ffc74e92..9bed37808 100644 --- a/packages/bot/src/handlers/misc/USER_UPDATE.ts +++ b/packages/bot/src/handlers/misc/USER_UPDATE.ts @@ -1,9 +1,9 @@ -import type { DiscordGatewayPayload, DiscordUser } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordGatewayPayload, DiscordUser } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleUserUpdate(bot: Bot, data: DiscordGatewayPayload): Promise { - if (!bot.events.botUpdate) return + if (!bot.events.botUpdate) return; - const payload = data.d as DiscordUser - bot.events.botUpdate(bot.transformers.user(bot, payload)) + const payload = data.d as DiscordUser; + bot.events.botUpdate(bot.transformers.user(bot, payload)); } diff --git a/packages/bot/src/handlers/misc/index.ts b/packages/bot/src/handlers/misc/index.ts index 4be796b12..c4eec9709 100644 --- a/packages/bot/src/handlers/misc/index.ts +++ b/packages/bot/src/handlers/misc/index.ts @@ -1,6 +1,6 @@ -export * from './PRESENCE_UPDATE.js' -export * from './RATE_LIMITED.js' -export * from './READY.js' -export * from './RESUMED.js' -export * from './TYPING_START.js' -export * from './USER_UPDATE.js' +export * from './PRESENCE_UPDATE.js'; +export * from './RATE_LIMITED.js'; +export * from './READY.js'; +export * from './RESUMED.js'; +export * from './TYPING_START.js'; +export * from './USER_UPDATE.js'; diff --git a/packages/bot/src/handlers/poll/MESSAGE_POLL_VOTE_ADD.ts b/packages/bot/src/handlers/poll/MESSAGE_POLL_VOTE_ADD.ts index 49e8cbcc3..96a02fb00 100644 --- a/packages/bot/src/handlers/poll/MESSAGE_POLL_VOTE_ADD.ts +++ b/packages/bot/src/handlers/poll/MESSAGE_POLL_VOTE_ADD.ts @@ -1,10 +1,10 @@ -import type { DiscordGatewayPayload, DiscordPollVoteAdd } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordGatewayPayload, DiscordPollVoteAdd } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleMessagePollVoteAdd(bot: Bot, data: DiscordGatewayPayload): Promise { - if (!bot.events.messagePollVoteAdd) return + if (!bot.events.messagePollVoteAdd) return; - const payload = data.d as DiscordPollVoteAdd + const payload = data.d as DiscordPollVoteAdd; bot.events.messagePollVoteAdd({ userId: bot.transformers.snowflake(payload.user_id), @@ -12,5 +12,5 @@ export async function handleMessagePollVoteAdd(bot: Bot, data: DiscordGatewayPay messageId: bot.transformers.snowflake(payload.message_id), guildId: payload.guild_id ? bot.transformers.snowflake(payload.guild_id) : undefined, answerId: payload.answer_id, - }) + }); } diff --git a/packages/bot/src/handlers/poll/MESSAGE_POLL_VOTE_REMOVE.ts b/packages/bot/src/handlers/poll/MESSAGE_POLL_VOTE_REMOVE.ts index 7c475cf11..a7cb1e4ad 100644 --- a/packages/bot/src/handlers/poll/MESSAGE_POLL_VOTE_REMOVE.ts +++ b/packages/bot/src/handlers/poll/MESSAGE_POLL_VOTE_REMOVE.ts @@ -1,10 +1,10 @@ -import type { DiscordGatewayPayload, DiscordPollVoteRemove } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordGatewayPayload, DiscordPollVoteRemove } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleMessagePollVoteRemove(bot: Bot, data: DiscordGatewayPayload): Promise { - if (!bot.events.messagePollVoteRemove) return + if (!bot.events.messagePollVoteRemove) return; - const payload = data.d as DiscordPollVoteRemove + const payload = data.d as DiscordPollVoteRemove; bot.events.messagePollVoteRemove({ userId: bot.transformers.snowflake(payload.user_id), @@ -12,5 +12,5 @@ export async function handleMessagePollVoteRemove(bot: Bot, data: DiscordGateway messageId: bot.transformers.snowflake(payload.message_id), guildId: payload.guild_id ? bot.transformers.snowflake(payload.guild_id) : undefined, answerId: payload.answer_id, - }) + }); } diff --git a/packages/bot/src/handlers/poll/index.ts b/packages/bot/src/handlers/poll/index.ts index 74fc15476..169c3e81a 100644 --- a/packages/bot/src/handlers/poll/index.ts +++ b/packages/bot/src/handlers/poll/index.ts @@ -1,2 +1,2 @@ -export * from './MESSAGE_POLL_VOTE_ADD.js' -export * from './MESSAGE_POLL_VOTE_REMOVE.js' +export * from './MESSAGE_POLL_VOTE_ADD.js'; +export * from './MESSAGE_POLL_VOTE_REMOVE.js'; diff --git a/packages/bot/src/handlers/roles/GUILD_ROLE_CREATE.ts b/packages/bot/src/handlers/roles/GUILD_ROLE_CREATE.ts index 929752ab4..3ff97cfc9 100644 --- a/packages/bot/src/handlers/roles/GUILD_ROLE_CREATE.ts +++ b/packages/bot/src/handlers/roles/GUILD_ROLE_CREATE.ts @@ -1,13 +1,13 @@ -import type { DiscordGatewayPayload, DiscordGuildRoleCreate } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordGatewayPayload, DiscordGuildRoleCreate } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleGuildRoleCreate(bot: Bot, data: DiscordGatewayPayload): Promise { - if (!bot.events.roleCreate) return + if (!bot.events.roleCreate) return; - const payload = data.d as DiscordGuildRoleCreate + const payload = data.d as DiscordGuildRoleCreate; bot.events.roleCreate( bot.transformers.role(bot, payload.role, { guildId: bot.transformers.snowflake(payload.guild_id), }), - ) + ); } diff --git a/packages/bot/src/handlers/roles/GUILD_ROLE_DELETE.ts b/packages/bot/src/handlers/roles/GUILD_ROLE_DELETE.ts index c04fdfcb3..c3c80cc31 100644 --- a/packages/bot/src/handlers/roles/GUILD_ROLE_DELETE.ts +++ b/packages/bot/src/handlers/roles/GUILD_ROLE_DELETE.ts @@ -1,12 +1,12 @@ -import type { DiscordGatewayPayload, DiscordGuildRoleDelete } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordGatewayPayload, DiscordGuildRoleDelete } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleGuildRoleDelete(bot: Bot, data: DiscordGatewayPayload): Promise { - if (!bot.events.roleDelete) return + if (!bot.events.roleDelete) return; - const payload = data.d as DiscordGuildRoleDelete + const payload = data.d as DiscordGuildRoleDelete; bot.events.roleDelete({ roleId: bot.transformers.snowflake(payload.role_id), guildId: bot.transformers.snowflake(payload.guild_id), - }) + }); } diff --git a/packages/bot/src/handlers/roles/GUILD_ROLE_UPDATE.ts b/packages/bot/src/handlers/roles/GUILD_ROLE_UPDATE.ts index 98051cde2..5e05df46f 100644 --- a/packages/bot/src/handlers/roles/GUILD_ROLE_UPDATE.ts +++ b/packages/bot/src/handlers/roles/GUILD_ROLE_UPDATE.ts @@ -1,14 +1,14 @@ -import type { DiscordGatewayPayload, DiscordGuildRoleUpdate } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordGatewayPayload, DiscordGuildRoleUpdate } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleGuildRoleUpdate(bot: Bot, data: DiscordGatewayPayload): Promise { - if (!bot.events.roleUpdate) return + if (!bot.events.roleUpdate) return; - const payload = data.d as DiscordGuildRoleUpdate + const payload = data.d as DiscordGuildRoleUpdate; bot.events.roleUpdate( bot.transformers.role(bot, payload.role, { guildId: bot.transformers.snowflake(payload.guild_id), }), - ) + ); } diff --git a/packages/bot/src/handlers/roles/index.ts b/packages/bot/src/handlers/roles/index.ts index 9e369134f..85009d58d 100644 --- a/packages/bot/src/handlers/roles/index.ts +++ b/packages/bot/src/handlers/roles/index.ts @@ -1,3 +1,3 @@ -export * from './GUILD_ROLE_CREATE.js' -export * from './GUILD_ROLE_DELETE.js' -export * from './GUILD_ROLE_UPDATE.js' +export * from './GUILD_ROLE_CREATE.js'; +export * from './GUILD_ROLE_DELETE.js'; +export * from './GUILD_ROLE_UPDATE.js'; diff --git a/packages/bot/src/handlers/soundboard/GUILD_SOUNDBOARD_SOUNDS_UPDATE.ts b/packages/bot/src/handlers/soundboard/GUILD_SOUNDBOARD_SOUNDS_UPDATE.ts index 8474b149e..955eee704 100644 --- a/packages/bot/src/handlers/soundboard/GUILD_SOUNDBOARD_SOUNDS_UPDATE.ts +++ b/packages/bot/src/handlers/soundboard/GUILD_SOUNDBOARD_SOUNDS_UPDATE.ts @@ -1,13 +1,13 @@ -import type { DiscordGatewayPayload, DiscordSoundboardSoundsUpdate } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordGatewayPayload, DiscordSoundboardSoundsUpdate } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleGuildSoundboardSoundsUpdate(bot: Bot, data: DiscordGatewayPayload): Promise { - if (!bot.events.soundboardSoundsUpdate) return + if (!bot.events.soundboardSoundsUpdate) return; - const payload = data.d as DiscordSoundboardSoundsUpdate + const payload = data.d as DiscordSoundboardSoundsUpdate; bot.events.soundboardSoundsUpdate({ guildId: bot.transformers.snowflake(payload.guild_id), soundboardSounds: payload.soundboard_sounds.map((sound) => bot.transformers.soundboardSound(bot, sound)), - }) + }); } diff --git a/packages/bot/src/handlers/soundboard/GUILD_SOUNDBOARD_SOUND_CREATE.ts b/packages/bot/src/handlers/soundboard/GUILD_SOUNDBOARD_SOUND_CREATE.ts index 574d9ed10..ea7485966 100644 --- a/packages/bot/src/handlers/soundboard/GUILD_SOUNDBOARD_SOUND_CREATE.ts +++ b/packages/bot/src/handlers/soundboard/GUILD_SOUNDBOARD_SOUND_CREATE.ts @@ -1,10 +1,10 @@ -import type { DiscordGatewayPayload, DiscordSoundboardSound } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordGatewayPayload, DiscordSoundboardSound } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleGuildSoundboardSoundCreate(bot: Bot, data: DiscordGatewayPayload): Promise { - if (!bot.events.soundboardSoundCreate) return + if (!bot.events.soundboardSoundCreate) return; - const payload = data.d as DiscordSoundboardSound + const payload = data.d as DiscordSoundboardSound; - bot.events.soundboardSoundCreate(bot.transformers.soundboardSound(bot, payload)) + bot.events.soundboardSoundCreate(bot.transformers.soundboardSound(bot, payload)); } diff --git a/packages/bot/src/handlers/soundboard/GUILD_SOUNDBOARD_SOUND_DELETE.ts b/packages/bot/src/handlers/soundboard/GUILD_SOUNDBOARD_SOUND_DELETE.ts index c10fb4554..b24fc29bb 100644 --- a/packages/bot/src/handlers/soundboard/GUILD_SOUNDBOARD_SOUND_DELETE.ts +++ b/packages/bot/src/handlers/soundboard/GUILD_SOUNDBOARD_SOUND_DELETE.ts @@ -1,13 +1,13 @@ -import type { DiscordGatewayPayload, DiscordSoundboardSoundDelete } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordGatewayPayload, DiscordSoundboardSoundDelete } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleGuildSoundboardSoundDelete(bot: Bot, data: DiscordGatewayPayload): Promise { - if (!bot.events.soundboardSoundDelete) return + if (!bot.events.soundboardSoundDelete) return; - const payload = data.d as DiscordSoundboardSoundDelete + const payload = data.d as DiscordSoundboardSoundDelete; bot.events.soundboardSoundDelete({ guildId: bot.transformers.snowflake(payload.guild_id), soundId: bot.transformers.snowflake(payload.sound_id), - }) + }); } diff --git a/packages/bot/src/handlers/soundboard/GUILD_SOUNDBOARD_SOUND_UPDATE.ts b/packages/bot/src/handlers/soundboard/GUILD_SOUNDBOARD_SOUND_UPDATE.ts index 6a830a262..3e639b0a6 100644 --- a/packages/bot/src/handlers/soundboard/GUILD_SOUNDBOARD_SOUND_UPDATE.ts +++ b/packages/bot/src/handlers/soundboard/GUILD_SOUNDBOARD_SOUND_UPDATE.ts @@ -1,10 +1,10 @@ -import type { DiscordGatewayPayload, DiscordSoundboardSound } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordGatewayPayload, DiscordSoundboardSound } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleGuildSoundboardSoundUpdate(bot: Bot, data: DiscordGatewayPayload): Promise { - if (!bot.events.soundboardSoundUpdate) return + if (!bot.events.soundboardSoundUpdate) return; - const payload = data.d as DiscordSoundboardSound + const payload = data.d as DiscordSoundboardSound; - bot.events.soundboardSoundUpdate(bot.transformers.soundboardSound(bot, payload)) + bot.events.soundboardSoundUpdate(bot.transformers.soundboardSound(bot, payload)); } diff --git a/packages/bot/src/handlers/soundboard/SOUNDBOARD_SOUNDS.ts b/packages/bot/src/handlers/soundboard/SOUNDBOARD_SOUNDS.ts index c92d3efa1..b2b3833b5 100644 --- a/packages/bot/src/handlers/soundboard/SOUNDBOARD_SOUNDS.ts +++ b/packages/bot/src/handlers/soundboard/SOUNDBOARD_SOUNDS.ts @@ -1,13 +1,13 @@ -import type { DiscordGatewayPayload, DiscordSoundboardSounds } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordGatewayPayload, DiscordSoundboardSounds } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleSoundboardSounds(bot: Bot, data: DiscordGatewayPayload): Promise { - if (!bot.events.soundboardSounds) return + if (!bot.events.soundboardSounds) return; - const payload = data.d as DiscordSoundboardSounds + const payload = data.d as DiscordSoundboardSounds; bot.events.soundboardSounds({ guildId: bot.transformers.snowflake(payload.guild_id), soundboardSounds: payload.soundboard_sounds.map((sound) => bot.transformers.soundboardSound(bot, sound)), - }) + }); } diff --git a/packages/bot/src/handlers/soundboard/index.ts b/packages/bot/src/handlers/soundboard/index.ts index 4be6088be..a5902a478 100644 --- a/packages/bot/src/handlers/soundboard/index.ts +++ b/packages/bot/src/handlers/soundboard/index.ts @@ -1,5 +1,5 @@ -export * from './GUILD_SOUNDBOARD_SOUND_CREATE.js' -export * from './GUILD_SOUNDBOARD_SOUND_DELETE.js' -export * from './GUILD_SOUNDBOARD_SOUND_UPDATE.js' -export * from './GUILD_SOUNDBOARD_SOUNDS_UPDATE.js' -export * from './SOUNDBOARD_SOUNDS.js' +export * from './GUILD_SOUNDBOARD_SOUND_CREATE.js'; +export * from './GUILD_SOUNDBOARD_SOUND_DELETE.js'; +export * from './GUILD_SOUNDBOARD_SOUND_UPDATE.js'; +export * from './GUILD_SOUNDBOARD_SOUNDS_UPDATE.js'; +export * from './SOUNDBOARD_SOUNDS.js'; diff --git a/packages/bot/src/handlers/subscriptions/SUBSCRIPTION_CREATE.ts b/packages/bot/src/handlers/subscriptions/SUBSCRIPTION_CREATE.ts index ac9b7fbf2..32ce6128a 100644 --- a/packages/bot/src/handlers/subscriptions/SUBSCRIPTION_CREATE.ts +++ b/packages/bot/src/handlers/subscriptions/SUBSCRIPTION_CREATE.ts @@ -1,9 +1,9 @@ -import type { DiscordGatewayPayload, DiscordSubscription } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordGatewayPayload, DiscordSubscription } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleSubscriptionCreate(bot: Bot, data: DiscordGatewayPayload): Promise { - if (!bot.events.subscriptionCreate) return + if (!bot.events.subscriptionCreate) return; - const payload = data.d as DiscordSubscription - bot.events.subscriptionCreate(bot.transformers.subscription(bot, payload)) + const payload = data.d as DiscordSubscription; + bot.events.subscriptionCreate(bot.transformers.subscription(bot, payload)); } diff --git a/packages/bot/src/handlers/subscriptions/SUBSCRIPTION_DELETE.ts b/packages/bot/src/handlers/subscriptions/SUBSCRIPTION_DELETE.ts index 30c0356e2..ce285fe81 100644 --- a/packages/bot/src/handlers/subscriptions/SUBSCRIPTION_DELETE.ts +++ b/packages/bot/src/handlers/subscriptions/SUBSCRIPTION_DELETE.ts @@ -1,9 +1,9 @@ -import type { DiscordGatewayPayload, DiscordSubscription } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordGatewayPayload, DiscordSubscription } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleSubscriptionDelete(bot: Bot, data: DiscordGatewayPayload): Promise { - if (!bot.events.subscriptionDelete) return + if (!bot.events.subscriptionDelete) return; - const payload = data.d as DiscordSubscription - bot.events.subscriptionDelete(bot.transformers.subscription(bot, payload)) + const payload = data.d as DiscordSubscription; + bot.events.subscriptionDelete(bot.transformers.subscription(bot, payload)); } diff --git a/packages/bot/src/handlers/subscriptions/SUBSCRIPTION_UPDATE.ts b/packages/bot/src/handlers/subscriptions/SUBSCRIPTION_UPDATE.ts index bdeb42b95..d592aae1c 100644 --- a/packages/bot/src/handlers/subscriptions/SUBSCRIPTION_UPDATE.ts +++ b/packages/bot/src/handlers/subscriptions/SUBSCRIPTION_UPDATE.ts @@ -1,9 +1,9 @@ -import type { DiscordGatewayPayload, DiscordSubscription } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordGatewayPayload, DiscordSubscription } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleSubscriptionUpdate(bot: Bot, data: DiscordGatewayPayload): Promise { - if (!bot.events.subscriptionUpdate) return + if (!bot.events.subscriptionUpdate) return; - const payload = data.d as DiscordSubscription - bot.events.subscriptionUpdate(bot.transformers.subscription(bot, payload)) + const payload = data.d as DiscordSubscription; + bot.events.subscriptionUpdate(bot.transformers.subscription(bot, payload)); } diff --git a/packages/bot/src/handlers/subscriptions/index.ts b/packages/bot/src/handlers/subscriptions/index.ts index 6b102b5ee..9fab46d6c 100644 --- a/packages/bot/src/handlers/subscriptions/index.ts +++ b/packages/bot/src/handlers/subscriptions/index.ts @@ -1,3 +1,3 @@ -export * from './SUBSCRIPTION_CREATE.js' -export * from './SUBSCRIPTION_DELETE.js' -export * from './SUBSCRIPTION_UPDATE.js' +export * from './SUBSCRIPTION_CREATE.js'; +export * from './SUBSCRIPTION_DELETE.js'; +export * from './SUBSCRIPTION_UPDATE.js'; diff --git a/packages/bot/src/handlers/voice/VOICE_CHANNEL_EFFECT_SEND.ts b/packages/bot/src/handlers/voice/VOICE_CHANNEL_EFFECT_SEND.ts index c93d3b89c..e10e75b3c 100644 --- a/packages/bot/src/handlers/voice/VOICE_CHANNEL_EFFECT_SEND.ts +++ b/packages/bot/src/handlers/voice/VOICE_CHANNEL_EFFECT_SEND.ts @@ -1,10 +1,10 @@ -import type { DiscordGatewayPayload, DiscordVoiceChannelEffectSend } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordGatewayPayload, DiscordVoiceChannelEffectSend } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleVoiceChannelEffectSend(bot: Bot, data: DiscordGatewayPayload): Promise { - if (!bot.events.voiceChannelEffectSend) return + if (!bot.events.voiceChannelEffectSend) return; - const payload = data.d as DiscordVoiceChannelEffectSend + const payload = data.d as DiscordVoiceChannelEffectSend; bot.events.voiceChannelEffectSend({ guildId: bot.transformers.snowflake(payload.guild_id), @@ -15,5 +15,5 @@ export async function handleVoiceChannelEffectSend(bot: Bot, data: DiscordGatewa emoji: payload.emoji ? bot.transformers.emoji(bot, payload.emoji) : undefined, soundId: typeof payload.sound_id === 'string' ? bot.transformers.snowflake(payload.sound_id) : payload.sound_id, soundVolume: payload.sound_volume, - }) + }); } diff --git a/packages/bot/src/handlers/voice/VOICE_SERVER_UPDATE.ts b/packages/bot/src/handlers/voice/VOICE_SERVER_UPDATE.ts index a0a712115..9f85fe64d 100644 --- a/packages/bot/src/handlers/voice/VOICE_SERVER_UPDATE.ts +++ b/packages/bot/src/handlers/voice/VOICE_SERVER_UPDATE.ts @@ -1,14 +1,14 @@ -import type { DiscordGatewayPayload, DiscordVoiceServerUpdate } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordGatewayPayload, DiscordVoiceServerUpdate } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleVoiceServerUpdate(bot: Bot, data: DiscordGatewayPayload): Promise { - if (!bot.events.voiceServerUpdate) return + if (!bot.events.voiceServerUpdate) return; - const payload = data.d as DiscordVoiceServerUpdate + const payload = data.d as DiscordVoiceServerUpdate; bot.events.voiceServerUpdate({ token: payload.token, guildId: bot.transformers.snowflake(payload.guild_id), endpoint: payload.endpoint ?? undefined, - }) + }); } diff --git a/packages/bot/src/handlers/voice/VOICE_STATE_UPDATE.ts b/packages/bot/src/handlers/voice/VOICE_STATE_UPDATE.ts index 6562b4ea9..73aed3cc3 100644 --- a/packages/bot/src/handlers/voice/VOICE_STATE_UPDATE.ts +++ b/packages/bot/src/handlers/voice/VOICE_STATE_UPDATE.ts @@ -1,10 +1,10 @@ -import type { DiscordGatewayPayload, DiscordVoiceState } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordGatewayPayload, DiscordVoiceState } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleVoiceStateUpdate(bot: Bot, data: DiscordGatewayPayload): Promise { - if (!bot.events.voiceStateUpdate) return + if (!bot.events.voiceStateUpdate) return; - const payload = data.d as DiscordVoiceState + const payload = data.d as DiscordVoiceState; - bot.events.voiceStateUpdate(bot.transformers.voiceState(bot, payload, { guildId: payload.guild_id })) + bot.events.voiceStateUpdate(bot.transformers.voiceState(bot, payload, { guildId: payload.guild_id })); } diff --git a/packages/bot/src/handlers/voice/index.ts b/packages/bot/src/handlers/voice/index.ts index b70327438..19c0a4276 100644 --- a/packages/bot/src/handlers/voice/index.ts +++ b/packages/bot/src/handlers/voice/index.ts @@ -1,3 +1,3 @@ -export * from './VOICE_CHANNEL_EFFECT_SEND.js' -export * from './VOICE_SERVER_UPDATE.js' -export * from './VOICE_STATE_UPDATE.js' +export * from './VOICE_CHANNEL_EFFECT_SEND.js'; +export * from './VOICE_SERVER_UPDATE.js'; +export * from './VOICE_STATE_UPDATE.js'; diff --git a/packages/bot/src/handlers/webhooks/WEBHOOKS_UPDATE.ts b/packages/bot/src/handlers/webhooks/WEBHOOKS_UPDATE.ts index 488041afd..1596f1d3e 100644 --- a/packages/bot/src/handlers/webhooks/WEBHOOKS_UPDATE.ts +++ b/packages/bot/src/handlers/webhooks/WEBHOOKS_UPDATE.ts @@ -1,12 +1,12 @@ -import type { DiscordGatewayPayload, DiscordWebhookUpdate } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { DiscordGatewayPayload, DiscordWebhookUpdate } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export async function handleWebhooksUpdate(bot: Bot, data: DiscordGatewayPayload, _shardId: number): Promise { - if (!bot.events.webhooksUpdate) return + if (!bot.events.webhooksUpdate) return; - const payload = data.d as DiscordWebhookUpdate + const payload = data.d as DiscordWebhookUpdate; bot.events.webhooksUpdate({ channelId: bot.transformers.snowflake(payload.channel_id), guildId: bot.transformers.snowflake(payload.guild_id), - }) + }); } diff --git a/packages/bot/src/handlers/webhooks/index.ts b/packages/bot/src/handlers/webhooks/index.ts index baf5f8d4d..d92fd52e3 100644 --- a/packages/bot/src/handlers/webhooks/index.ts +++ b/packages/bot/src/handlers/webhooks/index.ts @@ -1 +1 @@ -export * from './WEBHOOKS_UPDATE.js' +export * from './WEBHOOKS_UPDATE.js'; diff --git a/packages/bot/src/helpers.ts b/packages/bot/src/helpers.ts index ea937b36f..f18eebd2c 100644 --- a/packages/bot/src/helpers.ts +++ b/packages/bot/src/helpers.ts @@ -102,11 +102,11 @@ import type { StartThreadWithoutMessage, UpsertGlobalApplicationCommandOptions, UpsertGuildApplicationCommandOptions, -} from '@discordeno/types' -import { snakelize } from '@discordeno/utils' -import type { Bot } from './bot.js' -import type { DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from './desiredProperties.js' -import type { ThreadMemberTransformerExtra } from './transformers/threadMember.js' +} from '@discordeno/types'; +import { snakelize } from '@discordeno/utils'; +import type { Bot } from './bot.js'; +import type { DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from './desiredProperties.js'; +import type { ThreadMemberTransformerExtra } from './transformers/threadMember.js'; import type { Application, ApplicationCommand, @@ -143,705 +143,707 @@ import type { VoiceState, Webhook, WelcomeScreen, -} from './transformers/types.js' +} from './transformers/types.js'; export function createBotHelpers( bot: Bot, ): BotHelpers { return { createAutomodRule: async (guildId, options, reason) => { - return bot.transformers.automodRule(bot, snakelize(await bot.rest.createAutomodRule(guildId, options, reason))) + return bot.transformers.automodRule(bot, snakelize(await bot.rest.createAutomodRule(guildId, options, reason))); }, createChannel: async (guildId, options, reason) => { - return bot.transformers.channel(bot, snakelize(await bot.rest.createChannel(guildId, options, reason)), { guildId }) + return bot.transformers.channel(bot, snakelize(await bot.rest.createChannel(guildId, options, reason)), { guildId }); }, createEmoji: async (guildId, options, reason) => { - return bot.transformers.emoji(bot, snakelize(await bot.rest.createEmoji(guildId, options, reason))) + return bot.transformers.emoji(bot, snakelize(await bot.rest.createEmoji(guildId, options, reason))); }, createApplicationEmoji: async (options) => { - return bot.transformers.emoji(bot, snakelize(await bot.rest.createApplicationEmoji(options))) + return bot.transformers.emoji(bot, snakelize(await bot.rest.createApplicationEmoji(options))); }, createForumThread: async (channelId, options, reason) => { - return bot.transformers.channel(bot, snakelize(await bot.rest.createForumThread(channelId, options, reason))) + return bot.transformers.channel(bot, snakelize(await bot.rest.createForumThread(channelId, options, reason))); }, createGlobalApplicationCommand: async (command, options) => { - return bot.transformers.applicationCommand(bot, snakelize(await bot.rest.createGlobalApplicationCommand(command, options))) + return bot.transformers.applicationCommand(bot, snakelize(await bot.rest.createGlobalApplicationCommand(command, options))); }, createGuildApplicationCommand: async (command, guildId, options) => { - return bot.transformers.applicationCommand(bot, snakelize(await bot.rest.createGuildApplicationCommand(command, guildId, options))) + return bot.transformers.applicationCommand(bot, snakelize(await bot.rest.createGuildApplicationCommand(command, guildId, options))); }, createGuildSticker: async (guildId, options, reason) => { - return bot.transformers.sticker(bot, snakelize(await bot.rest.createGuildSticker(guildId, options, reason))) + return bot.transformers.sticker(bot, snakelize(await bot.rest.createGuildSticker(guildId, options, reason))); }, createGuildTemplate: async (guildId, options) => { - return bot.transformers.template(bot, snakelize(await bot.rest.createGuildTemplate(guildId, options))) + return bot.transformers.template(bot, snakelize(await bot.rest.createGuildTemplate(guildId, options))); }, createInvite: async (channelId, options, reason) => { - return await bot.rest.createInvite(channelId, options, reason) + return await bot.rest.createInvite(channelId, options, reason); }, getGuildRoleMemberCounts: async (guildId) => { - return await bot.rest.getGuildRoleMemberCounts(guildId) + return await bot.rest.getGuildRoleMemberCounts(guildId); }, createRole: async (guildId, options, reason) => { - return bot.transformers.role(bot, snakelize(await bot.rest.createRole(guildId, options, reason)), { guildId }) + return bot.transformers.role(bot, snakelize(await bot.rest.createRole(guildId, options, reason)), { guildId }); }, createScheduledEvent: async (guildId, options, reason) => { - return bot.transformers.scheduledEvent(bot, snakelize(await bot.rest.createScheduledEvent(guildId, options, reason))) + return bot.transformers.scheduledEvent(bot, snakelize(await bot.rest.createScheduledEvent(guildId, options, reason))); }, createStageInstance: async (options, reason) => { - return bot.transformers.stageInstance(bot, snakelize(await bot.rest.createStageInstance(options, reason))) + return bot.transformers.stageInstance(bot, snakelize(await bot.rest.createStageInstance(options, reason))); }, createWebhook: async (channelId, options, reason) => { - return bot.transformers.webhook(bot, snakelize(await bot.rest.createWebhook(channelId, options, reason))) + return bot.transformers.webhook(bot, snakelize(await bot.rest.createWebhook(channelId, options, reason))); }, editApplicationCommandPermissions: async (guildId, commandId, bearerToken, options) => { return bot.transformers.applicationCommandPermission( bot, snakelize(await bot.rest.editApplicationCommandPermissions(guildId, commandId, bearerToken, options)), - ) + ); }, editAutomodRule: async (guildId, ruleId, options, reason) => { - return bot.transformers.automodRule(bot, snakelize(await bot.rest.editAutomodRule(guildId, ruleId, options, reason))) + return bot.transformers.automodRule(bot, snakelize(await bot.rest.editAutomodRule(guildId, ruleId, options, reason))); }, editBotProfile: async (options) => { - return bot.transformers.user(bot, snakelize(await bot.rest.editBotProfile(options))) + return bot.transformers.user(bot, snakelize(await bot.rest.editBotProfile(options))); }, editChannel: async (channelId, options, reason) => { - return bot.transformers.channel(bot, snakelize(await bot.rest.editChannel(channelId, options, reason))) + return bot.transformers.channel(bot, snakelize(await bot.rest.editChannel(channelId, options, reason))); }, editEmoji: async (guildId, id, options, reason) => { - return bot.transformers.emoji(bot, snakelize(await bot.rest.editEmoji(guildId, id, options, reason))) + return bot.transformers.emoji(bot, snakelize(await bot.rest.editEmoji(guildId, id, options, reason))); }, editApplicationEmoji: async (id, options) => { - return bot.transformers.emoji(bot, snakelize(await bot.rest.editApplicationEmoji(id, options))) + return bot.transformers.emoji(bot, snakelize(await bot.rest.editApplicationEmoji(id, options))); }, editFollowupMessage: async (token, messageId, options) => { - return bot.transformers.message(bot, snakelize(await bot.rest.editFollowupMessage(token, messageId, options))) + return bot.transformers.message(bot, snakelize(await bot.rest.editFollowupMessage(token, messageId, options))); }, editGlobalApplicationCommand: async (commandId, options) => { - return bot.transformers.applicationCommand(bot, snakelize(await bot.rest.editGlobalApplicationCommand(commandId, options))) + return bot.transformers.applicationCommand(bot, snakelize(await bot.rest.editGlobalApplicationCommand(commandId, options))); }, editGuild: async (guildId, options, reason) => { - return bot.transformers.guild(bot, snakelize(await bot.rest.editGuild(guildId, options, reason))) + return bot.transformers.guild(bot, snakelize(await bot.rest.editGuild(guildId, options, reason))); }, editGuildApplicationCommand: async (commandId, guildId, options) => { - return bot.transformers.applicationCommand(bot, snakelize(await bot.rest.editGuildApplicationCommand(commandId, guildId, options))) + return bot.transformers.applicationCommand(bot, snakelize(await bot.rest.editGuildApplicationCommand(commandId, guildId, options))); }, editGuildSticker: async (guildId, stickerId, options, reason) => { - return bot.transformers.sticker(bot, snakelize(await bot.rest.editGuildSticker(guildId, stickerId, options, reason))) + return bot.transformers.sticker(bot, snakelize(await bot.rest.editGuildSticker(guildId, stickerId, options, reason))); }, editGuildTemplate: async (guildId, templateCode, options) => { - return bot.transformers.template(bot, snakelize(await bot.rest.editGuildTemplate(guildId, templateCode, options))) + return bot.transformers.template(bot, snakelize(await bot.rest.editGuildTemplate(guildId, templateCode, options))); }, editMessage: async (channelId, messageId, options) => { - return bot.transformers.message(bot, snakelize(await bot.rest.editMessage(channelId, messageId, options))) + return bot.transformers.message(bot, snakelize(await bot.rest.editMessage(channelId, messageId, options))); }, editOriginalInteractionResponse: async (token, options) => { - return bot.transformers.message(bot, snakelize(await bot.rest.editOriginalInteractionResponse(token, options))) + return bot.transformers.message(bot, snakelize(await bot.rest.editOriginalInteractionResponse(token, options))); }, editRole: async (guildId, roleId, options, reason) => { - return bot.transformers.role(bot, snakelize(await bot.rest.editRole(guildId, roleId, options, reason)), { guildId }) + return bot.transformers.role(bot, snakelize(await bot.rest.editRole(guildId, roleId, options, reason)), { guildId }); }, editRolePositions: async (guildId, options, reason) => { - return snakelize(await bot.rest.editRolePositions(guildId, options, reason)).map((role) => bot.transformers.role(bot, role, { guildId })) + return snakelize(await bot.rest.editRolePositions(guildId, options, reason)).map((role) => bot.transformers.role(bot, role, { guildId })); }, editScheduledEvent: async (guildId, eventId, options, reason) => { - return bot.transformers.scheduledEvent(bot, snakelize(await bot.rest.editScheduledEvent(guildId, eventId, options, reason))) + return bot.transformers.scheduledEvent(bot, snakelize(await bot.rest.editScheduledEvent(guildId, eventId, options, reason))); }, editStageInstance: async (channelId, topic, reason) => { - return bot.transformers.stageInstance(bot, snakelize(await bot.rest.editStageInstance(channelId, topic, reason))) + return bot.transformers.stageInstance(bot, snakelize(await bot.rest.editStageInstance(channelId, topic, reason))); }, editWebhook: async (webhookId, options, reason) => { - return bot.transformers.webhook(bot, snakelize(await bot.rest.editWebhook(webhookId, options, reason))) + return bot.transformers.webhook(bot, snakelize(await bot.rest.editWebhook(webhookId, options, reason))); }, editWebhookMessage: async (webhookId, token, messageId, options) => { - return bot.transformers.message(bot, snakelize(await bot.rest.editWebhookMessage(webhookId, token, messageId, options))) + return bot.transformers.message(bot, snakelize(await bot.rest.editWebhookMessage(webhookId, token, messageId, options))); }, editWebhookWithToken: async (webhookId, token, options) => { - return bot.transformers.webhook(bot, snakelize(await bot.rest.editWebhookWithToken(webhookId, token, options))) + return bot.transformers.webhook(bot, snakelize(await bot.rest.editWebhookWithToken(webhookId, token, options))); }, editWelcomeScreen: async (guildId, options, reason) => { - return bot.transformers.welcomeScreen(bot, snakelize(await bot.rest.editWelcomeScreen(guildId, options, reason))) + return bot.transformers.welcomeScreen(bot, snakelize(await bot.rest.editWelcomeScreen(guildId, options, reason))); }, editWidgetSettings: async (guildId, options, reason) => { - return bot.transformers.widgetSettings(bot, snakelize(await bot.rest.editWidgetSettings(guildId, options, reason))) + return bot.transformers.widgetSettings(bot, snakelize(await bot.rest.editWidgetSettings(guildId, options, reason))); }, executeWebhook: async (webhookId, token, options) => { - const result = await bot.rest.executeWebhook(webhookId, token, options) - if (!result) return + const result = await bot.rest.executeWebhook(webhookId, token, options); + if (!result) return; - return bot.transformers.message(bot, snakelize(result)) + return bot.transformers.message(bot, snakelize(result)); }, followAnnouncement: async (sourceChannelId, targetChannelId) => { - return await bot.rest.followAnnouncement(sourceChannelId, targetChannelId) + return await bot.rest.followAnnouncement(sourceChannelId, targetChannelId); }, getActiveThreads: async (guildId) => { - const result = await bot.rest.getActiveThreads(guildId) + const result = await bot.rest.getActiveThreads(guildId); return { threads: result.threads.map((thread) => bot.transformers.channel(bot, snakelize(thread), { guildId })), members: result.members.map((member) => bot.transformers.threadMember(bot, snakelize(member), { guildId })), - } + }; }, getApplicationInfo: async () => { - return bot.transformers.application(bot, snakelize(await bot.rest.getApplicationInfo())) + return bot.transformers.application(bot, snakelize(await bot.rest.getApplicationInfo())); }, editApplicationInfo: async (body) => { - return bot.transformers.application(bot, snakelize(await bot.rest.editApplicationInfo(body))) + return bot.transformers.application(bot, snakelize(await bot.rest.editApplicationInfo(body))); }, getCurrentAuthenticationInfo: async (bearerToken) => { - return await bot.rest.getCurrentAuthenticationInfo(bearerToken) + return await bot.rest.getCurrentAuthenticationInfo(bearerToken); }, exchangeToken: async (clientId, clientSecret, options) => { - return await bot.rest.exchangeToken(clientId, clientSecret, options) + return await bot.rest.exchangeToken(clientId, clientSecret, options); }, revokeToken: async (clientId, clientSecret, options) => { - return await bot.rest.revokeToken(clientId, clientSecret, options) + return await bot.rest.revokeToken(clientId, clientSecret, options); }, getApplicationCommandPermission: async (guildId, commandId, options) => { - const res = await bot.rest.getApplicationCommandPermission(guildId, commandId, options) - const snakedRes = snakelize(res) + const res = await bot.rest.getApplicationCommandPermission(guildId, commandId, options); + const snakedRes = snakelize(res); - return bot.transformers.applicationCommandPermission(bot, snakedRes) + return bot.transformers.applicationCommandPermission(bot, snakedRes); }, getApplicationCommandPermissions: async (guildId, options) => { return (await bot.rest.getApplicationCommandPermissions(guildId, options)).map((res) => bot.transformers.applicationCommandPermission(bot, snakelize(res)), - ) + ); }, getAuditLog: async (guildId, options) => { - return await bot.rest.getAuditLog(guildId, options) + return await bot.rest.getAuditLog(guildId, options); }, getAutomodRule: async (guildId, ruleId) => { - return bot.transformers.automodRule(bot, snakelize(await bot.rest.getAutomodRule(guildId, ruleId))) + return bot.transformers.automodRule(bot, snakelize(await bot.rest.getAutomodRule(guildId, ruleId))); }, getAutomodRules: async (guildId) => { - return (await bot.rest.getAutomodRules(guildId)).map((res) => bot.transformers.automodRule(bot, snakelize(res))) + return (await bot.rest.getAutomodRules(guildId)).map((res) => bot.transformers.automodRule(bot, snakelize(res))); }, getAvailableVoiceRegions: async () => { - return (await bot.rest.getAvailableVoiceRegions()).map((res) => bot.transformers.voiceRegion(bot, snakelize(res))) + return (await bot.rest.getAvailableVoiceRegions()).map((res) => bot.transformers.voiceRegion(bot, snakelize(res))); }, getBan: async (guildId, userId) => { - return await bot.rest.getBan(guildId, userId) + return await bot.rest.getBan(guildId, userId); }, getBans: async (guildId, options) => { - return await bot.rest.getBans(guildId, options) + return await bot.rest.getBans(guildId, options); }, getChannel: async (channelId) => { - return bot.transformers.channel(bot, snakelize(await bot.rest.getChannel(channelId))) + return bot.transformers.channel(bot, snakelize(await bot.rest.getChannel(channelId))); }, getChannelInvites: async (channelId) => { - return (await bot.rest.getChannelInvites(channelId)).map((res) => bot.transformers.invite(bot, snakelize(res))) + return (await bot.rest.getChannelInvites(channelId)).map((res) => bot.transformers.invite(bot, snakelize(res))); }, getChannels: async (guildId) => { - return (await bot.rest.getChannels(guildId)).map((res) => bot.transformers.channel(bot, snakelize(res), { guildId })) + return (await bot.rest.getChannels(guildId)).map((res) => bot.transformers.channel(bot, snakelize(res), { guildId })); }, getChannelWebhooks: async (channelId) => { - return (await bot.rest.getChannelWebhooks(channelId)).map((res) => bot.transformers.webhook(bot, snakelize(res))) + return (await bot.rest.getChannelWebhooks(channelId)).map((res) => bot.transformers.webhook(bot, snakelize(res))); }, getDmChannel: async (userId) => { - return bot.transformers.channel(bot, snakelize(await bot.rest.getDmChannel(userId))) + return bot.transformers.channel(bot, snakelize(await bot.rest.getDmChannel(userId))); }, getGroupDmChannel: async (options) => { - return bot.transformers.channel(bot, snakelize(await bot.rest.getGroupDmChannel(options))) + return bot.transformers.channel(bot, snakelize(await bot.rest.getGroupDmChannel(options))); }, getEmoji: async (guildId, emojiId) => { - return bot.transformers.emoji(bot, snakelize(await bot.rest.getEmoji(guildId, emojiId))) + return bot.transformers.emoji(bot, snakelize(await bot.rest.getEmoji(guildId, emojiId))); }, getApplicationEmoji: async (emojiId) => { - return bot.transformers.emoji(bot, snakelize(await bot.rest.getApplicationEmoji(emojiId))) + return bot.transformers.emoji(bot, snakelize(await bot.rest.getApplicationEmoji(emojiId))); }, getEmojis: async (guildId) => { - return (await bot.rest.getEmojis(guildId)).map((res) => bot.transformers.emoji(bot, snakelize(res))) + return (await bot.rest.getEmojis(guildId)).map((res) => bot.transformers.emoji(bot, snakelize(res))); }, getApplicationEmojis: async () => { - const res = await bot.rest.getApplicationEmojis() + const res = await bot.rest.getApplicationEmojis(); return { items: res.items.map((item) => bot.transformers.emoji(bot, snakelize(item))), - } + }; }, getFollowupMessage: async (token, messageId) => { - return bot.transformers.message(bot, snakelize(await bot.rest.getFollowupMessage(token, messageId))) + return bot.transformers.message(bot, snakelize(await bot.rest.getFollowupMessage(token, messageId))); }, getGatewayBot: async () => { - return bot.transformers.gatewayBot(bot, snakelize(await bot.rest.getGatewayBot())) + return bot.transformers.gatewayBot(bot, snakelize(await bot.rest.getGatewayBot())); }, getGlobalApplicationCommand: async (commandId) => { - return bot.transformers.applicationCommand(bot, snakelize(await bot.rest.getGlobalApplicationCommand(commandId))) + return bot.transformers.applicationCommand(bot, snakelize(await bot.rest.getGlobalApplicationCommand(commandId))); }, getGlobalApplicationCommands: async (options) => { - return (await bot.rest.getGlobalApplicationCommands(options)).map((res) => bot.transformers.applicationCommand(bot, snakelize(res))) + return (await bot.rest.getGlobalApplicationCommands(options)).map((res) => bot.transformers.applicationCommand(bot, snakelize(res))); }, getGuild: async (guildId, options) => { - return bot.transformers.guild(bot, snakelize(await bot.rest.getGuild(guildId, options))) + return bot.transformers.guild(bot, snakelize(await bot.rest.getGuild(guildId, options))); }, getGuilds: async (bearerToken, options) => { return (await bot.rest.getGuilds(bearerToken, options)).map>((res) => // @ts-expect-error getGuilds returns partial guilds bot.transformers.guild(bot, snakelize(res)), - ) + ); }, getGuildApplicationCommand: async (commandId, guildId) => { - return bot.transformers.applicationCommand(bot, snakelize(await bot.rest.getGuildApplicationCommand(commandId, guildId))) + return bot.transformers.applicationCommand(bot, snakelize(await bot.rest.getGuildApplicationCommand(commandId, guildId))); }, getGuildApplicationCommands: async (guildId, options) => { - return (await bot.rest.getGuildApplicationCommands(guildId, options)).map((res) => bot.transformers.applicationCommand(bot, snakelize(res))) + return (await bot.rest.getGuildApplicationCommands(guildId, options)).map((res) => bot.transformers.applicationCommand(bot, snakelize(res))); }, getGuildPreview: async (guildId) => { - return await bot.rest.getGuildPreview(guildId) + return await bot.rest.getGuildPreview(guildId); // return bot.transformers.xxx(bot, snakelize(await bot.rest.getGuildPreview(guildId))) }, getGuildSticker: async (guildId, stickerId) => { - return bot.transformers.sticker(bot, snakelize(await bot.rest.getGuildSticker(guildId, stickerId))) + return bot.transformers.sticker(bot, snakelize(await bot.rest.getGuildSticker(guildId, stickerId))); }, getGuildStickers: async (guildId) => { - return (await bot.rest.getGuildStickers(guildId)).map((res) => bot.transformers.sticker(bot, snakelize(res))) + return (await bot.rest.getGuildStickers(guildId)).map((res) => bot.transformers.sticker(bot, snakelize(res))); }, getGuildTemplate: async (templateCode) => { - return bot.transformers.template(bot, snakelize(await bot.rest.getGuildTemplate(templateCode))) + return bot.transformers.template(bot, snakelize(await bot.rest.getGuildTemplate(templateCode))); }, getGuildTemplates: async (guildId) => { - return (await bot.rest.getGuildTemplates(guildId)).map((res) => bot.transformers.template(bot, snakelize(res))) + return (await bot.rest.getGuildTemplates(guildId)).map((res) => bot.transformers.template(bot, snakelize(res))); }, getGuildWebhooks: async (guildId) => { - return (await bot.rest.getGuildWebhooks(guildId)).map((res) => bot.transformers.webhook(bot, snakelize(res))) + return (await bot.rest.getGuildWebhooks(guildId)).map((res) => bot.transformers.webhook(bot, snakelize(res))); }, getIntegrations: async (guildId) => { return (await bot.rest.getIntegrations(guildId)).map((res) => bot.transformers.integration(bot, snakelize({ ...res, guildId: guildId.toString() })), - ) + ); }, getInvite: async (inviteCode, options) => { - return bot.transformers.invite(bot, snakelize(await bot.rest.getInvite(inviteCode, options))) + return bot.transformers.invite(bot, snakelize(await bot.rest.getInvite(inviteCode, options))); }, getInvites: async (guildId) => { - return (await bot.rest.getInvites(guildId)).map((res) => bot.transformers.invite(bot, snakelize(res))) + return (await bot.rest.getInvites(guildId)).map((res) => bot.transformers.invite(bot, snakelize(res))); }, getMessage: async (channelId, messageId) => { - return bot.transformers.message(bot, snakelize(await bot.rest.getMessage(channelId, messageId))) + return bot.transformers.message(bot, snakelize(await bot.rest.getMessage(channelId, messageId))); }, getMessages: async (channelId, options) => { - return (await bot.rest.getMessages(channelId, options)).map((res) => bot.transformers.message(bot, snakelize(res))) + return (await bot.rest.getMessages(channelId, options)).map((res) => bot.transformers.message(bot, snakelize(res))); }, getStickerPack: async (stickerPackId) => { - return bot.transformers.stickerPack(bot, snakelize(await bot.rest.getStickerPack(stickerPackId))) + return bot.transformers.stickerPack(bot, snakelize(await bot.rest.getStickerPack(stickerPackId))); }, getStickerPacks: async () => { - return (await bot.rest.getStickerPacks()).map((res) => bot.transformers.stickerPack(bot, snakelize(res))) + return (await bot.rest.getStickerPacks()).map((res) => bot.transformers.stickerPack(bot, snakelize(res))); }, getOriginalInteractionResponse: async (token) => { - return bot.transformers.message(bot, snakelize(await bot.rest.getOriginalInteractionResponse(token))) + return bot.transformers.message(bot, snakelize(await bot.rest.getOriginalInteractionResponse(token))); }, getChannelPins: async (channelId, options) => { - const res = snakelize(await bot.rest.getChannelPins(channelId, options)) + const res = snakelize(await bot.rest.getChannelPins(channelId, options)); return { hasMore: res.has_more, items: res.items.map((item) => bot.transformers.messagePin(bot, item)), - } + }; }, getPinnedMessages: async (channelId) => { - return (await bot.rest.getPinnedMessages(channelId)).map((res) => bot.transformers.message(bot, snakelize(res))) + return (await bot.rest.getPinnedMessages(channelId)).map((res) => bot.transformers.message(bot, snakelize(res))); }, getPrivateArchivedThreads: async (channelId, options) => { - return await bot.rest.getPrivateArchivedThreads(channelId, options) + return await bot.rest.getPrivateArchivedThreads(channelId, options); }, getPrivateJoinedArchivedThreads: async (channelId, options) => { - return await bot.rest.getPrivateJoinedArchivedThreads(channelId, options) + return await bot.rest.getPrivateJoinedArchivedThreads(channelId, options); }, getPruneCount: async (guildId, options) => { - return await bot.rest.getPruneCount(guildId, options) + return await bot.rest.getPruneCount(guildId, options); }, getPublicArchivedThreads: async (channelId, options) => { - return await bot.rest.getPublicArchivedThreads(channelId, options) + return await bot.rest.getPublicArchivedThreads(channelId, options); }, getRoles: async (guildId) => { - return snakelize(await bot.rest.getRoles(guildId)).map((role) => bot.transformers.role(bot, role, { guildId })) + return snakelize(await bot.rest.getRoles(guildId)).map((role) => bot.transformers.role(bot, role, { guildId })); }, getRole: async (guildId, roleId) => { - return bot.transformers.role(bot, snakelize(await bot.rest.getRole(guildId, roleId)), { guildId }) + return bot.transformers.role(bot, snakelize(await bot.rest.getRole(guildId, roleId)), { guildId }); }, getScheduledEvent: async (guildId, eventId, options) => { - return bot.transformers.scheduledEvent(bot, snakelize(await bot.rest.getScheduledEvent(guildId, eventId, options))) + return bot.transformers.scheduledEvent(bot, snakelize(await bot.rest.getScheduledEvent(guildId, eventId, options))); }, getScheduledEvents: async (guildId, options) => { - return (await bot.rest.getScheduledEvents(guildId, options)).map((res) => bot.transformers.scheduledEvent(bot, snakelize(res))) + return (await bot.rest.getScheduledEvents(guildId, options)).map((res) => bot.transformers.scheduledEvent(bot, snakelize(res))); }, getScheduledEventUsers: async (guildId, eventId, options) => { return (await bot.rest.getScheduledEventUsers(guildId, eventId, options)).map((u) => { return { user: bot.transformers.user(bot, snakelize(u.user)), member: u.member && bot.transformers.member(bot, snakelize(u.member), { guildId, userId: bot.transformers.snowflake(u.user.id) }), - } - }) + }; + }); }, getSessionInfo: async () => { - return bot.transformers.gatewayBot(bot, snakelize(await bot.rest.getSessionInfo())) + return bot.transformers.gatewayBot(bot, snakelize(await bot.rest.getSessionInfo())); }, getStageInstance: async (channelId) => { - return bot.transformers.stageInstance(bot, snakelize(await bot.rest.getStageInstance(channelId))) + return bot.transformers.stageInstance(bot, snakelize(await bot.rest.getStageInstance(channelId))); }, getOwnVoiceState: async (guildId) => { - return bot.transformers.voiceState(bot, snakelize(await bot.rest.getOwnVoiceState(guildId)), { guildId }) + return bot.transformers.voiceState(bot, snakelize(await bot.rest.getOwnVoiceState(guildId)), { guildId }); }, getUserVoiceState: async (guildId, userId) => { - return bot.transformers.voiceState(bot, snakelize(await bot.rest.getUserVoiceState(guildId, userId)), { guildId }) + return bot.transformers.voiceState(bot, snakelize(await bot.rest.getUserVoiceState(guildId, userId)), { guildId }); }, getSticker: async (stickerId) => { - return bot.transformers.sticker(bot, snakelize(await bot.rest.getSticker(stickerId))) + return bot.transformers.sticker(bot, snakelize(await bot.rest.getSticker(stickerId))); }, getThreadMember: async (channelId, userId, options, extra) => { - return bot.transformers.threadMember(bot, snakelize(await bot.rest.getThreadMember(channelId, userId, options)), extra) + return bot.transformers.threadMember(bot, snakelize(await bot.rest.getThreadMember(channelId, userId, options)), extra); }, getThreadMembers: async (channelId, options, extra) => { - return (await bot.rest.getThreadMembers(channelId, options)).map((res) => bot.transformers.threadMember(bot, snakelize(res), extra)) + return (await bot.rest.getThreadMembers(channelId, options)).map((res) => bot.transformers.threadMember(bot, snakelize(res), extra)); }, getReactions: async (channelId, messageId, reaction, options) => { - return (await bot.rest.getReactions(channelId, messageId, reaction, options)).map((res) => bot.transformers.user(bot, snakelize(res))) + return (await bot.rest.getReactions(channelId, messageId, reaction, options)).map((res) => bot.transformers.user(bot, snakelize(res))); }, getUser: async (id) => { - return bot.transformers.user(bot, snakelize(await bot.rest.getUser(id))) + return bot.transformers.user(bot, snakelize(await bot.rest.getUser(id))); }, getCurrentUser: async (bearerToken) => { - return bot.transformers.user(bot, snakelize(await bot.rest.getCurrentUser(bearerToken))) + return bot.transformers.user(bot, snakelize(await bot.rest.getCurrentUser(bearerToken))); }, getUserConnections: async (bearerToken) => { - return await bot.rest.getUserConnections(bearerToken) + return await bot.rest.getUserConnections(bearerToken); }, getUserApplicationRoleConnection: async (bearerToken, applicationId) => { - return await bot.rest.getUserApplicationRoleConnection(bearerToken, applicationId) + return await bot.rest.getUserApplicationRoleConnection(bearerToken, applicationId); }, getVanityUrl: async (guildId) => { - return await bot.rest.getVanityUrl(guildId) + return await bot.rest.getVanityUrl(guildId); }, getVoiceRegions: async (guildId) => { - return (await bot.rest.getVoiceRegions(guildId)).map((res) => bot.transformers.voiceRegion(bot, snakelize(res))) + return (await bot.rest.getVoiceRegions(guildId)).map((res) => bot.transformers.voiceRegion(bot, snakelize(res))); }, getWebhook: async (webhookId) => { - return bot.transformers.webhook(bot, snakelize(await bot.rest.getWebhook(webhookId))) + return bot.transformers.webhook(bot, snakelize(await bot.rest.getWebhook(webhookId))); }, getWebhookMessage: async (webhookId, token, messageId, options) => { - return bot.transformers.message(bot, snakelize(await bot.rest.getWebhookMessage(webhookId, token, messageId, options))) + return bot.transformers.message(bot, snakelize(await bot.rest.getWebhookMessage(webhookId, token, messageId, options))); }, getWebhookWithToken: async (webhookId, token) => { - return bot.transformers.webhook(bot, snakelize(await bot.rest.getWebhookWithToken(webhookId, token))) + return bot.transformers.webhook(bot, snakelize(await bot.rest.getWebhookWithToken(webhookId, token))); }, getWelcomeScreen: async (guildId) => { - return bot.transformers.welcomeScreen(bot, snakelize(await bot.rest.getWelcomeScreen(guildId))) + return bot.transformers.welcomeScreen(bot, snakelize(await bot.rest.getWelcomeScreen(guildId))); }, getWidget: async (guildId) => { - return bot.transformers.widget(bot, snakelize(await bot.rest.getWidget(guildId))) + return bot.transformers.widget(bot, snakelize(await bot.rest.getWidget(guildId))); }, getWidgetSettings: async (guildId) => { - return bot.transformers.widgetSettings(bot, snakelize(await bot.rest.getWidgetSettings(guildId))) + return bot.transformers.widgetSettings(bot, snakelize(await bot.rest.getWidgetSettings(guildId))); }, publishMessage: async (channelId, messageId) => { - return bot.transformers.message(bot, snakelize(await bot.rest.publishMessage(channelId, messageId))) + return bot.transformers.message(bot, snakelize(await bot.rest.publishMessage(channelId, messageId))); }, sendMessage: async (channelId, options) => { - return bot.transformers.message(bot, snakelize(await bot.rest.sendMessage(channelId, options))) + return bot.transformers.message(bot, snakelize(await bot.rest.sendMessage(channelId, options))); }, sendFollowupMessage: async (token, options) => { - return bot.transformers.message(bot, snakelize(await bot.rest.sendFollowupMessage(token, options))) + return bot.transformers.message(bot, snakelize(await bot.rest.sendFollowupMessage(token, options))); }, startThreadWithMessage: async (channelId, messageId, options, reason) => { - return bot.transformers.channel(bot, snakelize(await bot.rest.startThreadWithMessage(channelId, messageId, options, reason))) + return bot.transformers.channel(bot, snakelize(await bot.rest.startThreadWithMessage(channelId, messageId, options, reason))); }, startThreadWithoutMessage: async (channelId, options, reason) => { - return bot.transformers.channel(bot, snakelize(await bot.rest.startThreadWithoutMessage(channelId, options, reason))) + return bot.transformers.channel(bot, snakelize(await bot.rest.startThreadWithoutMessage(channelId, options, reason))); }, syncGuildTemplate: async (guildId) => { - return bot.transformers.template(bot, snakelize(await bot.rest.syncGuildTemplate(guildId))) + return bot.transformers.template(bot, snakelize(await bot.rest.syncGuildTemplate(guildId))); }, upsertGlobalApplicationCommands: async (commands, options) => { return (await bot.rest.upsertGlobalApplicationCommands(commands, options)).map((res) => bot.transformers.applicationCommand(bot, snakelize(res)), - ) + ); }, upsertGuildApplicationCommands: async (guildId, commands, options) => { return (await bot.rest.upsertGuildApplicationCommands(guildId, commands, options)).map((res) => bot.transformers.applicationCommand(bot, snakelize(res)), - ) + ); }, editBotMember: async (guildId, options, reason) => { - return bot.transformers.member(bot, snakelize(await bot.rest.editBotMember(guildId, options, reason)), { guildId, userId: bot.id }) + return bot.transformers.member(bot, snakelize(await bot.rest.editBotMember(guildId, options, reason)), { guildId, userId: bot.id }); }, editMember: async (guildId, userId, options, reason) => { - return bot.transformers.member(bot, snakelize(await bot.rest.editMember(guildId, userId, options, reason)), { guildId, userId }) + return bot.transformers.member(bot, snakelize(await bot.rest.editMember(guildId, userId, options, reason)), { guildId, userId }); }, getMember: async (guildId, userId) => { - return bot.transformers.member(bot, snakelize(await bot.rest.getMember(guildId, userId)), { guildId, userId }) + return bot.transformers.member(bot, snakelize(await bot.rest.getMember(guildId, userId)), { guildId, userId }); }, getCurrentMember: async (guildId, bearerToken) => { - const res = await bot.rest.getCurrentMember(guildId, bearerToken) - return bot.transformers.member(bot, snakelize(res), { guildId, userId: bot.transformers.snowflake(res.user.id) }) + const res = await bot.rest.getCurrentMember(guildId, bearerToken); + return bot.transformers.member(bot, snakelize(res), { guildId, userId: bot.transformers.snowflake(res.user.id) }); }, getMembers: async (guildId, options) => { return (await bot.rest.getMembers(guildId, options)).map((res) => bot.transformers.member(bot, snakelize(res), { guildId, userId: bot.transformers.snowflake(res.user.id) }), - ) + ); }, pruneMembers: async (guildId, options, reason) => { - return await bot.rest.pruneMembers(guildId, options, reason) + return await bot.rest.pruneMembers(guildId, options, reason); }, searchMembers: async (guildId, query, options) => { return (await bot.rest.searchMembers(guildId, query, options)).map((res) => bot.transformers.member(bot, snakelize(res), { guildId, userId: bot.transformers.snowflake(res.user.id) }), - ) + ); }, bulkBanMembers: async (guildId, options, reason) => { - const res = await bot.rest.bulkBanMembers(guildId, options, reason) + const res = await bot.rest.bulkBanMembers(guildId, options, reason); return { bannedUsers: res.bannedUsers.map((x) => bot.transformers.snowflake(x)), failedUsers: res.failedUsers.map((x) => bot.transformers.snowflake(x)), - } + }; }, getApplicationActivityInstance: async (applicationId, instanceId) => { - return await bot.rest.getApplicationActivityInstance(applicationId, instanceId) + return await bot.rest.getApplicationActivityInstance(applicationId, instanceId); }, listApplicationRoleConnectionsMetadataRecords: async (applicationId) => { - return await bot.rest.listApplicationRoleConnectionsMetadataRecords(applicationId) + return await bot.rest.listApplicationRoleConnectionsMetadataRecords(applicationId); }, updateApplicationRoleConnectionsMetadataRecords: async (applicationId, options) => { - return await bot.rest.updateApplicationRoleConnectionsMetadataRecords(applicationId, options) + return await bot.rest.updateApplicationRoleConnectionsMetadataRecords(applicationId, options); }, createLobby: async (options) => { - return bot.transformers.lobby(bot, snakelize(await bot.rest.createLobby(options))) + return bot.transformers.lobby(bot, snakelize(await bot.rest.createLobby(options))); }, getLobby: async (lobbyId) => { - return bot.transformers.lobby(bot, snakelize(await bot.rest.getLobby(lobbyId))) + return bot.transformers.lobby(bot, snakelize(await bot.rest.getLobby(lobbyId))); }, modifyLobby: async (lobbyId, options) => { - return bot.transformers.lobby(bot, snakelize(await bot.rest.modifyLobby(lobbyId, options))) + return bot.transformers.lobby(bot, snakelize(await bot.rest.modifyLobby(lobbyId, options))); }, addMemberToLobby: async (lobbyId, userId, options) => { - return bot.transformers.lobbyMember(bot, snakelize(await bot.rest.addMemberToLobby(lobbyId, userId, options))) + return bot.transformers.lobbyMember(bot, snakelize(await bot.rest.addMemberToLobby(lobbyId, userId, options))); }, linkChannelToLobby: async (lobbyId, bearerToken, options) => { - return bot.transformers.lobby(bot, snakelize(await bot.rest.linkChannelToLobby(lobbyId, bearerToken, options))) + return bot.transformers.lobby(bot, snakelize(await bot.rest.linkChannelToLobby(lobbyId, bearerToken, options))); }, unlinkChannelToLobby: async (lobbyId, bearerToken) => { - return bot.transformers.lobby(bot, snakelize(await bot.rest.unlinkChannelToLobby(lobbyId, bearerToken))) + return bot.transformers.lobby(bot, snakelize(await bot.rest.unlinkChannelToLobby(lobbyId, bearerToken))); }, // All useless void return functions here addReaction: async (channelId, messageId, reaction) => { - return await bot.rest.addReaction(channelId, messageId, reaction) + return await bot.rest.addReaction(channelId, messageId, reaction); }, addReactions: async (channelId, messageId, reactions, ordered) => { - return await bot.rest.addReactions(channelId, messageId, reactions, ordered) + return await bot.rest.addReactions(channelId, messageId, reactions, ordered); }, addRole: async (guildId, userId, roleId, reason) => { - return await bot.rest.addRole(guildId, userId, roleId, reason) + return await bot.rest.addRole(guildId, userId, roleId, reason); }, addThreadMember: async (channelId, userId) => { - return await bot.rest.addThreadMember(channelId, userId) + return await bot.rest.addThreadMember(channelId, userId); }, addDmRecipient: async (channelId, userId, options) => { - return await bot.rest.addDmRecipient(channelId, userId, options) + return await bot.rest.addDmRecipient(channelId, userId, options); }, addGuildMember: async (guildId, userId, options) => { - return await bot.rest.addGuildMember(guildId, userId, options) + return await bot.rest.addGuildMember(guildId, userId, options); }, deleteAutomodRule: async (guildId, ruleId, reason) => { - return await bot.rest.deleteAutomodRule(guildId, ruleId, reason) + return await bot.rest.deleteAutomodRule(guildId, ruleId, reason); }, deleteChannel: async (channelId, reason) => { - return await bot.rest.deleteChannel(channelId, reason) + return await bot.rest.deleteChannel(channelId, reason); }, deleteChannelPermissionOverride: async (channelId, overwriteId, reason) => { - return await bot.rest.deleteChannelPermissionOverride(channelId, overwriteId, reason) + return await bot.rest.deleteChannelPermissionOverride(channelId, overwriteId, reason); }, deleteEmoji: async (guildId, id, reason) => { - return await bot.rest.deleteEmoji(guildId, id, reason) + return await bot.rest.deleteEmoji(guildId, id, reason); }, deleteApplicationEmoji: async (id) => { - return await bot.rest.deleteApplicationEmoji(id) + return await bot.rest.deleteApplicationEmoji(id); }, deleteFollowupMessage: async (token, messageId) => { - return await bot.rest.deleteFollowupMessage(token, messageId) + return await bot.rest.deleteFollowupMessage(token, messageId); }, deleteGlobalApplicationCommand: async (commandId) => { - return await bot.rest.deleteGlobalApplicationCommand(commandId) + return await bot.rest.deleteGlobalApplicationCommand(commandId); }, deleteGuildApplicationCommand: async (commandId, guildId) => { - return await bot.rest.deleteGuildApplicationCommand(commandId, guildId) + return await bot.rest.deleteGuildApplicationCommand(commandId, guildId); }, deleteGuildSticker: async (guildId, stickerId, reason) => { - return await bot.rest.deleteGuildSticker(guildId, stickerId, reason) + return await bot.rest.deleteGuildSticker(guildId, stickerId, reason); }, deleteGuildTemplate: async (guildId, templateCode) => { - return await bot.rest.deleteGuildTemplate(guildId, templateCode) + return await bot.rest.deleteGuildTemplate(guildId, templateCode); }, deleteIntegration: async (guildId, integrationId, reason) => { - return await bot.rest.deleteIntegration(guildId, integrationId, reason) + return await bot.rest.deleteIntegration(guildId, integrationId, reason); }, deleteInvite: async (inviteCode, reason) => { - return await bot.rest.deleteInvite(inviteCode, reason) + return await bot.rest.deleteInvite(inviteCode, reason); }, deleteMessage: async (channelId, messageId, reason) => { - return await bot.rest.deleteMessage(channelId, messageId, reason) + return await bot.rest.deleteMessage(channelId, messageId, reason); }, deleteMessages: async (channelId, messageIds, reason) => { - return await bot.rest.deleteMessages(channelId, messageIds, reason) + return await bot.rest.deleteMessages(channelId, messageIds, reason); }, deleteOriginalInteractionResponse: async (token) => { - return await bot.rest.deleteOriginalInteractionResponse(token) + return await bot.rest.deleteOriginalInteractionResponse(token); }, deleteOwnReaction: async (channelId, messageId, reaction) => { - return await bot.rest.deleteOwnReaction(channelId, messageId, reaction) + return await bot.rest.deleteOwnReaction(channelId, messageId, reaction); }, deleteReactionsAll: async (channelId, messageId) => { - return await bot.rest.deleteReactionsAll(channelId, messageId) + return await bot.rest.deleteReactionsAll(channelId, messageId); }, deleteReactionsEmoji: async (channelId, messageId, reaction) => { - return await bot.rest.deleteReactionsEmoji(channelId, messageId, reaction) + return await bot.rest.deleteReactionsEmoji(channelId, messageId, reaction); }, deleteRole: async (guildId, roleId, reason) => { - return await bot.rest.deleteRole(guildId, roleId, reason) + return await bot.rest.deleteRole(guildId, roleId, reason); }, deleteScheduledEvent: async (guildId, eventId) => { - return await bot.rest.deleteScheduledEvent(guildId, eventId) + return await bot.rest.deleteScheduledEvent(guildId, eventId); }, deleteStageInstance: async (channelId, reason) => { - return await bot.rest.deleteStageInstance(channelId, reason) + return await bot.rest.deleteStageInstance(channelId, reason); }, deleteUserReaction: async (channelId, messageId, userId, reaction) => { - return await bot.rest.deleteUserReaction(channelId, messageId, userId, reaction) + return await bot.rest.deleteUserReaction(channelId, messageId, userId, reaction); }, deleteWebhook: async (webhookId, reason) => { - return await bot.rest.deleteWebhook(webhookId, reason) + return await bot.rest.deleteWebhook(webhookId, reason); }, deleteWebhookMessage: async (webhookId, token, messageId, options) => { - return await bot.rest.deleteWebhookMessage(webhookId, token, messageId, options) + return await bot.rest.deleteWebhookMessage(webhookId, token, messageId, options); }, deleteWebhookWithToken: async (webhookId, token) => { - return await bot.rest.deleteWebhookWithToken(webhookId, token) + return await bot.rest.deleteWebhookWithToken(webhookId, token); }, editChannelPermissionOverrides: async (channelId, options, reason) => { - return await bot.rest.editChannelPermissionOverrides(channelId, options, reason) + return await bot.rest.editChannelPermissionOverrides(channelId, options, reason); }, editChannelPositions: async (guildId, channelPositions) => { - return await bot.rest.editChannelPositions(guildId, channelPositions) + return await bot.rest.editChannelPositions(guildId, channelPositions); }, editOwnVoiceState: async (guildId, options) => { - return await bot.rest.editOwnVoiceState(guildId, options) + return await bot.rest.editOwnVoiceState(guildId, options); }, editUserVoiceState: async (guildId, options) => { - return await bot.rest.editUserVoiceState(guildId, options) + return await bot.rest.editUserVoiceState(guildId, options); }, editUserApplicationRoleConnection: async (bearerToken, applicationId, options) => { - return await bot.rest.editUserApplicationRoleConnection(bearerToken, applicationId, options) + return await bot.rest.editUserApplicationRoleConnection(bearerToken, applicationId, options); }, joinThread: async (channelId) => { - return await bot.rest.joinThread(channelId) + return await bot.rest.joinThread(channelId); }, leaveGuild: async (guildId) => { - return await bot.rest.leaveGuild(guildId) + return await bot.rest.leaveGuild(guildId); }, leaveThread: async (channelId) => { - return await bot.rest.leaveThread(channelId) + return await bot.rest.leaveThread(channelId); }, removeRole: async (guildId, userId, roleId, reason) => { - return await bot.rest.removeRole(guildId, userId, roleId, reason) + return await bot.rest.removeRole(guildId, userId, roleId, reason); }, removeThreadMember: async (channelId, userId) => { - return await bot.rest.removeThreadMember(channelId, userId) + return await bot.rest.removeThreadMember(channelId, userId); }, removeDmRecipient: async (channelId, userId) => { - return await bot.rest.removeDmRecipient(channelId, userId) + return await bot.rest.removeDmRecipient(channelId, userId); }, sendInteractionResponse: async (interactionId, token, options, params) => { - const response = await bot.rest.sendInteractionResponse(interactionId, token, options, params) + const response = await bot.rest.sendInteractionResponse(interactionId, token, options, params); - if (!response) return + if (!response) return; - return bot.transformers.interactionCallbackResponse(bot, snakelize(response)) + return bot.transformers.interactionCallbackResponse(bot, snakelize(response)); }, triggerTypingIndicator: async (channelId) => { - return await bot.rest.triggerTypingIndicator(channelId) + return await bot.rest.triggerTypingIndicator(channelId); }, banMember: async (guildId, userId, options, reason) => { - return await bot.rest.banMember(guildId, userId, options, reason) + return await bot.rest.banMember(guildId, userId, options, reason); }, kickMember: async (guildId, userId, reason) => { - return await bot.rest.kickMember(guildId, userId, reason) + return await bot.rest.kickMember(guildId, userId, reason); }, pinMessage: async (channelId, messageId, reason) => { - return await bot.rest.pinMessage(channelId, messageId, reason) + return await bot.rest.pinMessage(channelId, messageId, reason); }, unbanMember: async (guildId, userId, reason) => { - return await bot.rest.unbanMember(guildId, userId, reason) + return await bot.rest.unbanMember(guildId, userId, reason); }, unpinMessage: async (channelId, messageId, reason) => { - return await bot.rest.unpinMessage(channelId, messageId, reason) + return await bot.rest.unpinMessage(channelId, messageId, reason); }, getGuildOnboarding: async (guildId) => { - return bot.transformers.guildOnboarding(bot, snakelize(await bot.rest.getGuildOnboarding(guildId))) + return bot.transformers.guildOnboarding(bot, snakelize(await bot.rest.getGuildOnboarding(guildId))); }, editGuildOnboarding: async (guildId, options, reason) => { - return bot.transformers.guildOnboarding(bot, snakelize(await bot.rest.editGuildOnboarding(guildId, options, reason))) + return bot.transformers.guildOnboarding(bot, snakelize(await bot.rest.editGuildOnboarding(guildId, options, reason))); }, listEntitlements: async (applicationId, options) => { - return (await bot.rest.listEntitlements(applicationId, options)).map((entitlement) => bot.transformers.entitlement(bot, snakelize(entitlement))) + return (await bot.rest.listEntitlements(applicationId, options)).map((entitlement) => + bot.transformers.entitlement(bot, snakelize(entitlement)), + ); }, getEntitlement: async (applicationId, entitlementId) => { - return bot.transformers.entitlement(bot, snakelize(await bot.rest.getEntitlement(applicationId, entitlementId))) + return bot.transformers.entitlement(bot, snakelize(await bot.rest.getEntitlement(applicationId, entitlementId))); }, createTestEntitlement: async (applicationId, body) => { // @ts-expect-error createTestEntitlement gives a partial, and this method returns a partial return bot.transformers.entitlement(bot, snakelize(await bot.rest.createTestEntitlement(applicationId, body))) as Partial< typeof bot.transformers.$inferredTypes.entitlement - > + >; }, deleteTestEntitlement: async (applicationId, entitlementId) => { - await bot.rest.deleteTestEntitlement(applicationId, entitlementId) + await bot.rest.deleteTestEntitlement(applicationId, entitlementId); }, listSkus: async (applicationId) => { - return (await bot.rest.listSkus(applicationId)).map((sku) => bot.transformers.sku(bot, snakelize(sku))) + return (await bot.rest.listSkus(applicationId)).map((sku) => bot.transformers.sku(bot, snakelize(sku))); }, getSubscription: async (skuId, subscriptionId) => { - return bot.transformers.subscription(bot, snakelize(await bot.rest.getSubscription(skuId, subscriptionId))) + return bot.transformers.subscription(bot, snakelize(await bot.rest.getSubscription(skuId, subscriptionId))); }, listSubscriptions: async (skuId, options) => { - return (await bot.rest.listSubscriptions(skuId, options)).map((subscription) => bot.transformers.subscription(bot, snakelize(subscription))) + return (await bot.rest.listSubscriptions(skuId, options)).map((subscription) => bot.transformers.subscription(bot, snakelize(subscription))); }, sendSoundboardSound: async (channelId, options) => { - await bot.rest.sendSoundboardSound(channelId, options) + await bot.rest.sendSoundboardSound(channelId, options); }, listDefaultSoundboardSounds: async () => { - return (await bot.rest.listDefaultSoundboardSounds()).map((sound) => bot.transformers.soundboardSound(bot, snakelize(sound))) + return (await bot.rest.listDefaultSoundboardSounds()).map((sound) => bot.transformers.soundboardSound(bot, snakelize(sound))); }, listGuildSoundboardSounds: async (guildId) => { - const res = await bot.rest.listGuildSoundboardSounds(guildId) + const res = await bot.rest.listGuildSoundboardSounds(guildId); return { items: res.items.map((sound) => bot.transformers.soundboardSound(bot, snakelize(sound))), - } + }; }, getGuildSoundboardSound: async (guildId, soundId) => { - return bot.transformers.soundboardSound(bot, snakelize(await bot.rest.getGuildSoundboardSound(guildId, soundId))) + return bot.transformers.soundboardSound(bot, snakelize(await bot.rest.getGuildSoundboardSound(guildId, soundId))); }, createGuildSoundboardSound: async (guildId, options, reason) => { - return bot.transformers.soundboardSound(bot, snakelize(await bot.rest.createGuildSoundboardSound(guildId, options, reason))) + return bot.transformers.soundboardSound(bot, snakelize(await bot.rest.createGuildSoundboardSound(guildId, options, reason))); }, modifyGuildSoundboardSound: async (guildId, soundId, options, reason) => { - return bot.transformers.soundboardSound(bot, snakelize(await bot.rest.modifyGuildSoundboardSound(guildId, soundId, options, reason))) + return bot.transformers.soundboardSound(bot, snakelize(await bot.rest.modifyGuildSoundboardSound(guildId, soundId, options, reason))); }, deleteGuildSoundboardSound: async (guildId, soundId, reason) => { - await bot.rest.deleteGuildSoundboardSound(guildId, soundId, reason) + await bot.rest.deleteGuildSoundboardSound(guildId, soundId, reason); }, deleteLobby: async (lobbyId) => { - await bot.rest.deleteLobby(lobbyId) + await bot.rest.deleteLobby(lobbyId); }, removeMemberFromLobby: async (lobbyId, userId) => { - await bot.rest.removeMemberFromLobby(lobbyId, userId) + await bot.rest.removeMemberFromLobby(lobbyId, userId); }, leaveLobby: async (lobbyId, bearerToken) => { - await bot.rest.leaveLobby(lobbyId, bearerToken) + await bot.rest.leaveLobby(lobbyId, bearerToken); }, - } + }; } export type BotHelpers = { @@ -849,386 +851,396 @@ export type BotHelpers Promise> - createChannel: (guildId: BigString, options: CreateGuildChannel, reason?: string) => Promise> - createEmoji: (guildId: BigString, options: CreateGuildEmoji, reason?: string) => Promise> - createApplicationEmoji: (options: CreateApplicationEmoji) => Promise> + ) => Promise>; + createChannel: (guildId: BigString, options: CreateGuildChannel, reason?: string) => Promise>; + createEmoji: (guildId: BigString, options: CreateGuildEmoji, reason?: string) => Promise>; + createApplicationEmoji: (options: CreateApplicationEmoji) => Promise>; createForumThread: ( channelId: BigString, options: CreateForumPostWithMessage, reason?: string, - ) => Promise> + ) => Promise>; createGlobalApplicationCommand: ( command: CreateApplicationCommand, options?: CreateGlobalApplicationCommandOptions, - ) => Promise> + ) => Promise>; createGuildApplicationCommand: ( command: CreateApplicationCommand, guildId: BigString, options?: CreateGuildApplicationCommandOptions, - ) => Promise> + ) => Promise>; createGuildSticker: ( guildId: BigString, options: CreateGuildStickerOptions, reason?: string, - ) => Promise> - createGuildTemplate: (guildId: BigString, options: CreateTemplate) => Promise> - createInvite: (channelId: BigString, options?: CreateChannelInvite, reason?: string) => Promise> - getGuildRoleMemberCounts: (guildId: BigString) => Promise> - createRole: (guildId: BigString, options: CreateGuildRole, reason?: string) => Promise> + ) => Promise>; + createGuildTemplate: (guildId: BigString, options: CreateTemplate) => Promise>; + createInvite: (channelId: BigString, options?: CreateChannelInvite, reason?: string) => Promise>; + getGuildRoleMemberCounts: (guildId: BigString) => Promise>; + createRole: (guildId: BigString, options: CreateGuildRole, reason?: string) => Promise>; createScheduledEvent: ( guildId: BigString, options: CreateScheduledEvent, reason?: string, - ) => Promise> - createStageInstance: (options: CreateStageInstance, reason?: string) => Promise> - createWebhook: (channelId: BigString, options: CreateWebhook, reason?: string) => Promise> + ) => Promise>; + createStageInstance: (options: CreateStageInstance, reason?: string) => Promise>; + createWebhook: (channelId: BigString, options: CreateWebhook, reason?: string) => Promise>; editApplicationCommandPermissions: ( guildId: BigString, commandId: BigString, bearerToken: string, options: Camelize[], - ) => Promise> + ) => Promise>; editAutomodRule: ( guildId: BigString, ruleId: BigString, options: Partial, reason?: string, - ) => Promise> + ) => Promise>; editBotProfile: (options: { - username?: string - botAvatarURL?: string | null - botBannerURL?: string | null - }) => Promise> - editChannel: (channelId: BigString, options: ModifyChannel, reason?: string) => Promise> - editEmoji: (guildId: BigString, id: BigString, options: ModifyGuildEmoji, reason?: string) => Promise> - editApplicationEmoji: (id: BigString, options: ModifyApplicationEmoji) => Promise> + username?: string; + botAvatarURL?: string | null; + botBannerURL?: string | null; + }) => Promise>; + editChannel: (channelId: BigString, options: ModifyChannel, reason?: string) => Promise>; + editEmoji: (guildId: BigString, id: BigString, options: ModifyGuildEmoji, reason?: string) => Promise>; + editApplicationEmoji: (id: BigString, options: ModifyApplicationEmoji) => Promise>; editFollowupMessage: ( token: string, messageId: BigString, options: InteractionCallbackData, - ) => Promise> + ) => Promise>; editGlobalApplicationCommand: ( commandId: BigString, options: CreateApplicationCommand, - ) => Promise> - editGuild: (guildId: BigString, options: ModifyGuild, reason?: string) => Promise> + ) => Promise>; + editGuild: (guildId: BigString, options: ModifyGuild, reason?: string) => Promise>; editGuildApplicationCommand: ( commandId: BigString, guildId: BigString, options: CreateApplicationCommand, - ) => Promise> + ) => Promise>; editGuildSticker: ( guildId: BigString, stickerId: BigString, options: AtLeastOne, reason?: string, - ) => Promise> + ) => Promise>; editGuildTemplate: ( guildId: BigString, templateCode: string, options: ModifyGuildTemplate, - ) => Promise> - editMessage: (channelId: BigString, messageId: BigString, options: EditMessage) => Promise> - editOriginalInteractionResponse: (token: string, options: InteractionCallbackData) => Promise> - editRole: (guildId: BigString, roleId: BigString, options: EditGuildRole, reason?: string) => Promise> - editRolePositions: (guildId: BigString, options: ModifyRolePositions[], reason?: string) => Promise[]> + ) => Promise>; + editMessage: (channelId: BigString, messageId: BigString, options: EditMessage) => Promise>; + editOriginalInteractionResponse: (token: string, options: InteractionCallbackData) => Promise>; + editRole: (guildId: BigString, roleId: BigString, options: EditGuildRole, reason?: string) => Promise>; + editRolePositions: (guildId: BigString, options: ModifyRolePositions[], reason?: string) => Promise[]>; editScheduledEvent: ( guildId: BigString, eventId: BigString, options: Partial, reason?: string, - ) => Promise> - editStageInstance: (channelId: BigString, topic: string, reason?: string) => Promise> - editWebhook: (webhookId: BigString, options: ModifyWebhook, reason?: string) => Promise> + ) => Promise>; + editStageInstance: (channelId: BigString, topic: string, reason?: string) => Promise>; + editWebhook: (webhookId: BigString, options: ModifyWebhook, reason?: string) => Promise>; editWebhookMessage: ( webhookId: BigString, token: string, messageId: BigString, options: EditWebhookMessageOptions, - ) => Promise> + ) => Promise>; editWebhookWithToken: ( webhookId: BigString, token: string, options: Omit, - ) => Promise> + ) => Promise>; editWelcomeScreen: ( guildId: BigString, options: ModifyGuildWelcomeScreen, reason?: string, - ) => Promise> + ) => Promise>; editWidgetSettings: ( guildId: BigString, options: Camelize, reason?: string, - ) => Promise> + ) => Promise>; editUserApplicationRoleConnection: ( bearerToken: string, applicationId: BigString, options: Camelize, - ) => Promise> - executeWebhook: (webhookId: BigString, token: string, options: ExecuteWebhook) => Promise | undefined> - followAnnouncement: (sourceChannelId: BigString, targetChannelId: BigString) => Promise> + ) => Promise>; + executeWebhook: ( + webhookId: BigString, + token: string, + options: ExecuteWebhook, + ) => Promise | undefined>; + followAnnouncement: (sourceChannelId: BigString, targetChannelId: BigString) => Promise>; getActiveThreads: ( guildId: BigString, - ) => Promise<{ threads: SetupDesiredProps[]; members: SetupDesiredProps[] }> - getApplicationInfo: () => Promise> - editApplicationInfo: (body: EditApplication) => Promise> - getCurrentAuthenticationInfo: (bearerToken: string) => Promise> - exchangeToken: (clientId: BigString, clientSecret: string, options: Camelize) => Promise> - revokeToken: (clientId: BigString, clientSecret: string, options: Camelize) => Promise + ) => Promise<{ threads: SetupDesiredProps[]; members: SetupDesiredProps[] }>; + getApplicationInfo: () => Promise>; + editApplicationInfo: (body: EditApplication) => Promise>; + getCurrentAuthenticationInfo: (bearerToken: string) => Promise>; + exchangeToken: ( + clientId: BigString, + clientSecret: string, + options: Camelize, + ) => Promise>; + revokeToken: (clientId: BigString, clientSecret: string, options: Camelize) => Promise; getApplicationCommandPermission: ( guildId: BigString, commandId: BigString, options?: GetApplicationCommandPermissionOptions, - ) => Promise> + ) => Promise>; getApplicationCommandPermissions: ( guildId: BigString, options?: GetApplicationCommandPermissionOptions, - ) => Promise[]> - getAuditLog: (guildId: BigString, options?: GetGuildAuditLog) => Promise> - getAutomodRule: (guildId: BigString, ruleId: BigString) => Promise> - getAutomodRules: (guildId: BigString) => Promise[]> - getAvailableVoiceRegions: () => Promise[]> - getBan: (guildId: BigString, userId: BigString) => Promise> - getBans: (guildId: BigString, options?: GetBans) => Promise[]> - getChannel: (channelId: BigString) => Promise> - getChannelInvites: (channelId: BigString) => Promise[]> - getChannels: (guildId: BigString) => Promise[]> - getChannelWebhooks: (channelId: BigString) => Promise[]> - getDmChannel: (userId: BigString) => Promise> - getGroupDmChannel: (options: CreateGroupDmOptions) => Promise> - getEmoji: (guildId: BigString, emojiId: BigString) => Promise> - getApplicationEmoji: (emojiId: BigString) => Promise> - getEmojis: (guildId: BigString) => Promise[]> - getApplicationEmojis: () => Promise<{ items: SetupDesiredProps[] }> - getFollowupMessage: (token: string, messageId: BigString) => Promise> - getGatewayBot: () => Promise> - getGlobalApplicationCommand: (commandId: BigString) => Promise> - getGlobalApplicationCommands: (options?: GetGlobalApplicationCommandsOptions) => Promise[]> - getGuild: (guildId: BigString, options?: { counts?: boolean }) => Promise> - getGuilds: (bearerToken: string, options?: GetUserGuilds) => Promise>[]> - getGuildApplicationCommand: (commandId: BigString, guildId: BigString) => Promise> + ) => Promise[]>; + getAuditLog: (guildId: BigString, options?: GetGuildAuditLog) => Promise>; + getAutomodRule: (guildId: BigString, ruleId: BigString) => Promise>; + getAutomodRules: (guildId: BigString) => Promise[]>; + getAvailableVoiceRegions: () => Promise[]>; + getBan: (guildId: BigString, userId: BigString) => Promise>; + getBans: (guildId: BigString, options?: GetBans) => Promise[]>; + getChannel: (channelId: BigString) => Promise>; + getChannelInvites: (channelId: BigString) => Promise[]>; + getChannels: (guildId: BigString) => Promise[]>; + getChannelWebhooks: (channelId: BigString) => Promise[]>; + getDmChannel: (userId: BigString) => Promise>; + getGroupDmChannel: (options: CreateGroupDmOptions) => Promise>; + getEmoji: (guildId: BigString, emojiId: BigString) => Promise>; + getApplicationEmoji: (emojiId: BigString) => Promise>; + getEmojis: (guildId: BigString) => Promise[]>; + getApplicationEmojis: () => Promise<{ items: SetupDesiredProps[] }>; + getFollowupMessage: (token: string, messageId: BigString) => Promise>; + getGatewayBot: () => Promise>; + getGlobalApplicationCommand: (commandId: BigString) => Promise>; + getGlobalApplicationCommands: ( + options?: GetGlobalApplicationCommandsOptions, + ) => Promise[]>; + getGuild: (guildId: BigString, options?: { counts?: boolean }) => Promise>; + getGuilds: (bearerToken: string, options?: GetUserGuilds) => Promise>[]>; + getGuildApplicationCommand: (commandId: BigString, guildId: BigString) => Promise>; getGuildApplicationCommands: ( guildId: BigString, options?: GetGuildApplicationCommandsOptions, - ) => Promise[]> - getGuildPreview: (guildId: BigString) => Promise> - getGuildSticker: (guildId: BigString, stickerId: BigString) => Promise> - getGuildStickers: (guildId: BigString) => Promise[]> - getGuildTemplate: (templateCode: string) => Promise> - getGuildTemplates: (guildId: BigString) => Promise[]> - getGuildWebhooks: (guildId: BigString) => Promise[]> - getIntegrations: (guildId: BigString) => Promise[]> - getInvite: (inviteCode: string, options?: GetInvite) => Promise> - getInvites: (guildId: BigString) => Promise[]> - getMessage: (channelId: BigString, messageId: BigString) => Promise> - getMessages: (channelId: BigString, options?: GetMessagesOptions) => Promise[]> - getStickerPack: (stickerPackId: BigString) => Promise> - getStickerPacks: () => Promise[]> - getOriginalInteractionResponse: (token: string) => Promise> + ) => Promise[]>; + getGuildPreview: (guildId: BigString) => Promise>; + getGuildSticker: (guildId: BigString, stickerId: BigString) => Promise>; + getGuildStickers: (guildId: BigString) => Promise[]>; + getGuildTemplate: (templateCode: string) => Promise>; + getGuildTemplates: (guildId: BigString) => Promise[]>; + getGuildWebhooks: (guildId: BigString) => Promise[]>; + getIntegrations: (guildId: BigString) => Promise[]>; + getInvite: (inviteCode: string, options?: GetInvite) => Promise>; + getInvites: (guildId: BigString) => Promise[]>; + getMessage: (channelId: BigString, messageId: BigString) => Promise>; + getMessages: (channelId: BigString, options?: GetMessagesOptions) => Promise[]>; + getStickerPack: (stickerPackId: BigString) => Promise>; + getStickerPacks: () => Promise[]>; + getOriginalInteractionResponse: (token: string) => Promise>; getChannelPins: ( channelId: BigString, options?: GetChannelPinsOptions, - ) => Promise<{ items: SetupDesiredProps[]; hasMore: boolean }> + ) => Promise<{ items: SetupDesiredProps[]; hasMore: boolean }>; /** @deprecated Use {@link BotHelpers.getChannelPins} instead */ - getPinnedMessages: (channelId: BigString) => Promise[]> - getPrivateArchivedThreads: (channelId: BigString, options?: ListArchivedThreads) => Promise> - getPrivateJoinedArchivedThreads: (channelId: BigString, options?: ListArchivedThreads) => Promise> - getPruneCount: (guildId: BigString, options?: GetGuildPruneCountQuery) => Promise> - getPublicArchivedThreads: (channelId: BigString, options?: ListArchivedThreads) => Promise> - getRoles: (guildId: BigString) => Promise[]> - getRole: (guildId: BigString, roleId: BigString) => Promise> + getPinnedMessages: (channelId: BigString) => Promise[]>; + getPrivateArchivedThreads: (channelId: BigString, options?: ListArchivedThreads) => Promise>; + getPrivateJoinedArchivedThreads: (channelId: BigString, options?: ListArchivedThreads) => Promise>; + getPruneCount: (guildId: BigString, options?: GetGuildPruneCountQuery) => Promise>; + getPublicArchivedThreads: (channelId: BigString, options?: ListArchivedThreads) => Promise>; + getRoles: (guildId: BigString) => Promise[]>; + getRole: (guildId: BigString, roleId: BigString) => Promise>; getScheduledEvent: ( guildId: BigString, eventId: BigString, options?: { withUserCount?: boolean }, - ) => Promise> - getScheduledEvents: (guildId: BigString, options?: GetScheduledEvents) => Promise[]> + ) => Promise>; + getScheduledEvents: (guildId: BigString, options?: GetScheduledEvents) => Promise[]>; getScheduledEventUsers: ( guildId: BigString, eventId: BigString, options?: GetScheduledEventUsers, - ) => Promise; member?: SetupDesiredProps }>> - getSessionInfo: () => Promise> - getStageInstance: (channelId: BigString) => Promise> - getOwnVoiceState: (guildId: BigString) => Promise> - getUserVoiceState: (guildId: BigString, userId: BigString) => Promise> - getSticker: (stickerId: BigString) => Promise> + ) => Promise; member?: SetupDesiredProps }>>; + getSessionInfo: () => Promise>; + getStageInstance: (channelId: BigString) => Promise>; + getOwnVoiceState: (guildId: BigString) => Promise>; + getUserVoiceState: (guildId: BigString, userId: BigString) => Promise>; + getSticker: (stickerId: BigString) => Promise>; getThreadMember: ( channelId: BigString, userId: BigString, options?: GetThreadMember, extra?: ThreadMemberTransformerExtra, - ) => Promise> + ) => Promise>; getThreadMembers: ( channelId: BigString, options?: ListThreadMembers, extra?: ThreadMemberTransformerExtra, - ) => Promise[]> + ) => Promise[]>; getReactions: ( channelId: BigString, messageId: BigString, reaction: string, options?: GetReactions, - ) => Promise[]> - getUser: (id: BigString) => Promise> - getCurrentUser: (bearerToken: string) => Promise> - getUserConnections: (bearerToken: string) => Promise[]> - getUserApplicationRoleConnection: (bearerToken: string, applicationId: BigString) => Promise> - getVanityUrl: (guildId: BigString) => Promise> - getVoiceRegions: (guildId: BigString) => Promise[]> - getWebhook: (webhookId: BigString) => Promise> + ) => Promise[]>; + getUser: (id: BigString) => Promise>; + getCurrentUser: (bearerToken: string) => Promise>; + getUserConnections: (bearerToken: string) => Promise[]>; + getUserApplicationRoleConnection: (bearerToken: string, applicationId: BigString) => Promise>; + getVanityUrl: (guildId: BigString) => Promise>; + getVoiceRegions: (guildId: BigString) => Promise[]>; + getWebhook: (webhookId: BigString) => Promise>; getWebhookMessage: ( webhookId: BigString, token: string, messageId: BigString, options?: GetWebhookMessageOptions, - ) => Promise> - getWebhookWithToken: (webhookId: BigString, token: string) => Promise> - getWelcomeScreen: (guildId: BigString) => Promise> - getWidget: (guildId: BigString) => Promise> - getWidgetSettings: (guildId: BigString) => Promise> - publishMessage: (channelId: BigString, messageId: BigString) => Promise> - sendMessage: (channelId: BigString, options: CreateMessageOptions) => Promise> - sendFollowupMessage: (token: string, options: InteractionCallbackData) => Promise> + ) => Promise>; + getWebhookWithToken: (webhookId: BigString, token: string) => Promise>; + getWelcomeScreen: (guildId: BigString) => Promise>; + getWidget: (guildId: BigString) => Promise>; + getWidgetSettings: (guildId: BigString) => Promise>; + publishMessage: (channelId: BigString, messageId: BigString) => Promise>; + sendMessage: (channelId: BigString, options: CreateMessageOptions) => Promise>; + sendFollowupMessage: (token: string, options: InteractionCallbackData) => Promise>; startThreadWithMessage: ( channelId: BigString, messageId: BigString, options: StartThreadWithMessage, reason?: string, - ) => Promise> + ) => Promise>; startThreadWithoutMessage: ( channelId: BigString, options: StartThreadWithoutMessage, reason?: string, - ) => Promise> - syncGuildTemplate: (guildId: BigString) => Promise> + ) => Promise>; + syncGuildTemplate: (guildId: BigString) => Promise>; upsertGlobalApplicationCommands: ( commands: CreateApplicationCommand[], options?: UpsertGlobalApplicationCommandOptions, - ) => Promise[]> + ) => Promise[]>; upsertGuildApplicationCommands: ( guildId: BigString, commands: CreateApplicationCommand[], options?: UpsertGuildApplicationCommandOptions, - ) => Promise[]> - editBotMember: (guildId: BigString, options: EditBotMemberOptions, reason?: string) => Promise> + ) => Promise[]>; + editBotMember: (guildId: BigString, options: EditBotMemberOptions, reason?: string) => Promise>; editMember: ( guildId: BigString, userId: BigString, options: ModifyGuildMember, reason?: string, - ) => Promise> - getMember: (guildId: BigString, userId: BigString) => Promise> - getCurrentMember: (guildId: BigString, bearerToken: string) => Promise> - getMembers: (guildId: BigString, options: ListGuildMembers) => Promise[]> - pruneMembers: (guildId: BigString, options: BeginGuildPrune, reason?: string) => Promise<{ pruned: number | null }> + ) => Promise>; + getMember: (guildId: BigString, userId: BigString) => Promise>; + getCurrentMember: (guildId: BigString, bearerToken: string) => Promise>; + getMembers: (guildId: BigString, options: ListGuildMembers) => Promise[]>; + pruneMembers: (guildId: BigString, options: BeginGuildPrune, reason?: string) => Promise<{ pruned: number | null }>; searchMembers: ( guildId: BigString, query: string, options?: Omit, - ) => Promise[]> - bulkBanMembers: (guildId: BigString, options: CreateGuildBulkBan, reason?: string) => Promise<{ bannedUsers: bigint[]; failedUsers: bigint[] }> - getApplicationActivityInstance: (applicationId: BigString, instanceId: string) => Promise> - listApplicationRoleConnectionsMetadataRecords: (applicationId: BigString) => Promise[]> + ) => Promise[]>; + bulkBanMembers: (guildId: BigString, options: CreateGuildBulkBan, reason?: string) => Promise<{ bannedUsers: bigint[]; failedUsers: bigint[] }>; + getApplicationActivityInstance: (applicationId: BigString, instanceId: string) => Promise>; + listApplicationRoleConnectionsMetadataRecords: (applicationId: BigString) => Promise[]>; updateApplicationRoleConnectionsMetadataRecords: ( applicationId: BigString, options: Camelize[], - ) => Promise[]> - createLobby: (options: CreateLobby) => Promise> - getLobby: (lobbyId: BigString) => Promise> - modifyLobby: (lobbyId: BigString, options: ModifyLobby) => Promise> - addMemberToLobby: (lobbyId: BigString, userId: BigString, options: AddLobbyMember) => Promise> - linkChannelToLobby: (lobbyId: BigString, bearerToken: string, options: LinkChannelToLobby) => Promise> - unlinkChannelToLobby: (lobbyId: BigString, bearerToken: string) => Promise> + ) => Promise[]>; + createLobby: (options: CreateLobby) => Promise>; + getLobby: (lobbyId: BigString) => Promise>; + modifyLobby: (lobbyId: BigString, options: ModifyLobby) => Promise>; + addMemberToLobby: (lobbyId: BigString, userId: BigString, options: AddLobbyMember) => Promise>; + linkChannelToLobby: (lobbyId: BigString, bearerToken: string, options: LinkChannelToLobby) => Promise>; + unlinkChannelToLobby: (lobbyId: BigString, bearerToken: string) => Promise>; // functions return Void so dont need any special handling - addReaction: (channelId: BigString, messageId: BigString, reaction: string) => Promise - addReactions: (channelId: BigString, messageId: BigString, reactions: string[], ordered?: boolean) => Promise - addRole: (guildId: BigString, userId: BigString, roleId: BigString, reason?: string) => Promise - addThreadMember: (channelId: BigString, userId: BigString) => Promise - addDmRecipient: (channelId: BigString, userId: BigString, options: AddDmRecipientOptions) => Promise - addGuildMember: (guildId: BigString, userId: BigString, options: AddGuildMemberOptions) => Promise - deleteAutomodRule: (guildId: BigString, ruleId: BigString, reason?: string) => Promise - deleteChannel: (channelId: BigString, reason?: string) => Promise - deleteChannelPermissionOverride: (channelId: BigString, overwriteId: BigString, reason?: string) => Promise - deleteEmoji: (guildId: BigString, id: BigString, reason?: string) => Promise - deleteApplicationEmoji: (id: BigString) => Promise - deleteFollowupMessage: (token: string, messageId: BigString) => Promise - deleteGlobalApplicationCommand: (commandId: BigString) => Promise - deleteGuildApplicationCommand: (commandId: BigString, guildId: BigString) => Promise - deleteGuildSticker: (guildId: BigString, stickerId: BigString, reason?: string) => Promise - deleteGuildTemplate: (guildId: BigString, templateCode: string) => Promise - deleteIntegration: (guildId: BigString, integrationId: BigString, reason?: string) => Promise - deleteInvite: (inviteCode: string, reason?: string) => Promise - deleteMessage: (channelId: BigString, messageId: BigString, reason?: string) => Promise - deleteMessages: (channelId: BigString, messageIds: BigString[], reason?: string) => Promise - deleteOriginalInteractionResponse: (token: string) => Promise - deleteOwnReaction: (channelId: BigString, messageId: BigString, reaction: string) => Promise - deleteReactionsAll: (channelId: BigString, messageId: BigString) => Promise - deleteReactionsEmoji: (channelId: BigString, messageId: BigString, reaction: string) => Promise - deleteRole: (guildId: BigString, roleId: BigString, reason?: string) => Promise - deleteScheduledEvent: (guildId: BigString, eventId: BigString) => Promise - deleteStageInstance: (channelId: BigString, reason?: string) => Promise - deleteUserReaction: (channelId: BigString, messageId: BigString, userId: BigString, reaction: string) => Promise - deleteWebhook: (webhookId: BigString, reason?: string) => Promise - deleteWebhookMessage: (webhookId: BigString, token: string, messageId: BigString, options?: DeleteWebhookMessageOptions) => Promise - deleteWebhookWithToken: (webhookId: BigString, token: string) => Promise - editChannelPermissionOverrides: (channelId: BigString, options: EditChannelPermissionOverridesOptions, reason?: string) => Promise - editChannelPositions: (guildId: BigString, channelPositions: ModifyGuildChannelPositions[]) => Promise - editOwnVoiceState: (guildId: BigString, options: EditOwnVoiceState) => Promise - editUserVoiceState: (guildId: BigString, options: EditUserVoiceState) => Promise - joinThread: (channelId: BigString) => Promise - leaveGuild: (guildId: BigString) => Promise - leaveThread: (channelId: BigString) => Promise - removeRole: (guildId: BigString, userId: BigString, roleId: BigString, reason?: string) => Promise - removeThreadMember: (channelId: BigString, userId: BigString) => Promise - removeDmRecipient: (channelId: BigString, userId: BigString) => Promise + addReaction: (channelId: BigString, messageId: BigString, reaction: string) => Promise; + addReactions: (channelId: BigString, messageId: BigString, reactions: string[], ordered?: boolean) => Promise; + addRole: (guildId: BigString, userId: BigString, roleId: BigString, reason?: string) => Promise; + addThreadMember: (channelId: BigString, userId: BigString) => Promise; + addDmRecipient: (channelId: BigString, userId: BigString, options: AddDmRecipientOptions) => Promise; + addGuildMember: (guildId: BigString, userId: BigString, options: AddGuildMemberOptions) => Promise; + deleteAutomodRule: (guildId: BigString, ruleId: BigString, reason?: string) => Promise; + deleteChannel: (channelId: BigString, reason?: string) => Promise; + deleteChannelPermissionOverride: (channelId: BigString, overwriteId: BigString, reason?: string) => Promise; + deleteEmoji: (guildId: BigString, id: BigString, reason?: string) => Promise; + deleteApplicationEmoji: (id: BigString) => Promise; + deleteFollowupMessage: (token: string, messageId: BigString) => Promise; + deleteGlobalApplicationCommand: (commandId: BigString) => Promise; + deleteGuildApplicationCommand: (commandId: BigString, guildId: BigString) => Promise; + deleteGuildSticker: (guildId: BigString, stickerId: BigString, reason?: string) => Promise; + deleteGuildTemplate: (guildId: BigString, templateCode: string) => Promise; + deleteIntegration: (guildId: BigString, integrationId: BigString, reason?: string) => Promise; + deleteInvite: (inviteCode: string, reason?: string) => Promise; + deleteMessage: (channelId: BigString, messageId: BigString, reason?: string) => Promise; + deleteMessages: (channelId: BigString, messageIds: BigString[], reason?: string) => Promise; + deleteOriginalInteractionResponse: (token: string) => Promise; + deleteOwnReaction: (channelId: BigString, messageId: BigString, reaction: string) => Promise; + deleteReactionsAll: (channelId: BigString, messageId: BigString) => Promise; + deleteReactionsEmoji: (channelId: BigString, messageId: BigString, reaction: string) => Promise; + deleteRole: (guildId: BigString, roleId: BigString, reason?: string) => Promise; + deleteScheduledEvent: (guildId: BigString, eventId: BigString) => Promise; + deleteStageInstance: (channelId: BigString, reason?: string) => Promise; + deleteUserReaction: (channelId: BigString, messageId: BigString, userId: BigString, reaction: string) => Promise; + deleteWebhook: (webhookId: BigString, reason?: string) => Promise; + deleteWebhookMessage: (webhookId: BigString, token: string, messageId: BigString, options?: DeleteWebhookMessageOptions) => Promise; + deleteWebhookWithToken: (webhookId: BigString, token: string) => Promise; + editChannelPermissionOverrides: (channelId: BigString, options: EditChannelPermissionOverridesOptions, reason?: string) => Promise; + editChannelPositions: (guildId: BigString, channelPositions: ModifyGuildChannelPositions[]) => Promise; + editOwnVoiceState: (guildId: BigString, options: EditOwnVoiceState) => Promise; + editUserVoiceState: (guildId: BigString, options: EditUserVoiceState) => Promise; + joinThread: (channelId: BigString) => Promise; + leaveGuild: (guildId: BigString) => Promise; + leaveThread: (channelId: BigString) => Promise; + removeRole: (guildId: BigString, userId: BigString, roleId: BigString, reason?: string) => Promise; + removeThreadMember: (channelId: BigString, userId: BigString) => Promise; + removeDmRecipient: (channelId: BigString, userId: BigString) => Promise; sendInteractionResponse: ( interactionId: BigString, token: string, options: InteractionResponse, params?: InteractionCallbackOptions, - ) => Promise> - triggerTypingIndicator: (channelId: BigString) => Promise - banMember: (guildId: BigString, userId: BigString, options?: CreateGuildBan, reason?: string) => Promise - kickMember: (guildId: BigString, userId: BigString, reason?: string) => Promise - pinMessage: (channelId: BigString, messageId: BigString, reason?: string) => Promise - unbanMember: (guildId: BigString, userId: BigString, reason?: string) => Promise - unpinMessage: (channelId: BigString, messageId: BigString, reason?: string) => Promise - getGuildOnboarding: (guildId: BigString) => Promise> + ) => Promise>; + triggerTypingIndicator: (channelId: BigString) => Promise; + banMember: (guildId: BigString, userId: BigString, options?: CreateGuildBan, reason?: string) => Promise; + kickMember: (guildId: BigString, userId: BigString, reason?: string) => Promise; + pinMessage: (channelId: BigString, messageId: BigString, reason?: string) => Promise; + unbanMember: (guildId: BigString, userId: BigString, reason?: string) => Promise; + unpinMessage: (channelId: BigString, messageId: BigString, reason?: string) => Promise; + getGuildOnboarding: (guildId: BigString) => Promise>; editGuildOnboarding: ( guildId: BigString, options: EditGuildOnboarding, reason?: string, - ) => Promise> - listEntitlements: (applicationId: BigString, options?: GetEntitlements) => Promise[]> - getEntitlement: (applicationId: BigString, entitlementId: BigString) => Promise> + ) => Promise>; + listEntitlements: (applicationId: BigString, options?: GetEntitlements) => Promise[]>; + getEntitlement: (applicationId: BigString, entitlementId: BigString) => Promise>; createTestEntitlement: ( applicationId: BigString, body: CreateTestEntitlement, - ) => Promise>> - deleteTestEntitlement: (applicationId: BigString, entitlementId: BigString) => Promise - listSkus: (applicationId: BigString) => Promise[]> - listSubscriptions: (skuId: BigString, options?: ListSkuSubscriptionsOptions) => Promise[]> - getSubscription: (skuId: BigString, subscriptionId: BigString) => Promise> - sendSoundboardSound: (channelId: BigString, options: SendSoundboardSound) => Promise - listDefaultSoundboardSounds: () => Promise[]> - listGuildSoundboardSounds: (guildId: BigString) => Promise<{ items: SetupDesiredProps[] }> - getGuildSoundboardSound: (guildId: BigString, soundId: BigString) => Promise> + ) => Promise>>; + deleteTestEntitlement: (applicationId: BigString, entitlementId: BigString) => Promise; + listSkus: (applicationId: BigString) => Promise[]>; + listSubscriptions: (skuId: BigString, options?: ListSkuSubscriptionsOptions) => Promise[]>; + getSubscription: (skuId: BigString, subscriptionId: BigString) => Promise>; + sendSoundboardSound: (channelId: BigString, options: SendSoundboardSound) => Promise; + listDefaultSoundboardSounds: () => Promise[]>; + listGuildSoundboardSounds: (guildId: BigString) => Promise<{ items: SetupDesiredProps[] }>; + getGuildSoundboardSound: (guildId: BigString, soundId: BigString) => Promise>; createGuildSoundboardSound: ( guildId: BigString, options: CreateGuildSoundboardSound, reason?: string, - ) => Promise> + ) => Promise>; modifyGuildSoundboardSound: ( guildId: BigString, soundId: BigString, options: ModifyGuildSoundboardSound, reason?: string, - ) => Promise> - deleteGuildSoundboardSound: (guildId: BigString, soundId: BigString, reason?: string) => Promise - deleteLobby: (lobbyId: BigString) => Promise - removeMemberFromLobby: (lobbyId: BigString, userId: BigString) => Promise - leaveLobby: (lobbyId: BigString, bearerToken: string) => Promise -} + ) => Promise>; + deleteGuildSoundboardSound: (guildId: BigString, soundId: BigString, reason?: string) => Promise; + deleteLobby: (lobbyId: BigString) => Promise; + removeMemberFromLobby: (lobbyId: BigString, userId: BigString) => Promise; + leaveLobby: (lobbyId: BigString, bearerToken: string) => Promise; +}; diff --git a/packages/bot/src/index.ts b/packages/bot/src/index.ts index c0d3c2824..9baaf0944 100644 --- a/packages/bot/src/index.ts +++ b/packages/bot/src/index.ts @@ -1,14 +1,14 @@ -export * from '@discordeno/gateway' -export * from '@discordeno/rest' -export * from '@discordeno/types' -export * from '@discordeno/utils' -export * from './bot.js' -export * from './commandOptionsParser.js' -export * from './constants.js' -export * from './desiredProperties.js' -export * from './events.js' -export * from './handlers/index.js' -export * from './handlers.js' -export * from './helpers.js' -export * from './transformers/index.js' -export * from './transformers.js' +export * from '@discordeno/gateway'; +export * from '@discordeno/rest'; +export * from '@discordeno/types'; +export * from '@discordeno/utils'; +export * from './bot.js'; +export * from './commandOptionsParser.js'; +export * from './constants.js'; +export * from './desiredProperties.js'; +export * from './events.js'; +export * from './handlers/index.js'; +export * from './handlers.js'; +export * from './helpers.js'; +export * from './transformers/index.js'; +export * from './transformers.js'; diff --git a/packages/bot/src/transformers.ts b/packages/bot/src/transformers.ts index 728d5a215..ed757475f 100644 --- a/packages/bot/src/transformers.ts +++ b/packages/bot/src/transformers.ts @@ -77,35 +77,35 @@ import type { DiscordWebhook, DiscordWelcomeScreen, RecursivePartial, -} from '@discordeno/types' -import { bigintToSnowflake, snowflakeToBigint } from '@discordeno/utils' -import type { Bot } from './bot.js' +} from '@discordeno/types'; +import { bigintToSnowflake, snowflakeToBigint } from '@discordeno/utils'; +import type { Bot } from './bot.js'; import { createDesiredPropertiesObject, type DesiredPropertiesBehavior, type SetupDesiredProps, type TransformersDesiredProperties, -} from './desiredProperties.js' -import { transformActivity, transformActivityInstance, transformActivityLocation } from './transformers/activity.js' -import { transformApplication } from './transformers/application.js' -import { transformApplicationCommand } from './transformers/applicationCommand.js' -import { transformApplicationCommandOption } from './transformers/applicationCommandOption.js' -import { transformApplicationCommandOptionChoice } from './transformers/applicationCommandOptionChoice.js' -import { transformApplicationCommandPermission } from './transformers/applicationCommandPermission.js' -import { transformAttachment } from './transformers/attachment.js' -import { transformAuditLogEntry } from './transformers/auditLogEntry.js' -import { transformAutoModerationActionExecution } from './transformers/automodActionExecution.js' -import { transformAutoModerationRule } from './transformers/automodRule.js' -import { transformAvatarDecorationData } from './transformers/avatarDecorationData.js' -import { transformChannel, transformForumTag } from './transformers/channel.js' -import { transformComponent, transformMediaGalleryItem, transformUnfurledMediaItem } from './transformers/component.js' -import { transformEmbed } from './transformers/embed.js' -import { transformDefaultReactionEmoji, transformEmoji } from './transformers/emoji.js' -import { transformEntitlement } from './transformers/entitlement.js' -import { transformGatewayBot } from './transformers/gatewayBot.js' -import { transformGuild } from './transformers/guild.js' -import { transformIncidentsData } from './transformers/incidentsData.js' -import { transformIntegration } from './transformers/integration.js' +} from './desiredProperties.js'; +import { transformActivity, transformActivityInstance, transformActivityLocation } from './transformers/activity.js'; +import { transformApplication } from './transformers/application.js'; +import { transformApplicationCommand } from './transformers/applicationCommand.js'; +import { transformApplicationCommandOption } from './transformers/applicationCommandOption.js'; +import { transformApplicationCommandOptionChoice } from './transformers/applicationCommandOptionChoice.js'; +import { transformApplicationCommandPermission } from './transformers/applicationCommandPermission.js'; +import { transformAttachment } from './transformers/attachment.js'; +import { transformAuditLogEntry } from './transformers/auditLogEntry.js'; +import { transformAutoModerationActionExecution } from './transformers/automodActionExecution.js'; +import { transformAutoModerationRule } from './transformers/automodRule.js'; +import { transformAvatarDecorationData } from './transformers/avatarDecorationData.js'; +import { transformChannel, transformForumTag } from './transformers/channel.js'; +import { transformComponent, transformMediaGalleryItem, transformUnfurledMediaItem } from './transformers/component.js'; +import { transformEmbed } from './transformers/embed.js'; +import { transformDefaultReactionEmoji, transformEmoji } from './transformers/emoji.js'; +import { transformEntitlement } from './transformers/entitlement.js'; +import { transformGatewayBot } from './transformers/gatewayBot.js'; +import { transformGuild } from './transformers/guild.js'; +import { transformIncidentsData } from './transformers/incidentsData.js'; +import { transformIntegration } from './transformers/integration.js'; import { transformInteraction, transformInteractionCallback, @@ -113,46 +113,46 @@ import { transformInteractionDataOption, transformInteractionDataResolved, transformInteractionResource, -} from './transformers/interaction.js' -import { transformInvite } from './transformers/invite.js' -import { transformLobby, transformLobbyMember } from './transformers/lobby.js' -import { transformMember } from './transformers/member.js' +} from './transformers/interaction.js'; +import { transformInvite } from './transformers/invite.js'; +import { transformLobby, transformLobbyMember } from './transformers/lobby.js'; +import { transformMember } from './transformers/member.js'; import { transformMessage, transformMessageCall, transformMessageInteractionMetadata, transformMessagePin, transformMessageSnapshot, -} from './transformers/message.js' -import { transformGuildOnboarding, transformGuildOnboardingPrompt, transformGuildOnboardingPromptOption } from './transformers/onboarding.js' -import { transformPoll, transformPollMedia } from './transformers/poll.js' -import { transformPresence } from './transformers/presence.js' -import { transformActivityToDiscordActivity } from './transformers/reverse/activity.js' -import { transformAllowedMentionsToDiscordAllowedMentions } from './transformers/reverse/allowedMentions.js' -import { transformApplicationToDiscordApplication } from './transformers/reverse/application.js' -import { transformApplicationCommandToDiscordApplicationCommand } from './transformers/reverse/applicationCommand.js' -import { transformApplicationCommandOptionToDiscordApplicationCommandOption } from './transformers/reverse/applicationCommandOption.js' -import { transformApplicationCommandOptionChoiceToDiscordApplicationCommandOptionChoice } from './transformers/reverse/applicationCommandOptionChoice.js' -import { transformAttachmentToDiscordAttachment } from './transformers/reverse/attachment.js' +} from './transformers/message.js'; +import { transformGuildOnboarding, transformGuildOnboardingPrompt, transformGuildOnboardingPromptOption } from './transformers/onboarding.js'; +import { transformPoll, transformPollMedia } from './transformers/poll.js'; +import { transformPresence } from './transformers/presence.js'; +import { transformActivityToDiscordActivity } from './transformers/reverse/activity.js'; +import { transformAllowedMentionsToDiscordAllowedMentions } from './transformers/reverse/allowedMentions.js'; +import { transformApplicationToDiscordApplication } from './transformers/reverse/application.js'; +import { transformApplicationCommandToDiscordApplicationCommand } from './transformers/reverse/applicationCommand.js'; +import { transformApplicationCommandOptionToDiscordApplicationCommandOption } from './transformers/reverse/applicationCommandOption.js'; +import { transformApplicationCommandOptionChoiceToDiscordApplicationCommandOptionChoice } from './transformers/reverse/applicationCommandOptionChoice.js'; +import { transformAttachmentToDiscordAttachment } from './transformers/reverse/attachment.js'; import { transformComponentToDiscordComponent, transformMediaGalleryItemToDiscordMediaGalleryItem, transformUnfurledMediaItemToDiscordUnfurledMediaItem, -} from './transformers/reverse/component.js' -import { transformEmbedToDiscordEmbed } from './transformers/reverse/embed.js' -import { transformMemberToDiscordMember, transformUserToDiscordUser } from './transformers/reverse/member.js' -import { transformTeamToDiscordTeam } from './transformers/reverse/team.js' -import { transformRole, transformRoleColors } from './transformers/role.js' -import { transformScheduledEvent, transformScheduledEventRecurrenceRule } from './transformers/scheduledEvent.js' -import { transformSku } from './transformers/sku.js' -import { transformSoundboardSound } from './transformers/soundboardSound.js' -import { transformStageInstance } from './transformers/stageInstance.js' -import { transformInviteStageInstance } from './transformers/stageInviteInstance.js' -import { transformSticker, transformStickerPack } from './transformers/sticker.js' -import { transformSubscription } from './transformers/subscription.js' -import { transformTeam } from './transformers/team.js' -import { transformTemplate } from './transformers/template.js' -import { type ThreadMemberTransformerExtra, transformThreadMember, transformThreadMemberGuildCreate } from './transformers/threadMember.js' +} from './transformers/reverse/component.js'; +import { transformEmbedToDiscordEmbed } from './transformers/reverse/embed.js'; +import { transformMemberToDiscordMember, transformUserToDiscordUser } from './transformers/reverse/member.js'; +import { transformTeamToDiscordTeam } from './transformers/reverse/team.js'; +import { transformRole, transformRoleColors } from './transformers/role.js'; +import { transformScheduledEvent, transformScheduledEventRecurrenceRule } from './transformers/scheduledEvent.js'; +import { transformSku } from './transformers/sku.js'; +import { transformSoundboardSound } from './transformers/soundboardSound.js'; +import { transformStageInstance } from './transformers/stageInstance.js'; +import { transformInviteStageInstance } from './transformers/stageInviteInstance.js'; +import { transformSticker, transformStickerPack } from './transformers/sticker.js'; +import { transformSubscription } from './transformers/subscription.js'; +import { transformTeam } from './transformers/team.js'; +import { transformTemplate } from './transformers/template.js'; +import { type ThreadMemberTransformerExtra, transformThreadMember, transformThreadMemberGuildCreate } from './transformers/threadMember.js'; import type { Activity, ActivityInstance, @@ -226,134 +226,134 @@ import type { VoiceState, Webhook, WelcomeScreen, -} from './transformers/types.js' -import { transformCollectibles, transformNameplate, transformUser, transformUserPrimaryGuild } from './transformers/user.js' -import { transformVoiceRegion } from './transformers/voiceRegion.js' -import { transformVoiceState } from './transformers/voiceState.js' -import { transformWebhook } from './transformers/webhook.js' -import { transformWelcomeScreen } from './transformers/welcomeScreen.js' -import { transformWidget } from './transformers/widget.js' -import { transformWidgetSettings } from './transformers/widgetSettings.js' +} from './transformers/types.js'; +import { transformCollectibles, transformNameplate, transformUser, transformUserPrimaryGuild } from './transformers/user.js'; +import { transformVoiceRegion } from './transformers/voiceRegion.js'; +import { transformVoiceState } from './transformers/voiceState.js'; +import { transformWebhook } from './transformers/webhook.js'; +import { transformWelcomeScreen } from './transformers/welcomeScreen.js'; +import { transformWidget } from './transformers/widget.js'; +import { transformWidgetSettings } from './transformers/widgetSettings.js'; export type TransformerFunctions = { - activity: TransformerFunction - activityInstance: TransformerFunction - activityLocation: TransformerFunction - application: TransformerFunction - applicationCommand: TransformerFunction - applicationCommandOption: TransformerFunction - applicationCommandOptionChoice: TransformerFunction - applicationCommandPermission: TransformerFunction - attachment: TransformerFunction - auditLogEntry: TransformerFunction - automodActionExecution: TransformerFunction - automodRule: TransformerFunction - avatarDecorationData: TransformerFunction - channel: TransformerFunction - collectibles: TransformerFunction - component: TransformerFunction - defaultReactionEmoji: TransformerFunction - embed: TransformerFunction - emoji: TransformerFunction - entitlement: TransformerFunction - forumTag: TransformerFunction - gatewayBot: TransformerFunction - guild: TransformerFunction - guildOnboarding: TransformerFunction - guildOnboardingPrompt: TransformerFunction - guildOnboardingPromptOption: TransformerFunction - incidentsData: TransformerFunction - integration: TransformerFunction - interaction: TransformerFunction - interactionCallback: TransformerFunction + activity: TransformerFunction; + activityInstance: TransformerFunction; + activityLocation: TransformerFunction; + application: TransformerFunction; + applicationCommand: TransformerFunction; + applicationCommandOption: TransformerFunction; + applicationCommandOptionChoice: TransformerFunction; + applicationCommandPermission: TransformerFunction; + attachment: TransformerFunction; + auditLogEntry: TransformerFunction; + automodActionExecution: TransformerFunction; + automodRule: TransformerFunction; + avatarDecorationData: TransformerFunction; + channel: TransformerFunction; + collectibles: TransformerFunction; + component: TransformerFunction; + defaultReactionEmoji: TransformerFunction; + embed: TransformerFunction; + emoji: TransformerFunction; + entitlement: TransformerFunction; + forumTag: TransformerFunction; + gatewayBot: TransformerFunction; + guild: TransformerFunction; + guildOnboarding: TransformerFunction; + guildOnboardingPrompt: TransformerFunction; + guildOnboardingPromptOption: TransformerFunction; + incidentsData: TransformerFunction; + integration: TransformerFunction; + interaction: TransformerFunction; + interactionCallback: TransformerFunction; interactionCallbackResponse: TransformerFunction< TProps, TBehavior, DiscordInteractionCallbackResponse, InteractionCallbackResponse, { shardId?: number } - > - interactionDataOptions: TransformerFunction + >; + interactionDataOptions: TransformerFunction; interactionDataResolved: TransformerFunction< TProps, TBehavior, DiscordInteractionDataResolved, InteractionDataResolved, { shardId?: number; guildId?: BigString } - > - interactionResource: TransformerFunction - invite: TransformerFunction - inviteStageInstance: TransformerFunction - lobby: TransformerFunction - lobbyMember: TransformerFunction - mediaGalleryItem: TransformerFunction - member: TransformerFunction - message: TransformerFunction - messageCall: TransformerFunction - messageInteractionMetadata: TransformerFunction - messagePin: TransformerFunction - messageSnapshot: TransformerFunction - nameplate: TransformerFunction - poll: TransformerFunction - pollMedia: TransformerFunction - presence: TransformerFunction - role: TransformerFunction - roleColors: TransformerFunction - scheduledEvent: TransformerFunction - scheduledEventRecurrenceRule: TransformerFunction - sku: TransformerFunction - soundboardSound: TransformerFunction - stageInstance: TransformerFunction - sticker: TransformerFunction - stickerPack: TransformerFunction - subscription: TransformerFunction - team: TransformerFunction - template: TransformerFunction - threadMember: TransformerFunction - threadMemberGuildCreate: TransformerFunction - unfurledMediaItem: TransformerFunction - user: TransformerFunction - userPrimaryGuild: TransformerFunction - voiceRegion: TransformerFunction - voiceState: TransformerFunction - webhook: TransformerFunction - welcomeScreen: TransformerFunction - widget: TransformerFunction - widgetSettings: TransformerFunction -} + >; + interactionResource: TransformerFunction; + invite: TransformerFunction; + inviteStageInstance: TransformerFunction; + lobby: TransformerFunction; + lobbyMember: TransformerFunction; + mediaGalleryItem: TransformerFunction; + member: TransformerFunction; + message: TransformerFunction; + messageCall: TransformerFunction; + messageInteractionMetadata: TransformerFunction; + messagePin: TransformerFunction; + messageSnapshot: TransformerFunction; + nameplate: TransformerFunction; + poll: TransformerFunction; + pollMedia: TransformerFunction; + presence: TransformerFunction; + role: TransformerFunction; + roleColors: TransformerFunction; + scheduledEvent: TransformerFunction; + scheduledEventRecurrenceRule: TransformerFunction; + sku: TransformerFunction; + soundboardSound: TransformerFunction; + stageInstance: TransformerFunction; + sticker: TransformerFunction; + stickerPack: TransformerFunction; + subscription: TransformerFunction; + team: TransformerFunction; + template: TransformerFunction; + threadMember: TransformerFunction; + threadMemberGuildCreate: TransformerFunction; + unfurledMediaItem: TransformerFunction; + user: TransformerFunction; + userPrimaryGuild: TransformerFunction; + voiceRegion: TransformerFunction; + voiceState: TransformerFunction; + webhook: TransformerFunction; + welcomeScreen: TransformerFunction; + widget: TransformerFunction; + widgetSettings: TransformerFunction; +}; export type Transformers = TransformerFunctions< TProps, TBehavior > & { - customizers: TransformerCustomizers - desiredProperties: TProps + customizers: TransformerCustomizers; + desiredProperties: TProps; reverse: { - activity: (bot: Bot, payload: Activity) => DiscordActivity - allowedMentions: (bot: Bot, payload: AllowedMentions) => DiscordAllowedMentions - application: (bot: Bot, payload: Application) => DiscordApplication - applicationCommand: (bot: Bot, payload: ApplicationCommand) => DiscordApplicationCommand - applicationCommandOption: (bot: Bot, payload: ApplicationCommandOption) => DiscordApplicationCommandOption - applicationCommandOptionChoice: (bot: Bot, payload: ApplicationCommandOptionChoice) => DiscordApplicationCommandOptionChoice - attachment: (bot: Bot, payload: SetupDesiredProps) => DiscordAttachment - component: (bot: Bot, payload: Component) => DiscordMessageComponent | DiscordMessageComponentFromModalInteractionResponse - embed: (bot: Bot, payload: Embed) => DiscordEmbed - mediaGalleryItem: (bot: Bot, payload: MediaGalleryItem) => DiscordMediaGalleryItem - member: (bot: Bot, payload: SetupDesiredProps) => DiscordMember - snowflake: (snowflake: BigString) => string - team: (bot: Bot, payload: Team) => DiscordTeam - unfurledMediaItem: (bot: Bot, payload: UnfurledMediaItem) => DiscordUnfurledMediaItem - user: (bot: Bot, payload: SetupDesiredProps) => DiscordUser - } - snowflake: (snowflake: BigString) => bigint -} + activity: (bot: Bot, payload: Activity) => DiscordActivity; + allowedMentions: (bot: Bot, payload: AllowedMentions) => DiscordAllowedMentions; + application: (bot: Bot, payload: Application) => DiscordApplication; + applicationCommand: (bot: Bot, payload: ApplicationCommand) => DiscordApplicationCommand; + applicationCommandOption: (bot: Bot, payload: ApplicationCommandOption) => DiscordApplicationCommandOption; + applicationCommandOptionChoice: (bot: Bot, payload: ApplicationCommandOptionChoice) => DiscordApplicationCommandOptionChoice; + attachment: (bot: Bot, payload: SetupDesiredProps) => DiscordAttachment; + component: (bot: Bot, payload: Component) => DiscordMessageComponent | DiscordMessageComponentFromModalInteractionResponse; + embed: (bot: Bot, payload: Embed) => DiscordEmbed; + mediaGalleryItem: (bot: Bot, payload: MediaGalleryItem) => DiscordMediaGalleryItem; + member: (bot: Bot, payload: SetupDesiredProps) => DiscordMember; + snowflake: (snowflake: BigString) => string; + team: (bot: Bot, payload: Team) => DiscordTeam; + unfurledMediaItem: (bot: Bot, payload: UnfurledMediaItem) => DiscordUnfurledMediaItem; + user: (bot: Bot, payload: SetupDesiredProps) => DiscordUser; + }; + snowflake: (snowflake: BigString) => bigint; +}; -const defaultCustomizer = (_bot: unknown, _payload: unknown, structure: unknown) => structure +const defaultCustomizer = (_bot: unknown, _payload: unknown, structure: unknown) => structure; export function createTransformers( options: RecursivePartial>, ): Transformers { - const _options = options as RecursivePartial> + const _options = options as RecursivePartial>; return { customizers: { @@ -522,7 +522,7 @@ export function createTransformers as unknown as Transformers + } satisfies Transformers as unknown as Transformers; } export type TransformerFunction< @@ -531,7 +531,7 @@ export type TransformerFunction< TPayload, TTransformed, TExtra = {}, -> = (bot: Bot, payload: TPayload, extra?: TExtra) => SetupDesiredProps +> = (bot: Bot, payload: TPayload, extra?: TExtra) => SetupDesiredProps; export type TransformerCustomizerFunction< TProps extends TransformersDesiredProperties, @@ -539,7 +539,7 @@ export type TransformerCustomizerFunction< TPayload, TTransformed, TExtra = {}, -> = (bot: Bot, payload: TPayload, transformed: TTransformed, extra?: TExtra) => any +> = (bot: Bot, payload: TPayload, transformed: TTransformed, extra?: TExtra) => any; export type TransformerCustomizers = { [K in keyof TransformerFunctions]: TransformerFunctions[K] extends TransformerFunction< @@ -550,9 +550,9 @@ export type TransformerCustomizers ? TransformerCustomizerFunction, BigStringsToBigints> - : 'ERROR: Invalid transformer found' -} + : 'ERROR: Invalid transformer found'; +}; export type BigStringsToBigints = { - [K in keyof T]: BigString extends T[K] ? bigint : T[K] -} + [K in keyof T]: BigString extends T[K] ? bigint : T[K]; +}; diff --git a/packages/bot/src/transformers/activity.ts b/packages/bot/src/transformers/activity.ts index 60c5297e7..379547d93 100644 --- a/packages/bot/src/transformers/activity.ts +++ b/packages/bot/src/transformers/activity.ts @@ -1,7 +1,7 @@ -import type { DiscordActivity, DiscordActivityInstance, DiscordActivityLocation } from '@discordeno/types' -import type { Bot } from '../bot.js' -import type { DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from '../desiredProperties.js' -import type { Activity, ActivityInstance, ActivityLocation } from './types.js' +import type { DiscordActivity, DiscordActivityInstance, DiscordActivityLocation } from '@discordeno/types'; +import type { Bot } from '../bot.js'; +import type { DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from '../desiredProperties.js'; +import type { Activity, ActivityInstance, ActivityLocation } from './types.js'; export function transformActivity(bot: Bot, payload: DiscordActivity): Activity { const activity = { @@ -35,32 +35,32 @@ export function transformActivity(bot: Bot, payload: DiscordActivity): Activity instance: payload.instance, flags: payload.flags, buttons: payload.buttons, - } as Activity + } as Activity; - return bot.transformers.customizers.activity(bot, payload, activity) + return bot.transformers.customizers.activity(bot, payload, activity); } export function transformActivityInstance(bot: Bot, payload: DiscordActivityInstance): ActivityInstance { - const props = bot.transformers.desiredProperties.activityInstance - const activityInstance = {} as SetupDesiredProps + const props = bot.transformers.desiredProperties.activityInstance; + const activityInstance = {} as SetupDesiredProps; - if (props.applicationId && payload.application_id) activityInstance.applicationId = bot.transformers.snowflake(payload.application_id) - if (props.instanceId && payload.instance_id) activityInstance.instanceId = payload.instance_id - if (props.launchId && payload.launch_id) activityInstance.launchId = bot.transformers.snowflake(payload.launch_id) - if (props.location && payload.location) activityInstance.location = bot.transformers.activityLocation(bot, payload.location) - if (props.users && payload.users) activityInstance.users = payload.users.map((x) => bot.transformers.snowflake(x)) + if (props.applicationId && payload.application_id) activityInstance.applicationId = bot.transformers.snowflake(payload.application_id); + if (props.instanceId && payload.instance_id) activityInstance.instanceId = payload.instance_id; + if (props.launchId && payload.launch_id) activityInstance.launchId = bot.transformers.snowflake(payload.launch_id); + if (props.location && payload.location) activityInstance.location = bot.transformers.activityLocation(bot, payload.location); + if (props.users && payload.users) activityInstance.users = payload.users.map((x) => bot.transformers.snowflake(x)); - return bot.transformers.customizers.activityInstance(bot, payload, activityInstance) + return bot.transformers.customizers.activityInstance(bot, payload, activityInstance); } export function transformActivityLocation(bot: Bot, payload: DiscordActivityLocation): ActivityLocation { - const props = bot.transformers.desiredProperties.activityLocation - const activityLocation = {} as SetupDesiredProps + const props = bot.transformers.desiredProperties.activityLocation; + const activityLocation = {} as SetupDesiredProps; - if (props.id && payload.id) activityLocation.id = payload.id - if (props.kind && payload.kind) activityLocation.kind = payload.kind - if (props.channelId && payload.channel_id) activityLocation.channelId = bot.transformers.snowflake(payload.channel_id) - if (props.guildId && payload.guild_id) activityLocation.guildId = bot.transformers.snowflake(payload.guild_id) + if (props.id && payload.id) activityLocation.id = payload.id; + if (props.kind && payload.kind) activityLocation.kind = payload.kind; + if (props.channelId && payload.channel_id) activityLocation.channelId = bot.transformers.snowflake(payload.channel_id); + if (props.guildId && payload.guild_id) activityLocation.guildId = bot.transformers.snowflake(payload.guild_id); - return bot.transformers.customizers.activityLocation(bot, payload, activityLocation) + return bot.transformers.customizers.activityLocation(bot, payload, activityLocation); } diff --git a/packages/bot/src/transformers/application.ts b/packages/bot/src/transformers/application.ts index edb1a9232..48e7adaa7 100644 --- a/packages/bot/src/transformers/application.ts +++ b/packages/bot/src/transformers/application.ts @@ -1,7 +1,7 @@ -import { type DiscordApplication, DiscordApplicationIntegrationType, type DiscordUser } from '@discordeno/types' -import { iconHashToBigInt } from '@discordeno/utils' -import type { Bot } from '../bot.js' -import type { Application } from './types.js' +import { type DiscordApplication, DiscordApplicationIntegrationType, type DiscordUser } from '@discordeno/types'; +import { iconHashToBigInt } from '@discordeno/utils'; +import type { Bot } from '../bot.js'; +import type { Application } from './types.js'; export function transformApplication(bot: Bot, payload: DiscordApplication, extra?: { shardId?: number }): Application { const application = { @@ -66,7 +66,7 @@ export function transformApplication(bot: Bot, payload: DiscordApplication, extr eventWebhooksUrl: payload.event_webhooks_url, eventWebhooksStatus: payload.event_webhooks_status, eventWebhooksTypes: payload.event_webhooks_types, - } as Application + } as Application; - return bot.transformers.customizers.application(bot, payload, application, extra) + return bot.transformers.customizers.application(bot, payload, application, extra); } diff --git a/packages/bot/src/transformers/applicationCommand.ts b/packages/bot/src/transformers/applicationCommand.ts index 62cd1bc81..1061747a5 100644 --- a/packages/bot/src/transformers/applicationCommand.ts +++ b/packages/bot/src/transformers/applicationCommand.ts @@ -1,6 +1,6 @@ -import type { DiscordApplicationCommand } from '@discordeno/types' -import type { Bot } from '../bot.js' -import type { ApplicationCommand } from './types.js' +import type { DiscordApplicationCommand } from '@discordeno/types'; +import type { Bot } from '../bot.js'; +import type { ApplicationCommand } from './types.js'; export function transformApplicationCommand(bot: Bot, payload: DiscordApplicationCommand): ApplicationCommand { const applicationCommand = { @@ -17,7 +17,7 @@ export function transformApplicationCommand(bot: Bot, payload: DiscordApplicatio version: payload.version, options: payload.options?.map((option) => bot.transformers.applicationCommandOption(bot, option)), - } as ApplicationCommand + } as ApplicationCommand; - return bot.transformers.customizers.applicationCommand(bot, payload, applicationCommand) + return bot.transformers.customizers.applicationCommand(bot, payload, applicationCommand); } diff --git a/packages/bot/src/transformers/applicationCommandOption.ts b/packages/bot/src/transformers/applicationCommandOption.ts index 4fb20288e..452070ed0 100644 --- a/packages/bot/src/transformers/applicationCommandOption.ts +++ b/packages/bot/src/transformers/applicationCommandOption.ts @@ -1,6 +1,6 @@ -import type { DiscordApplicationCommandOption } from '@discordeno/types' -import type { Bot } from '../bot.js' -import type { ApplicationCommandOption } from './types.js' +import type { DiscordApplicationCommandOption } from '@discordeno/types'; +import type { Bot } from '../bot.js'; +import type { ApplicationCommandOption } from './types.js'; export function transformApplicationCommandOption(bot: Bot, payload: DiscordApplicationCommandOption): ApplicationCommandOption { const applicationCommandOption = { @@ -18,7 +18,7 @@ export function transformApplicationCommandOption(bot: Bot, payload: DiscordAppl minLength: payload.min_length, maxLength: payload.max_length, options: payload.options?.map((option) => bot.transformers.applicationCommandOption(bot, option)), - } as ApplicationCommandOption + } as ApplicationCommandOption; - return bot.transformers.customizers.applicationCommandOption(bot, payload, applicationCommandOption) + return bot.transformers.customizers.applicationCommandOption(bot, payload, applicationCommandOption); } diff --git a/packages/bot/src/transformers/applicationCommandOptionChoice.ts b/packages/bot/src/transformers/applicationCommandOptionChoice.ts index d5e0eee27..391ec5bab 100644 --- a/packages/bot/src/transformers/applicationCommandOptionChoice.ts +++ b/packages/bot/src/transformers/applicationCommandOptionChoice.ts @@ -1,13 +1,13 @@ -import type { DiscordApplicationCommandOptionChoice } from '@discordeno/types' -import type { Bot } from '../bot.js' -import type { ApplicationCommandOptionChoice } from './types.js' +import type { DiscordApplicationCommandOptionChoice } from '@discordeno/types'; +import type { Bot } from '../bot.js'; +import type { ApplicationCommandOptionChoice } from './types.js'; export function transformApplicationCommandOptionChoice(bot: Bot, payload: DiscordApplicationCommandOptionChoice): ApplicationCommandOptionChoice { const applicationCommandOptionChoice = { name: payload.name, nameLocalizations: payload.name_localizations ?? undefined, value: payload.value, - } as ApplicationCommandOptionChoice + } as ApplicationCommandOptionChoice; - return bot.transformers.customizers.applicationCommandOptionChoice(bot, payload, applicationCommandOptionChoice) + return bot.transformers.customizers.applicationCommandOptionChoice(bot, payload, applicationCommandOptionChoice); } diff --git a/packages/bot/src/transformers/applicationCommandPermission.ts b/packages/bot/src/transformers/applicationCommandPermission.ts index 09b0ed606..6c6521d49 100644 --- a/packages/bot/src/transformers/applicationCommandPermission.ts +++ b/packages/bot/src/transformers/applicationCommandPermission.ts @@ -1,6 +1,6 @@ -import type { DiscordGuildApplicationCommandPermissions } from '@discordeno/types' -import type { Bot } from '../bot.js' -import type { GuildApplicationCommandPermissions } from './types.js' +import type { DiscordGuildApplicationCommandPermissions } from '@discordeno/types'; +import type { Bot } from '../bot.js'; +import type { GuildApplicationCommandPermissions } from './types.js'; export function transformApplicationCommandPermission( bot: Bot, @@ -15,7 +15,7 @@ export function transformApplicationCommandPermission( type: perm.type, permission: perm.permission, })), - } as GuildApplicationCommandPermissions + } as GuildApplicationCommandPermissions; - return bot.transformers.customizers.applicationCommandPermission(bot, payload, applicationCommandPermission) + return bot.transformers.customizers.applicationCommandPermission(bot, payload, applicationCommandPermission); } diff --git a/packages/bot/src/transformers/attachment.ts b/packages/bot/src/transformers/attachment.ts index 205405501..64e8bfd85 100644 --- a/packages/bot/src/transformers/attachment.ts +++ b/packages/bot/src/transformers/attachment.ts @@ -1,26 +1,26 @@ -import type { DiscordAttachment } from '@discordeno/types' -import type { Bot } from '../bot.js' -import type { DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from '../desiredProperties.js' -import type { Attachment } from './types.js' +import type { DiscordAttachment } from '@discordeno/types'; +import type { Bot } from '../bot.js'; +import type { DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from '../desiredProperties.js'; +import type { Attachment } from './types.js'; export function transformAttachment(bot: Bot, payload: DiscordAttachment): typeof bot.transformers.$inferredTypes.attachment { - const props = bot.transformers.desiredProperties.attachment - const attachment = {} as SetupDesiredProps + const props = bot.transformers.desiredProperties.attachment; + const attachment = {} as SetupDesiredProps; - if (props.id && payload.id) attachment.id = bot.transformers.snowflake(payload.id) - if (props.filename && payload.filename) attachment.filename = payload.filename - if (props.title && payload.title) attachment.title = payload.title - if (props.contentType && payload.content_type) attachment.contentType = payload.content_type - if (props.size) attachment.size = payload.size - if (props.url && payload.url) attachment.url = payload.url - if (props.proxyUrl && payload.proxy_url) attachment.proxyUrl = payload.proxy_url - if (props.height && payload.height) attachment.height = payload.height - if (props.width && payload.width) attachment.width = payload.width - if (props.ephemeral && payload.ephemeral) attachment.ephemeral = payload.ephemeral - if (props.description && payload.description) attachment.description = payload.description - if (props.duration_secs && payload.duration_secs) attachment.duration_secs = payload.duration_secs - if (props.waveform && payload.waveform) attachment.waveform = payload.waveform - if (props.flags) attachment.flags = payload.flags + if (props.id && payload.id) attachment.id = bot.transformers.snowflake(payload.id); + if (props.filename && payload.filename) attachment.filename = payload.filename; + if (props.title && payload.title) attachment.title = payload.title; + if (props.contentType && payload.content_type) attachment.contentType = payload.content_type; + if (props.size) attachment.size = payload.size; + if (props.url && payload.url) attachment.url = payload.url; + if (props.proxyUrl && payload.proxy_url) attachment.proxyUrl = payload.proxy_url; + if (props.height && payload.height) attachment.height = payload.height; + if (props.width && payload.width) attachment.width = payload.width; + if (props.ephemeral && payload.ephemeral) attachment.ephemeral = payload.ephemeral; + if (props.description && payload.description) attachment.description = payload.description; + if (props.duration_secs && payload.duration_secs) attachment.duration_secs = payload.duration_secs; + if (props.waveform && payload.waveform) attachment.waveform = payload.waveform; + if (props.flags) attachment.flags = payload.flags; - return bot.transformers.customizers.attachment(bot, payload, attachment) + return bot.transformers.customizers.attachment(bot, payload, attachment); } diff --git a/packages/bot/src/transformers/auditLogEntry.ts b/packages/bot/src/transformers/auditLogEntry.ts index 490774690..4acd82677 100644 --- a/packages/bot/src/transformers/auditLogEntry.ts +++ b/packages/bot/src/transformers/auditLogEntry.ts @@ -1,7 +1,7 @@ -import type { DiscordAuditLogEntry } from '@discordeno/types' -import { camelize } from '@discordeno/utils' -import type { Bot } from '../bot.js' -import type { AuditLogEntry } from './types.js' +import type { DiscordAuditLogEntry } from '@discordeno/types'; +import { camelize } from '@discordeno/utils'; +import type { Bot } from '../bot.js'; +import type { AuditLogEntry } from './types.js'; export function transformAuditLogEntry(bot: Bot, payload: DiscordAuditLogEntry): AuditLogEntry { const auditLogEntry = { @@ -27,7 +27,7 @@ export function transformAuditLogEntry(bot: Bot, payload: DiscordAuditLogEntry): } : undefined, reason: payload.reason, - } as AuditLogEntry + } as AuditLogEntry; - return bot.transformers.customizers.auditLogEntry(bot, payload, auditLogEntry) + return bot.transformers.customizers.auditLogEntry(bot, payload, auditLogEntry); } diff --git a/packages/bot/src/transformers/automodActionExecution.ts b/packages/bot/src/transformers/automodActionExecution.ts index 25e38ffb2..c673de22b 100644 --- a/packages/bot/src/transformers/automodActionExecution.ts +++ b/packages/bot/src/transformers/automodActionExecution.ts @@ -1,6 +1,6 @@ -import type { DiscordAutoModerationActionExecution } from '@discordeno/types' -import type { Bot } from '../bot.js' -import type { AutoModerationActionExecution } from './types.js' +import type { DiscordAutoModerationActionExecution } from '@discordeno/types'; +import type { Bot } from '../bot.js'; +import type { AutoModerationActionExecution } from './types.js'; export function transformAutoModerationActionExecution(bot: Bot, payload: DiscordAutoModerationActionExecution): AutoModerationActionExecution { const rule = { @@ -24,7 +24,7 @@ export function transformAutoModerationActionExecution(bot: Bot, payload: Discor } : undefined, }, - } as AutoModerationActionExecution + } as AutoModerationActionExecution; - return bot.transformers.customizers.automodActionExecution(bot, payload, rule) + return bot.transformers.customizers.automodActionExecution(bot, payload, rule); } diff --git a/packages/bot/src/transformers/automodRule.ts b/packages/bot/src/transformers/automodRule.ts index a4ec14671..b4d518a85 100644 --- a/packages/bot/src/transformers/automodRule.ts +++ b/packages/bot/src/transformers/automodRule.ts @@ -1,6 +1,6 @@ -import type { DiscordAutoModerationRule } from '@discordeno/types' -import type { Bot } from '../bot.js' -import type { AutoModerationRule } from './types.js' +import type { DiscordAutoModerationRule } from '@discordeno/types'; +import type { Bot } from '../bot.js'; +import type { AutoModerationRule } from './types.js'; export function transformAutoModerationRule(bot: Bot, payload: DiscordAutoModerationRule): AutoModerationRule { const rule = { @@ -33,7 +33,7 @@ export function transformAutoModerationRule(bot: Bot, payload: DiscordAutoModera } : undefined, })), - } as AutoModerationRule + } as AutoModerationRule; - return bot.transformers.customizers.automodRule(bot, payload, rule) + return bot.transformers.customizers.automodRule(bot, payload, rule); } diff --git a/packages/bot/src/transformers/avatarDecorationData.ts b/packages/bot/src/transformers/avatarDecorationData.ts index 443d6404b..358fd25ea 100644 --- a/packages/bot/src/transformers/avatarDecorationData.ts +++ b/packages/bot/src/transformers/avatarDecorationData.ts @@ -1,14 +1,14 @@ -import type { DiscordAvatarDecorationData } from '@discordeno/types' -import { iconHashToBigInt } from '@discordeno/utils' -import type { Bot } from '../bot.js' -import type { AvatarDecorationData } from './types.js' +import type { DiscordAvatarDecorationData } from '@discordeno/types'; +import { iconHashToBigInt } from '@discordeno/utils'; +import type { Bot } from '../bot.js'; +import type { AvatarDecorationData } from './types.js'; export function transformAvatarDecorationData(bot: Bot, payload: DiscordAvatarDecorationData): AvatarDecorationData { - const data = {} as AvatarDecorationData - const props = bot.transformers.desiredProperties.avatarDecorationData + const data = {} as AvatarDecorationData; + const props = bot.transformers.desiredProperties.avatarDecorationData; - if (props.asset && payload.asset) data.asset = iconHashToBigInt(payload.asset) - if (props.skuId && payload.sku_id) data.skuId = bot.transformers.snowflake(payload.sku_id) + if (props.asset && payload.asset) data.asset = iconHashToBigInt(payload.asset); + if (props.skuId && payload.sku_id) data.skuId = bot.transformers.snowflake(payload.sku_id); - return data + return data; } diff --git a/packages/bot/src/transformers/channel.ts b/packages/bot/src/transformers/channel.ts index d8a608dd2..ad1261a4f 100644 --- a/packages/bot/src/transformers/channel.ts +++ b/packages/bot/src/transformers/channel.ts @@ -1,26 +1,26 @@ -import type { BigString, DiscordChannel, DiscordForumTag } from '@discordeno/types' -import { calculatePermissions, iconHashToBigInt } from '@discordeno/utils' -import type { Bot } from '../bot.js' -import type { DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from '../desiredProperties.js' -import { ChannelToggles } from './toggles/channel.js' -import { Permissions } from './toggles/Permissions.js' -import type { Channel, ForumTag } from './types.js' +import type { BigString, DiscordChannel, DiscordForumTag } from '@discordeno/types'; +import { calculatePermissions, iconHashToBigInt } from '@discordeno/utils'; +import type { Bot } from '../bot.js'; +import type { DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from '../desiredProperties.js'; +import { ChannelToggles } from './toggles/channel.js'; +import { Permissions } from './toggles/Permissions.js'; +import type { Channel, ForumTag } from './types.js'; -const Mask = (1n << 64n) - 1n +const Mask = (1n << 64n) - 1n; export function packOverwrites(allow: string, deny: string, id: string, type: number): bigint { - return pack64(allow, 0) | pack64(deny, 1) | pack64(id, 2) | pack64(type, 3) + return pack64(allow, 0) | pack64(deny, 1) | pack64(id, 2) | pack64(type, 3); } function unpack64(v: bigint, shift: number): bigint { - return (v >> BigInt(shift * 64)) & Mask + return (v >> BigInt(shift * 64)) & Mask; } function pack64(v: string | number, shift: number): bigint { - const b = BigInt(v) - if (b < 0 || b > Mask) throw new Error('should have been a 64 bit unsigned integer: ' + v.toString()) - return b << BigInt(shift * 64) + const b = BigInt(v); + if (b < 0 || b > Mask) throw new Error('should have been a 64 bit unsigned integer: ' + v.toString()); + return b << BigInt(shift * 64); } export function separateOverwrites(v: bigint): [number, bigint, bigint, bigint] { - return [Number(unpack64(v, 3)), unpack64(v, 2), unpack64(v, 0), unpack64(v, 1)] as [number, bigint, bigint, bigint] + return [Number(unpack64(v, 3)), unpack64(v, 2), unpack64(v, 0), unpack64(v, 1)] as [number, bigint, bigint, bigint]; } export const baseChannel: Channel = { @@ -28,35 +28,35 @@ export const baseChannel: Channel = { ...(undefined as unknown as Channel), get archived() { - return !!this.toggles?.archived + return !!this.toggles?.archived; }, get invitable() { - return !!this.toggles?.invitable + return !!this.toggles?.invitable; }, get locked() { - return !!this.toggles?.locked + return !!this.toggles?.locked; }, get nsfw() { - return !!this.toggles?.nsfw + return !!this.toggles?.nsfw; }, get newlyCreated() { - return !!this.toggles?.newlyCreated + return !!this.toggles?.newlyCreated; }, get managed() { - return !!this.toggles?.managed + return !!this.toggles?.managed; }, get permissionOverwrites() { return ( this.internalOverwrites?.map((overwrite) => { - const [type, id, allow, deny] = separateOverwrites(overwrite) + const [type, id, allow, deny] = separateOverwrites(overwrite); return { type, id, allow: calculatePermissions(allow), deny: calculatePermissions(deny), - } + }; }) ?? [] - ) + ); }, get threadMetadata() { return { @@ -66,76 +66,76 @@ export const baseChannel: Channel = { locked: !!this.toggles?.locked, invitable: !!this.toggles?.invitable, archived: !!this.toggles?.archived, - } + }; }, -} +}; export function transformChannel(bot: Bot, payload: DiscordChannel, extra?: { guildId?: BigString }) { - const channel = Object.create(baseChannel) as SetupDesiredProps - const props = bot.transformers.desiredProperties.channel - channel.toggles = new ChannelToggles(payload) + const channel = Object.create(baseChannel) as SetupDesiredProps; + const props = bot.transformers.desiredProperties.channel; + channel.toggles = new ChannelToggles(payload); - if (props.id && payload.id) channel.id = bot.transformers.snowflake(payload.id) + if (props.id && payload.id) channel.id = bot.transformers.snowflake(payload.id); if (props.guildId && (extra?.guildId ?? payload.guild_id)) - channel.guildId = extra?.guildId ? bot.transformers.snowflake(extra.guildId) : bot.transformers.snowflake(payload.guild_id!) - if (props.type) channel.type = payload.type - if (props.position) channel.position = payload.position - if (props.name && payload.name) channel.name = payload.name - if (props.topic && payload.topic) channel.topic = payload.topic - if (props.lastMessageId && payload.last_message_id) channel.lastMessageId = bot.transformers.snowflake(payload.last_message_id) - if (props.bitrate && payload.bitrate) channel.bitrate = payload.bitrate - if (props.userLimit) channel.userLimit = payload.user_limit - if (props.rateLimitPerUser) channel.rateLimitPerUser = payload.rate_limit_per_user - if (props.ownerId && payload.owner_id) channel.ownerId = bot.transformers.snowflake(payload.owner_id) - if (props.lastPinTimestamp && payload.last_pin_timestamp) channel.lastPinTimestamp = Date.parse(payload.last_pin_timestamp) - if (props.rtcRegion && payload.rtc_region) channel.rtcRegion = payload.rtc_region - if (props.videoQualityMode && payload.video_quality_mode) channel.videoQualityMode = payload.video_quality_mode - if (props.messageCount) channel.messageCount = payload.message_count - if (props.memberCount) channel.memberCount = payload.member_count + channel.guildId = extra?.guildId ? bot.transformers.snowflake(extra.guildId) : bot.transformers.snowflake(payload.guild_id!); + if (props.type) channel.type = payload.type; + if (props.position) channel.position = payload.position; + if (props.name && payload.name) channel.name = payload.name; + if (props.topic && payload.topic) channel.topic = payload.topic; + if (props.lastMessageId && payload.last_message_id) channel.lastMessageId = bot.transformers.snowflake(payload.last_message_id); + if (props.bitrate && payload.bitrate) channel.bitrate = payload.bitrate; + if (props.userLimit) channel.userLimit = payload.user_limit; + if (props.rateLimitPerUser) channel.rateLimitPerUser = payload.rate_limit_per_user; + if (props.ownerId && payload.owner_id) channel.ownerId = bot.transformers.snowflake(payload.owner_id); + if (props.lastPinTimestamp && payload.last_pin_timestamp) channel.lastPinTimestamp = Date.parse(payload.last_pin_timestamp); + if (props.rtcRegion && payload.rtc_region) channel.rtcRegion = payload.rtc_region; + if (props.videoQualityMode && payload.video_quality_mode) channel.videoQualityMode = payload.video_quality_mode; + if (props.messageCount) channel.messageCount = payload.message_count; + if (props.memberCount) channel.memberCount = payload.member_count; if (props.threadMetadata) { - channel.internalThreadMetadata = {} as NonNullable + channel.internalThreadMetadata = {} as NonNullable; if (payload.thread_metadata?.archive_timestamp) - channel.internalThreadMetadata.archiveTimestamp = Date.parse(payload.thread_metadata.archive_timestamp) + channel.internalThreadMetadata.archiveTimestamp = Date.parse(payload.thread_metadata.archive_timestamp); if (payload.thread_metadata?.create_timestamp) - channel.internalThreadMetadata.createTimestamp = Date.parse(payload.thread_metadata.create_timestamp) + channel.internalThreadMetadata.createTimestamp = Date.parse(payload.thread_metadata.create_timestamp); if (payload.thread_metadata?.auto_archive_duration) - channel.internalThreadMetadata.autoArchiveDuration = payload.thread_metadata.auto_archive_duration + channel.internalThreadMetadata.autoArchiveDuration = payload.thread_metadata.auto_archive_duration; } if (props.defaultAutoArchiveDuration && payload.default_auto_archive_duration) - channel.defaultAutoArchiveDuration = payload.default_auto_archive_duration - if (props.permissions && payload.permissions) channel.permissions = new Permissions(payload.permissions) - if (props.flags) channel.flags = payload.flags + channel.defaultAutoArchiveDuration = payload.default_auto_archive_duration; + if (props.permissions && payload.permissions) channel.permissions = new Permissions(payload.permissions); + if (props.flags) channel.flags = payload.flags; if (props.permissionOverwrites && payload.permission_overwrites) - channel.internalOverwrites = payload.permission_overwrites.map((o) => packOverwrites(o.allow ?? '0', o.deny ?? '0', o.id, o.type)) - if (props.parentId && payload.parent_id) channel.parentId = bot.transformers.snowflake(payload.parent_id) - if (props.recipients && payload.recipients) channel.recipients = payload.recipients.map((u) => bot.transformers.user(bot, u)) - if (props.icon && payload.icon) channel.icon = iconHashToBigInt(payload.icon) - if (props.applicationId && payload.application_id) channel.applicationId = bot.transformers.snowflake(payload.application_id) - if (props.member && payload.member) channel.member = bot.transformers.threadMember(bot, payload.member, { guildId: extra?.guildId }) - if (props.totalMessageSent && payload.total_message_sent !== undefined) channel.totalMessageSent = payload.total_message_sent - if (props.availableTags && payload.available_tags) channel.availableTags = payload.available_tags.map((x) => bot.transformers.forumTag(bot, x)) - if (props.appliedTags && payload.applied_tags) channel.appliedTags = payload.applied_tags.map((x) => bot.transformers.snowflake(x)) + channel.internalOverwrites = payload.permission_overwrites.map((o) => packOverwrites(o.allow ?? '0', o.deny ?? '0', o.id, o.type)); + if (props.parentId && payload.parent_id) channel.parentId = bot.transformers.snowflake(payload.parent_id); + if (props.recipients && payload.recipients) channel.recipients = payload.recipients.map((u) => bot.transformers.user(bot, u)); + if (props.icon && payload.icon) channel.icon = iconHashToBigInt(payload.icon); + if (props.applicationId && payload.application_id) channel.applicationId = bot.transformers.snowflake(payload.application_id); + if (props.member && payload.member) channel.member = bot.transformers.threadMember(bot, payload.member, { guildId: extra?.guildId }); + if (props.totalMessageSent && payload.total_message_sent !== undefined) channel.totalMessageSent = payload.total_message_sent; + if (props.availableTags && payload.available_tags) channel.availableTags = payload.available_tags.map((x) => bot.transformers.forumTag(bot, x)); + if (props.appliedTags && payload.applied_tags) channel.appliedTags = payload.applied_tags.map((x) => bot.transformers.snowflake(x)); if (props.defaultReactionEmoji && payload.default_reaction_emoji) - channel.defaultReactionEmoji = bot.transformers.defaultReactionEmoji(bot, payload.default_reaction_emoji) + channel.defaultReactionEmoji = bot.transformers.defaultReactionEmoji(bot, payload.default_reaction_emoji); if (props.defaultThreadRateLimitPerUser && payload.default_thread_rate_limit_per_user) - channel.defaultThreadRateLimitPerUser = payload.default_thread_rate_limit_per_user - if (props.defaultSortOrder && payload.default_sort_order !== undefined) channel.defaultSortOrder = payload.default_sort_order - if (props.defaultForumLayout && payload.default_forum_layout !== undefined) channel.defaultForumLayout = payload.default_forum_layout + channel.defaultThreadRateLimitPerUser = payload.default_thread_rate_limit_per_user; + if (props.defaultSortOrder && payload.default_sort_order !== undefined) channel.defaultSortOrder = payload.default_sort_order; + if (props.defaultForumLayout && payload.default_forum_layout !== undefined) channel.defaultForumLayout = payload.default_forum_layout; return bot.transformers.customizers.channel(bot, payload, channel, { guildId: extra?.guildId ? bot.transformers.snowflake(extra.guildId) : undefined, - }) + }); } export function transformForumTag(bot: Bot, payload: DiscordForumTag): ForumTag { - const props = bot.transformers.desiredProperties.forumTag - const forumTag = {} as SetupDesiredProps + const props = bot.transformers.desiredProperties.forumTag; + const forumTag = {} as SetupDesiredProps; - if (props.id && payload.id) forumTag.id = bot.transformers.snowflake(payload.id) - if (props.name && payload.name) forumTag.name = payload.name - if (props.moderated && payload.moderated) forumTag.moderated = payload.moderated - if (props.emojiId && payload.emoji_id) forumTag.emojiId = bot.transformers.snowflake(payload.emoji_id) - if (props.emojiName && payload.emoji_name) forumTag.emojiName = payload.emoji_name + if (props.id && payload.id) forumTag.id = bot.transformers.snowflake(payload.id); + if (props.name && payload.name) forumTag.name = payload.name; + if (props.moderated && payload.moderated) forumTag.moderated = payload.moderated; + if (props.emojiId && payload.emoji_id) forumTag.emojiId = bot.transformers.snowflake(payload.emoji_id); + if (props.emojiName && payload.emoji_name) forumTag.emojiName = payload.emoji_name; - return bot.transformers.customizers.forumTag(bot, payload, forumTag) + return bot.transformers.customizers.forumTag(bot, payload, forumTag); } diff --git a/packages/bot/src/transformers/component.ts b/packages/bot/src/transformers/component.ts index 279e23ad1..4379490ba 100644 --- a/packages/bot/src/transformers/component.ts +++ b/packages/bot/src/transformers/component.ts @@ -22,173 +22,175 @@ import { type DiscordThumbnailComponent, type DiscordUnfurledMediaItem, MessageComponentTypes, -} from '@discordeno/types' -import type { Bot } from '../bot.js' -import type { DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from '../desiredProperties.js' -import type { Component, MediaGalleryItem, UnfurledMediaItem } from './types.js' +} from '@discordeno/types'; +import type { Bot } from '../bot.js'; +import type { DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from '../desiredProperties.js'; +import type { Component, MediaGalleryItem, UnfurledMediaItem } from './types.js'; export function transformComponent(bot: Bot, payload: DiscordMessageComponent | DiscordMessageComponentFromModalInteractionResponse): Component { - let component: SetupDesiredProps + let component: SetupDesiredProps; // This switch is exhaustive, so we dont need the default case and TS does not error out for the un-initialized component variable switch (payload.type) { case MessageComponentTypes.ActionRow: - component = transformActionRow(bot, payload) - break + component = transformActionRow(bot, payload); + break; case MessageComponentTypes.Button: - component = transformButtonComponent(bot, payload) - break + component = transformButtonComponent(bot, payload); + break; case MessageComponentTypes.Container: - component = transformContainerComponent(bot, payload) - break + component = transformContainerComponent(bot, payload); + break; case MessageComponentTypes.TextInput: - component = transformInputTextComponent(bot, payload) - break + component = transformInputTextComponent(bot, payload); + break; case MessageComponentTypes.StringSelect: case MessageComponentTypes.UserSelect: case MessageComponentTypes.RoleSelect: case MessageComponentTypes.MentionableSelect: case MessageComponentTypes.ChannelSelect: - component = transformSelectMenuComponent(bot, payload) - break + component = transformSelectMenuComponent(bot, payload); + break; case MessageComponentTypes.Section: - component = transformSectionComponent(bot, payload) - break + component = transformSectionComponent(bot, payload); + break; case MessageComponentTypes.Thumbnail: - component = transformThumbnailComponent(bot, payload) - break + component = transformThumbnailComponent(bot, payload); + break; case MessageComponentTypes.MediaGallery: - component = transformMediaGalleryComponent(bot, payload) - break + component = transformMediaGalleryComponent(bot, payload); + break; case MessageComponentTypes.File: - component = transformFileComponent(bot, payload) - break + component = transformFileComponent(bot, payload); + break; case MessageComponentTypes.Separator: - component = transformSeparatorComponent(bot, payload) - break + component = transformSeparatorComponent(bot, payload); + break; case MessageComponentTypes.TextDisplay: - component = transformTextDisplayComponent(bot, payload) - break + component = transformTextDisplayComponent(bot, payload); + break; case MessageComponentTypes.Label: - component = transformLabelComponent(bot, payload) - break + component = transformLabelComponent(bot, payload); + break; case MessageComponentTypes.FileUpload: - component = transformFileUploadComponent(bot, payload) - break + component = transformFileUploadComponent(bot, payload); + break; } - return bot.transformers.customizers.component(bot, payload, component) + return bot.transformers.customizers.component(bot, payload, component); } export function transformUnfurledMediaItem(bot: Bot, payload: DiscordUnfurledMediaItem): UnfurledMediaItem { - const props = bot.transformers.desiredProperties.unfurledMediaItem - const mediaItem = {} as SetupDesiredProps + const props = bot.transformers.desiredProperties.unfurledMediaItem; + const mediaItem = {} as SetupDesiredProps; - if (props.url && payload.url) mediaItem.url = payload.url - if (props.proxyUrl && payload.proxy_url) mediaItem.proxyUrl = payload.proxy_url - if (props.height && payload.height) mediaItem.height = payload.height - if (props.width && payload.width) mediaItem.width = payload.width - if (props.contentType && payload.content_type) mediaItem.contentType = payload.content_type - if (props.attachmentId && payload.attachment_id) mediaItem.attachmentId = bot.transformers.snowflake(payload.attachment_id) + if (props.url && payload.url) mediaItem.url = payload.url; + if (props.proxyUrl && payload.proxy_url) mediaItem.proxyUrl = payload.proxy_url; + if (props.height && payload.height) mediaItem.height = payload.height; + if (props.width && payload.width) mediaItem.width = payload.width; + if (props.contentType && payload.content_type) mediaItem.contentType = payload.content_type; + if (props.attachmentId && payload.attachment_id) mediaItem.attachmentId = bot.transformers.snowflake(payload.attachment_id); - return bot.transformers.customizers.unfurledMediaItem(bot, payload, mediaItem) + return bot.transformers.customizers.unfurledMediaItem(bot, payload, mediaItem); } export function transformMediaGalleryItem(bot: Bot, payload: DiscordMediaGalleryItem): MediaGalleryItem { - const props = bot.transformers.desiredProperties.mediaGalleryItem - const galleryItem = {} as SetupDesiredProps + const props = bot.transformers.desiredProperties.mediaGalleryItem; + const galleryItem = {} as SetupDesiredProps; - if (props.media && payload.media) galleryItem.media = bot.transformers.unfurledMediaItem(bot, payload.media) - if (props.description && payload.description) galleryItem.description = payload.description - if (props.spoiler && payload.spoiler) galleryItem.spoiler = payload.spoiler + if (props.media && payload.media) galleryItem.media = bot.transformers.unfurledMediaItem(bot, payload.media); + if (props.description && payload.description) galleryItem.description = payload.description; + if (props.spoiler && payload.spoiler) galleryItem.spoiler = payload.spoiler; - return bot.transformers.customizers.mediaGalleryItem(bot, payload, galleryItem) + return bot.transformers.customizers.mediaGalleryItem(bot, payload, galleryItem); } function transformActionRow(bot: Bot, payload: DiscordActionRow) { - const props = bot.transformers.desiredProperties.component - const actionRow = {} as SetupDesiredProps + const props = bot.transformers.desiredProperties.component; + const actionRow = {} as SetupDesiredProps; - if (props.type && payload.type) actionRow.type = payload.type - if (props.id && payload.id) actionRow.id = payload.id - if (props.components && payload.components) actionRow.components = payload.components.map((component) => bot.transformers.component(bot, component)) + if (props.type && payload.type) actionRow.type = payload.type; + if (props.id && payload.id) actionRow.id = payload.id; + if (props.components && payload.components) + actionRow.components = payload.components.map((component) => bot.transformers.component(bot, component)); - return actionRow + return actionRow; } function transformContainerComponent(bot: Bot, payload: DiscordContainerComponent) { - const props = bot.transformers.desiredProperties.component - const container = {} as SetupDesiredProps + const props = bot.transformers.desiredProperties.component; + const container = {} as SetupDesiredProps; - if (props.type && payload.type) container.type = payload.type - if (props.id && payload.id) container.id = payload.id - if (props.accentColor && payload.accent_color) container.accentColor = payload.accent_color - if (props.spoiler && payload.spoiler) container.spoiler = payload.spoiler - if (props.components && payload.components) container.components = payload.components.map((component) => bot.transformers.component(bot, component)) + if (props.type && payload.type) container.type = payload.type; + if (props.id && payload.id) container.id = payload.id; + if (props.accentColor && payload.accent_color) container.accentColor = payload.accent_color; + if (props.spoiler && payload.spoiler) container.spoiler = payload.spoiler; + if (props.components && payload.components) + container.components = payload.components.map((component) => bot.transformers.component(bot, component)); - return container + return container; } function transformButtonComponent(bot: Bot, payload: DiscordButtonComponent) { - const props = bot.transformers.desiredProperties.component - const button = {} as SetupDesiredProps + const props = bot.transformers.desiredProperties.component; + const button = {} as SetupDesiredProps; - if (props.type && payload.type) button.type = payload.type - if (props.id && payload.id) button.id = payload.id - if (props.label && payload.label) button.label = payload.label - if (props.customId && payload.custom_id) button.customId = payload.custom_id - if (props.style && payload.style) button.style = payload.style - if (props.emoji && payload.emoji) button.emoji = bot.transformers.emoji(bot, payload.emoji) - if (props.url && payload.url) button.url = payload.url - if (props.disabled && payload.disabled) button.disabled = payload.disabled - if (props.skuId && payload.sku_id) button.skuId = bot.transformers.snowflake(payload.sku_id) + if (props.type && payload.type) button.type = payload.type; + if (props.id && payload.id) button.id = payload.id; + if (props.label && payload.label) button.label = payload.label; + if (props.customId && payload.custom_id) button.customId = payload.custom_id; + if (props.style && payload.style) button.style = payload.style; + if (props.emoji && payload.emoji) button.emoji = bot.transformers.emoji(bot, payload.emoji); + if (props.url && payload.url) button.url = payload.url; + if (props.disabled && payload.disabled) button.disabled = payload.disabled; + if (props.skuId && payload.sku_id) button.skuId = bot.transformers.snowflake(payload.sku_id); - return button + return button; } function transformInputTextComponent(bot: Bot, payload: DiscordTextInputComponent | DiscordTextInputInteractionResponse) { - const props = bot.transformers.desiredProperties.component - const input = {} as SetupDesiredProps + const props = bot.transformers.desiredProperties.component; + const input = {} as SetupDesiredProps; - if (props.type && payload.type) input.type = payload.type - if (props.id && payload.id) input.id = payload.id - if (props.value && payload.value) input.value = payload.value - if (props.customId && payload.custom_id) input.customId = payload.custom_id + if (props.type && payload.type) input.type = payload.type; + if (props.id && payload.id) input.id = payload.id; + if (props.value && payload.value) input.value = payload.value; + if (props.customId && payload.custom_id) input.customId = payload.custom_id; // Check if it is the component or the response if ('style' in payload) { - if (props.style && payload.style) input.style = payload.style - if (props.required && payload.required) input.required = payload.required - if (props.label && payload.label) input.label = payload.label - if (props.placeholder && payload.placeholder) input.placeholder = payload.placeholder - if (props.minLength && payload.min_length) input.minLength = payload.min_length - if (props.maxLength && payload.max_length) input.maxLength = payload.max_length + if (props.style && payload.style) input.style = payload.style; + if (props.required && payload.required) input.required = payload.required; + if (props.label && payload.label) input.label = payload.label; + if (props.placeholder && payload.placeholder) input.placeholder = payload.placeholder; + if (props.minLength && payload.min_length) input.minLength = payload.min_length; + if (props.maxLength && payload.max_length) input.maxLength = payload.max_length; } - return input + return input; } function transformSelectMenuComponent(bot: Bot, payload: DiscordSelectMenuComponent | DiscordStringSelectInteractionResponse) { - const props = bot.transformers.desiredProperties.component - const select = {} as SetupDesiredProps + const props = bot.transformers.desiredProperties.component; + const select = {} as SetupDesiredProps; - if (props.type && payload.type) select.type = payload.type - if (props.id && payload.id) select.id = payload.id - if (props.customId && payload.custom_id) select.customId = payload.custom_id + if (props.type && payload.type) select.type = payload.type; + if (props.id && payload.id) select.id = payload.id; + if (props.customId && payload.custom_id) select.customId = payload.custom_id; // Check if this is the string select response if ('values' in payload) { - if (props.values && payload.values) select.values = payload.values + if (props.values && payload.values) select.values = payload.values; } else { - if (props.placeholder && payload.placeholder) select.placeholder = payload.placeholder - if (props.minValues && payload.min_values) select.minValues = payload.min_values - if (props.maxValues && payload.max_values) select.maxValues = payload.max_values + if (props.placeholder && payload.placeholder) select.placeholder = payload.placeholder; + if (props.minValues && payload.min_values) select.minValues = payload.min_values; + if (props.maxValues && payload.max_values) select.maxValues = payload.max_values; if (props.defaultValues && payload.default_values) select.defaultValues = payload.default_values.map((defaultValue) => ({ id: bot.transformers.snowflake(defaultValue.id), type: defaultValue.type, - })) - if (props.channelTypes && payload.channel_types) select.channelTypes = payload.channel_types + })); + if (props.channelTypes && payload.channel_types) select.channelTypes = payload.channel_types; if (props.options && payload.options) select.options = payload.options.map((option) => ({ label: option.label, @@ -202,121 +204,121 @@ function transformSelectMenuComponent(bot: Bot, payload: DiscordSelectMenuCompon } : undefined, default: option.default, - })) - if (props.disabled && payload.disabled) select.disabled = payload.disabled + })); + if (props.disabled && payload.disabled) select.disabled = payload.disabled; } - return select + return select; } function transformSectionComponent(bot: Bot, payload: DiscordSectionComponent) { - const props = bot.transformers.desiredProperties.component - const section = {} as SetupDesiredProps + const props = bot.transformers.desiredProperties.component; + const section = {} as SetupDesiredProps; - if (props.type && payload.type) section.type = payload.type - if (props.id && payload.id) section.id = payload.id - if (props.components && payload.components) section.components = payload.components.map((component) => bot.transformers.component(bot, component)) - if (props.accessory && payload.accessory) section.accessory = bot.transformers.component(bot, payload.accessory) + if (props.type && payload.type) section.type = payload.type; + if (props.id && payload.id) section.id = payload.id; + if (props.components && payload.components) section.components = payload.components.map((component) => bot.transformers.component(bot, component)); + if (props.accessory && payload.accessory) section.accessory = bot.transformers.component(bot, payload.accessory); - return section + return section; } function transformThumbnailComponent(bot: Bot, payload: DiscordThumbnailComponent) { - const props = bot.transformers.desiredProperties.component - const thumbnail = {} as SetupDesiredProps + const props = bot.transformers.desiredProperties.component; + const thumbnail = {} as SetupDesiredProps; - if (props.type && payload.type) thumbnail.type = payload.type - if (props.id && payload.id) thumbnail.id = payload.id - if (props.media && payload.media) thumbnail.media = bot.transformers.unfurledMediaItem(bot, payload.media) - if (props.description && payload.description) thumbnail.description = payload.description - if (props.spoiler && payload.spoiler) thumbnail.spoiler = payload.spoiler + if (props.type && payload.type) thumbnail.type = payload.type; + if (props.id && payload.id) thumbnail.id = payload.id; + if (props.media && payload.media) thumbnail.media = bot.transformers.unfurledMediaItem(bot, payload.media); + if (props.description && payload.description) thumbnail.description = payload.description; + if (props.spoiler && payload.spoiler) thumbnail.spoiler = payload.spoiler; - return thumbnail + return thumbnail; } function transformMediaGalleryComponent(bot: Bot, payload: DiscordMediaGalleryComponent) { - const props = bot.transformers.desiredProperties.component - const mediaGallery = {} as SetupDesiredProps + const props = bot.transformers.desiredProperties.component; + const mediaGallery = {} as SetupDesiredProps; - if (props.type && payload.type) mediaGallery.type = payload.type - if (props.id && payload.id) mediaGallery.id = payload.id - if (props.items && payload.items) mediaGallery.items = payload.items.map((item) => bot.transformers.mediaGalleryItem(bot, item)) + if (props.type && payload.type) mediaGallery.type = payload.type; + if (props.id && payload.id) mediaGallery.id = payload.id; + if (props.items && payload.items) mediaGallery.items = payload.items.map((item) => bot.transformers.mediaGalleryItem(bot, item)); - return mediaGallery + return mediaGallery; } function transformFileComponent(bot: Bot, payload: DiscordFileComponent) { - const props = bot.transformers.desiredProperties.component - const file = {} as SetupDesiredProps + const props = bot.transformers.desiredProperties.component; + const file = {} as SetupDesiredProps; - if (props.type && payload.type) file.type = payload.type - if (props.id && payload.id) file.id = payload.id - if (props.file && payload.file) file.file = bot.transformers.unfurledMediaItem(bot, payload.file) - if (props.spoiler && payload.spoiler) file.spoiler = payload.spoiler - if (props.name && payload.name) file.name = payload.name - if (props.size && payload.size) file.size = payload.size + if (props.type && payload.type) file.type = payload.type; + if (props.id && payload.id) file.id = payload.id; + if (props.file && payload.file) file.file = bot.transformers.unfurledMediaItem(bot, payload.file); + if (props.spoiler && payload.spoiler) file.spoiler = payload.spoiler; + if (props.name && payload.name) file.name = payload.name; + if (props.size && payload.size) file.size = payload.size; - return file + return file; } function transformTextDisplayComponent(bot: Bot, payload: DiscordTextDisplayComponent | DiscordTextDisplayInteractionResponse) { - const props = bot.transformers.desiredProperties.component - const textDisplay = {} as SetupDesiredProps + const props = bot.transformers.desiredProperties.component; + const textDisplay = {} as SetupDesiredProps; - if (props.type && payload.type) textDisplay.type = payload.type - if (props.id && payload.id) textDisplay.id = payload.id + if (props.type && payload.type) textDisplay.type = payload.type; + if (props.id && payload.id) textDisplay.id = payload.id; // That that this isn't a response if ('content' in payload) { - if (props.content && payload.content) textDisplay.content = payload.content + if (props.content && payload.content) textDisplay.content = payload.content; } - return textDisplay + return textDisplay; } function transformSeparatorComponent(bot: Bot, payload: DiscordSeparatorComponent) { - const props = bot.transformers.desiredProperties.component - const separator = {} as SetupDesiredProps + const props = bot.transformers.desiredProperties.component; + const separator = {} as SetupDesiredProps; - if (props.type && payload.type) separator.type = payload.type - if (props.id && payload.id) separator.id = payload.id - if (props.divider && payload.divider) separator.divider = payload.divider - if (props.spacing && payload.spacing) separator.spacing = payload.spacing + if (props.type && payload.type) separator.type = payload.type; + if (props.id && payload.id) separator.id = payload.id; + if (props.divider && payload.divider) separator.divider = payload.divider; + if (props.spacing && payload.spacing) separator.spacing = payload.spacing; - return separator + return separator; } function transformLabelComponent(bot: Bot, payload: DiscordLabelComponent | DiscordLabelInteractionResponse) { - const props = bot.transformers.desiredProperties.component - const label = {} as SetupDesiredProps + const props = bot.transformers.desiredProperties.component; + const label = {} as SetupDesiredProps; - if (props.type && payload.type) label.type = payload.type - if (props.id && payload.id) label.id = payload.id + if (props.type && payload.type) label.type = payload.type; + if (props.id && payload.id) label.id = payload.id; // Check that this isn't a response if ('label' in payload) { - if (props.label && payload.label) label.label = payload.label - if (props.description && payload.description) label.description = payload.description + if (props.label && payload.label) label.label = payload.label; + if (props.description && payload.description) label.description = payload.description; } - if (props.component && payload.component) label.component = bot.transformers.component(bot, payload.component) + if (props.component && payload.component) label.component = bot.transformers.component(bot, payload.component); - return label + return label; } function transformFileUploadComponent(bot: Bot, payload: DiscordFileUploadComponent | DiscordFileUploadInteractionResponse): Component { - const props = bot.transformers.desiredProperties.component - const fileUpload = {} as Component + const props = bot.transformers.desiredProperties.component; + const fileUpload = {} as Component; - if (props.type && payload.type) fileUpload.type = payload.type - if (props.id && payload.id) fileUpload.id = payload.id - if (props.customId && payload.custom_id) fileUpload.customId = payload.custom_id + if (props.type && payload.type) fileUpload.type = payload.type; + if (props.id && payload.id) fileUpload.id = payload.id; + if (props.customId && payload.custom_id) fileUpload.customId = payload.custom_id; // Check that this is a response if ('values' in payload) { - if (props.values && payload.values) fileUpload.values = payload.values + if (props.values && payload.values) fileUpload.values = payload.values; } else { - if (props.minValues && payload.min_values) fileUpload.minValues = payload.min_values - if (props.maxValues && payload.max_values) fileUpload.maxValues = payload.max_values - if (props.required && payload.required) fileUpload.required = payload.required + if (props.minValues && payload.min_values) fileUpload.minValues = payload.min_values; + if (props.maxValues && payload.max_values) fileUpload.maxValues = payload.max_values; + if (props.required && payload.required) fileUpload.required = payload.required; } - return fileUpload + return fileUpload; } diff --git a/packages/bot/src/transformers/embed.ts b/packages/bot/src/transformers/embed.ts index 45fe773fb..ad7bd171d 100644 --- a/packages/bot/src/transformers/embed.ts +++ b/packages/bot/src/transformers/embed.ts @@ -1,6 +1,6 @@ -import type { DiscordEmbed } from '@discordeno/types' -import type { Bot } from '../bot.js' -import type { Embed } from './types.js' +import type { DiscordEmbed } from '@discordeno/types'; +import type { Bot } from '../bot.js'; +import type { Embed } from './types.js'; export function transformEmbed(bot: Bot, payload: DiscordEmbed): Embed { const embed = { @@ -51,7 +51,7 @@ export function transformEmbed(bot: Bot, payload: DiscordEmbed): Embed { } : undefined, fields: payload.fields, - } as Embed + } as Embed; - return bot.transformers.customizers.embed(bot, payload, embed) + return bot.transformers.customizers.embed(bot, payload, embed); } diff --git a/packages/bot/src/transformers/emoji.ts b/packages/bot/src/transformers/emoji.ts index f75d3f27b..2740206f8 100644 --- a/packages/bot/src/transformers/emoji.ts +++ b/packages/bot/src/transformers/emoji.ts @@ -1,47 +1,47 @@ -import type { DiscordDefaultReactionEmoji, DiscordEmoji } from '@discordeno/types' -import type { Bot } from '../bot.js' -import type { DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from '../desiredProperties.js' -import { EmojiToggles } from './toggles/emoji.js' -import type { DefaultReactionEmoji, Emoji } from './types.js' +import type { DiscordDefaultReactionEmoji, DiscordEmoji } from '@discordeno/types'; +import type { Bot } from '../bot.js'; +import type { DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from '../desiredProperties.js'; +import { EmojiToggles } from './toggles/emoji.js'; +import type { DefaultReactionEmoji, Emoji } from './types.js'; export const baseEmoji: Emoji = { // This allows typescript to still check for type errors on functions below ...(undefined as unknown as Emoji), get animated() { - return this.toggles?.animated + return this.toggles?.animated; }, get requireColons() { - return this.toggles?.requireColons + return this.toggles?.requireColons; }, get managed() { - return this.toggles?.managed + return this.toggles?.managed; }, get available() { - return this.toggles.available + return this.toggles.available; }, -} +}; export function transformEmoji(bot: Bot, payload: DiscordEmoji): Emoji { - const props = bot.transformers.desiredProperties.emoji - const emoji = Object.create(baseEmoji) as SetupDesiredProps + const props = bot.transformers.desiredProperties.emoji; + const emoji = Object.create(baseEmoji) as SetupDesiredProps; - if (props.id && payload.id) emoji.id = bot.transformers.snowflake(payload.id) - if (props.name && payload.name) emoji.name = payload.name - if (props.roles && payload.roles) emoji.roles = payload.roles.map((id) => bot.transformers.snowflake(id)) - if (props.user && payload.user) emoji.user = bot.transformers.user(bot, payload.user) + if (props.id && payload.id) emoji.id = bot.transformers.snowflake(payload.id); + if (props.name && payload.name) emoji.name = payload.name; + if (props.roles && payload.roles) emoji.roles = payload.roles.map((id) => bot.transformers.snowflake(id)); + if (props.user && payload.user) emoji.user = bot.transformers.user(bot, payload.user); - emoji.toggles = new EmojiToggles(payload) + emoji.toggles = new EmojiToggles(payload); - return bot.transformers.customizers.emoji(bot, payload, emoji) + return bot.transformers.customizers.emoji(bot, payload, emoji); } export function transformDefaultReactionEmoji(bot: Bot, payload: DiscordDefaultReactionEmoji): DefaultReactionEmoji { - const props = bot.transformers.desiredProperties.defaultReactionEmoji - const defaultReactionEmoji = {} as SetupDesiredProps + const props = bot.transformers.desiredProperties.defaultReactionEmoji; + const defaultReactionEmoji = {} as SetupDesiredProps; - if (props.emojiId && payload.emoji_id) defaultReactionEmoji.emojiId = bot.transformers.snowflake(payload.emoji_id) - if (props.emojiName && payload.emoji_name) defaultReactionEmoji.emojiName = payload.emoji_name + if (props.emojiId && payload.emoji_id) defaultReactionEmoji.emojiId = bot.transformers.snowflake(payload.emoji_id); + if (props.emojiName && payload.emoji_name) defaultReactionEmoji.emojiName = payload.emoji_name; - return bot.transformers.customizers.defaultReactionEmoji(bot, payload, defaultReactionEmoji) + return bot.transformers.customizers.defaultReactionEmoji(bot, payload, defaultReactionEmoji); } diff --git a/packages/bot/src/transformers/entitlement.ts b/packages/bot/src/transformers/entitlement.ts index 907720329..c0956c0bf 100644 --- a/packages/bot/src/transformers/entitlement.ts +++ b/packages/bot/src/transformers/entitlement.ts @@ -1,22 +1,22 @@ -import type { DiscordEntitlement } from '@discordeno/types' -import type { Bot } from '../bot.js' -import type { DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from '../desiredProperties.js' -import type { Entitlement } from './types.js' +import type { DiscordEntitlement } from '@discordeno/types'; +import type { Bot } from '../bot.js'; +import type { DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from '../desiredProperties.js'; +import type { Entitlement } from './types.js'; export function transformEntitlement(bot: Bot, payload: DiscordEntitlement): Entitlement { - const props = bot.transformers.desiredProperties.entitlement - const entitlement = {} as SetupDesiredProps + const props = bot.transformers.desiredProperties.entitlement; + const entitlement = {} as SetupDesiredProps; - if (props.id && payload.id) entitlement.id = bot.transformers.snowflake(payload.id) - if (props.skuId && payload.sku_id) entitlement.skuId = bot.transformers.snowflake(payload.sku_id) - if (props.userId && payload.user_id) entitlement.userId = bot.transformers.snowflake(payload.user_id) - if (props.guildId && payload.guild_id) entitlement.guildId = bot.transformers.snowflake(payload.guild_id) - if (props.applicationId && payload.application_id) entitlement.applicationId = bot.transformers.snowflake(payload.application_id) - if (props.type && payload.type) entitlement.type = payload.type - if (props.deleted && payload.deleted !== undefined) entitlement.deleted = payload.deleted - if (props.startsAt && payload.starts_at) entitlement.startsAt = Date.parse(payload.starts_at) - if (props.endsAt && payload.ends_at) entitlement.endsAt = Date.parse(payload.ends_at) - if (props.consumed && payload.consumed !== undefined) entitlement.consumed = payload.consumed + if (props.id && payload.id) entitlement.id = bot.transformers.snowflake(payload.id); + if (props.skuId && payload.sku_id) entitlement.skuId = bot.transformers.snowflake(payload.sku_id); + if (props.userId && payload.user_id) entitlement.userId = bot.transformers.snowflake(payload.user_id); + if (props.guildId && payload.guild_id) entitlement.guildId = bot.transformers.snowflake(payload.guild_id); + if (props.applicationId && payload.application_id) entitlement.applicationId = bot.transformers.snowflake(payload.application_id); + if (props.type && payload.type) entitlement.type = payload.type; + if (props.deleted && payload.deleted !== undefined) entitlement.deleted = payload.deleted; + if (props.startsAt && payload.starts_at) entitlement.startsAt = Date.parse(payload.starts_at); + if (props.endsAt && payload.ends_at) entitlement.endsAt = Date.parse(payload.ends_at); + if (props.consumed && payload.consumed !== undefined) entitlement.consumed = payload.consumed; - return bot.transformers.customizers.entitlement(bot, payload, entitlement) + return bot.transformers.customizers.entitlement(bot, payload, entitlement); } diff --git a/packages/bot/src/transformers/gatewayBot.ts b/packages/bot/src/transformers/gatewayBot.ts index 6082fbf2a..9680c6c76 100644 --- a/packages/bot/src/transformers/gatewayBot.ts +++ b/packages/bot/src/transformers/gatewayBot.ts @@ -1,6 +1,6 @@ -import type { DiscordGetGatewayBot } from '@discordeno/types' -import type { Bot } from '../bot.js' -import type { GetGatewayBot } from './types.js' +import type { DiscordGetGatewayBot } from '@discordeno/types'; +import type { Bot } from '../bot.js'; +import type { GetGatewayBot } from './types.js'; export function transformGatewayBot(bot: Bot, payload: DiscordGetGatewayBot): GetGatewayBot { const gatewayBot = { @@ -12,7 +12,7 @@ export function transformGatewayBot(bot: Bot, payload: DiscordGetGatewayBot): Ge resetAfter: payload.session_start_limit.reset_after, maxConcurrency: payload.session_start_limit.max_concurrency, }, - } as GetGatewayBot + } as GetGatewayBot; - return bot.transformers.customizers.gatewayBot(bot, payload, gatewayBot) + return bot.transformers.customizers.gatewayBot(bot, payload, gatewayBot); } diff --git a/packages/bot/src/transformers/guild.ts b/packages/bot/src/transformers/guild.ts index 9786a90e6..70fd18fb8 100644 --- a/packages/bot/src/transformers/guild.ts +++ b/packages/bot/src/transformers/guild.ts @@ -1,52 +1,52 @@ -import { ChannelTypes, type DiscordGuild, type DiscordPresenceUpdate } from '@discordeno/types' -import { Collection, iconHashToBigInt } from '@discordeno/utils' -import type { Bot } from '../bot.js' -import type { DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from '../desiredProperties.js' -import { GuildToggles } from './toggles/guild.js' -import type { Channel, Guild } from './types.js' +import { ChannelTypes, type DiscordGuild, type DiscordPresenceUpdate } from '@discordeno/types'; +import { Collection, iconHashToBigInt } from '@discordeno/utils'; +import type { Bot } from '../bot.js'; +import type { DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from '../desiredProperties.js'; +import { GuildToggles } from './toggles/guild.js'; +import type { Channel, Guild } from './types.js'; export const baseGuild: Guild = { // This allows typescript to still check for type errors on functions below ...(undefined as unknown as Guild), get threads() { - if (!this.channels) return new Collection() + if (!this.channels) return new Collection(); const threads = this.channels .array() - .filter((x) => x.type === ChannelTypes.PublicThread || x.type === ChannelTypes.PrivateThread || x.type === ChannelTypes.AnnouncementThread) + .filter((x) => x.type === ChannelTypes.PublicThread || x.type === ChannelTypes.PrivateThread || x.type === ChannelTypes.AnnouncementThread); - return new Collection(threads.map((x) => [x.id, x])) + return new Collection(threads.map((x) => [x.id, x])); }, get features() { - return this.toggles.features + return this.toggles.features; }, -} +}; export function transformGuild(bot: Bot, payload: DiscordGuild, extra?: { shardId?: number }): Guild { - const guildId = bot.transformers.snowflake(payload.id) - const props = bot.transformers.desiredProperties.guild - const guild: SetupDesiredProps = Object.create(baseGuild) + const guildId = bot.transformers.snowflake(payload.id); + const props = bot.transformers.desiredProperties.guild; + const guild: SetupDesiredProps = Object.create(baseGuild); - if (props.afkTimeout && payload.afk_timeout) guild.afkTimeout = payload.afk_timeout - if (props.approximateMemberCount && payload.approximate_member_count) guild.approximateMemberCount = payload.approximate_member_count - if (props.approximatePresenceCount && payload.approximate_presence_count) guild.approximatePresenceCount = payload.approximate_presence_count - if (props.defaultMessageNotifications) guild.defaultMessageNotifications = payload.default_message_notifications - if (props.description && payload.description) guild.description = payload.description - if (props.toggles) guild.toggles = new GuildToggles(payload) - if (props.explicitContentFilter) guild.explicitContentFilter = payload.explicit_content_filter - if (props.maxMembers && payload.max_members) guild.maxMembers = payload.max_members - if (props.maxPresences && payload.max_presences) guild.maxPresences = payload.max_presences ?? undefined - if (props.maxVideoChannelUsers && payload.max_video_channel_users) guild.maxVideoChannelUsers = payload.max_video_channel_users + if (props.afkTimeout && payload.afk_timeout) guild.afkTimeout = payload.afk_timeout; + if (props.approximateMemberCount && payload.approximate_member_count) guild.approximateMemberCount = payload.approximate_member_count; + if (props.approximatePresenceCount && payload.approximate_presence_count) guild.approximatePresenceCount = payload.approximate_presence_count; + if (props.defaultMessageNotifications) guild.defaultMessageNotifications = payload.default_message_notifications; + if (props.description && payload.description) guild.description = payload.description; + if (props.toggles) guild.toggles = new GuildToggles(payload); + if (props.explicitContentFilter) guild.explicitContentFilter = payload.explicit_content_filter; + if (props.maxMembers && payload.max_members) guild.maxMembers = payload.max_members; + if (props.maxPresences && payload.max_presences) guild.maxPresences = payload.max_presences ?? undefined; + if (props.maxVideoChannelUsers && payload.max_video_channel_users) guild.maxVideoChannelUsers = payload.max_video_channel_users; if (props.maxStageVideoChannelUsers && payload.max_stage_video_channel_users) - guild.maxStageVideoChannelUsers = payload.max_stage_video_channel_users - if (props.mfaLevel) guild.mfaLevel = payload.mfa_level - if (props.name && payload.name) guild.name = payload.name - if (props.nsfwLevel) guild.nsfwLevel = payload.nsfw_level - if (props.preferredLocale && payload.preferred_locale) guild.preferredLocale = payload.preferred_locale + guild.maxStageVideoChannelUsers = payload.max_stage_video_channel_users; + if (props.mfaLevel) guild.mfaLevel = payload.mfa_level; + if (props.name && payload.name) guild.name = payload.name; + if (props.nsfwLevel) guild.nsfwLevel = payload.nsfw_level; + if (props.preferredLocale && payload.preferred_locale) guild.preferredLocale = payload.preferred_locale; if (props.premiumSubscriptionCount && payload.premium_subscription_count !== undefined) - guild.premiumSubscriptionCount = payload.premium_subscription_count - if (props.premiumTier) guild.premiumTier = payload.premium_tier + guild.premiumSubscriptionCount = payload.premium_subscription_count; + if (props.premiumTier) guild.premiumTier = payload.premium_tier; if (props.stageInstances && payload.stage_instances) guild.stageInstances = payload.stage_instances.map((si) => ({ /** The id of this Stage instance */ @@ -57,59 +57,59 @@ export function transformGuild(bot: Bot, payload: DiscordGuild, extra?: { shardI channelId: bot.transformers.snowflake(si.channel_id), /** The topic of the Stage instance (1-120 characters) */ topic: si.topic, - })) + })); if (props.channels && (!!payload.channels || !!payload.threads)) guild.channels = new Collection( [...(payload.channels ?? []), ...(payload.threads ?? [])].map((channel) => { - const result = bot.transformers.channel(bot, channel, { guildId }) + const result = bot.transformers.channel(bot, channel, { guildId }); // TODO: We should check that id exists, or else the collection will have undefined as it's key (This is valid for all the collections below as well) // @ts-expect-error: See TODO above - return [result.id, result] + return [result.id, result]; }), - ) + ); if (props.members && payload.members) guild.members = new Collection( payload.members.map((member) => { - const result = bot.transformers.member(bot, member, { guildId, userId: bot.transformers.snowflake(member.user!.id) }) + const result = bot.transformers.member(bot, member, { guildId, userId: bot.transformers.snowflake(member.user!.id) }); // @ts-expect-error: See TODO above - return [result.id, result] + return [result.id, result]; }), - ) + ); if (props.roles && payload.roles) guild.roles = new Collection( payload.roles.map((role) => { - const result = bot.transformers.role(bot, role, { guildId }) + const result = bot.transformers.role(bot, role, { guildId }); // @ts-expect-error: See TODO above - return [result.id, result] + return [result.id, result]; }), - ) + ); if (props.emojis && payload.emojis) guild.emojis = new Collection( payload.emojis.map((emoji) => { - const result = bot.transformers.emoji(bot, emoji) + const result = bot.transformers.emoji(bot, emoji); // @ts-expect-error: See TODO above - return [result.id!, result] + return [result.id!, result]; }), - ) + ); if (props.voiceStates && payload.voice_states) guild.voiceStates = new Collection( payload.voice_states.map((voiceState) => { - const result = bot.transformers.voiceState(bot, voiceState, { guildId }) + const result = bot.transformers.voiceState(bot, voiceState, { guildId }); // @ts-expect-error: See TODO above - return [result.userId, result] + return [result.userId, result]; }), - ) + ); if (props.stickers && payload.stickers) guild.stickers = new Collection( payload.stickers?.map((sticker) => { - const result = bot.transformers.sticker(bot, sticker) + const result = bot.transformers.sticker(bot, sticker); // @ts-expect-error: See TODO above - return [result.id, result] + return [result.id, result]; }), - ) - if (props.systemChannelFlags && payload.system_channel_flags) guild.systemChannelFlags = payload.system_channel_flags - if (props.vanityUrlCode && payload.vanity_url_code) guild.vanityUrlCode = payload.vanity_url_code - if (props.verificationLevel) guild.verificationLevel = payload.verification_level + ); + if (props.systemChannelFlags && payload.system_channel_flags) guild.systemChannelFlags = payload.system_channel_flags; + if (props.vanityUrlCode && payload.vanity_url_code) guild.vanityUrlCode = payload.vanity_url_code; + if (props.verificationLevel) guild.verificationLevel = payload.verification_level; if (props.welcomeScreen && payload.welcome_screen) guild.welcomeScreen = { description: payload.welcome_screen.description ?? undefined, @@ -119,35 +119,35 @@ export function transformGuild(bot: Bot, payload: DiscordGuild, extra?: { shardI emojiId: wc.emoji_id ? bot.transformers.snowflake(wc.emoji_id) : undefined, emojiName: wc.emoji_name ?? undefined, })), - } - if (props.discoverySplash && payload.discovery_splash) guild.discoverySplash = iconHashToBigInt(payload.discovery_splash) - if (props.joinedAt && payload.joined_at) guild.joinedAt = Date.parse(payload.joined_at) - if (props.memberCount && payload.member_count) guild.memberCount = payload.member_count ?? 0 - if (props.shardId && extra?.shardId) guild.shardId = extra.shardId - if (props.icon && payload.icon) guild.icon = iconHashToBigInt(payload.icon) - if (props.banner && payload.banner) guild.banner = iconHashToBigInt(payload.banner) - if (props.splash && payload.splash) guild.splash = iconHashToBigInt(payload.splash) - if (props.id && payload.id) guild.id = guildId - if (props.ownerId && payload.owner_id) guild.ownerId = bot.transformers.snowflake(payload.owner_id) - if (props.permissions && payload.permissions) guild.permissions = bot.transformers.snowflake(payload.permissions) - if (props.afkChannelId && payload.afk_channel_id) guild.afkChannelId = bot.transformers.snowflake(payload.afk_channel_id) - if (props.widgetChannelId && payload.widget_channel_id) guild.widgetChannelId = bot.transformers.snowflake(payload.widget_channel_id) - if (props.applicationId && payload.application_id) guild.applicationId = bot.transformers.snowflake(payload.application_id) - if (props.systemChannelId && payload.system_channel_id) guild.systemChannelId = bot.transformers.snowflake(payload.system_channel_id) - if (props.rulesChannelId && payload.rules_channel_id) guild.rulesChannelId = bot.transformers.snowflake(payload.rules_channel_id) + }; + if (props.discoverySplash && payload.discovery_splash) guild.discoverySplash = iconHashToBigInt(payload.discovery_splash); + if (props.joinedAt && payload.joined_at) guild.joinedAt = Date.parse(payload.joined_at); + if (props.memberCount && payload.member_count) guild.memberCount = payload.member_count ?? 0; + if (props.shardId && extra?.shardId) guild.shardId = extra.shardId; + if (props.icon && payload.icon) guild.icon = iconHashToBigInt(payload.icon); + if (props.banner && payload.banner) guild.banner = iconHashToBigInt(payload.banner); + if (props.splash && payload.splash) guild.splash = iconHashToBigInt(payload.splash); + if (props.id && payload.id) guild.id = guildId; + if (props.ownerId && payload.owner_id) guild.ownerId = bot.transformers.snowflake(payload.owner_id); + if (props.permissions && payload.permissions) guild.permissions = bot.transformers.snowflake(payload.permissions); + if (props.afkChannelId && payload.afk_channel_id) guild.afkChannelId = bot.transformers.snowflake(payload.afk_channel_id); + if (props.widgetChannelId && payload.widget_channel_id) guild.widgetChannelId = bot.transformers.snowflake(payload.widget_channel_id); + if (props.applicationId && payload.application_id) guild.applicationId = bot.transformers.snowflake(payload.application_id); + if (props.systemChannelId && payload.system_channel_id) guild.systemChannelId = bot.transformers.snowflake(payload.system_channel_id); + if (props.rulesChannelId && payload.rules_channel_id) guild.rulesChannelId = bot.transformers.snowflake(payload.rules_channel_id); if (props.publicUpdatesChannelId && payload.public_updates_channel_id) - guild.publicUpdatesChannelId = bot.transformers.snowflake(payload.public_updates_channel_id) - if (props.premiumProgressBarEnabled && payload.premium_progress_bar_enabled) guild.premiumProgressBarEnabled = payload.premium_progress_bar_enabled - if (props.large && payload.large) guild.large = payload.large - if (props.owner && payload.owner) guild.owner = payload.owner - if (props.widgetEnabled && payload.widget_enabled) guild.widgetEnabled = payload.widget_enabled - if (props.unavailable && payload.unavailable) guild.unavailable = payload.unavailable - if (props.iconHash && payload.icon_hash) guild.iconHash = iconHashToBigInt(payload.icon_hash) + guild.publicUpdatesChannelId = bot.transformers.snowflake(payload.public_updates_channel_id); + if (props.premiumProgressBarEnabled && payload.premium_progress_bar_enabled) guild.premiumProgressBarEnabled = payload.premium_progress_bar_enabled; + if (props.large && payload.large) guild.large = payload.large; + if (props.owner && payload.owner) guild.owner = payload.owner; + if (props.widgetEnabled && payload.widget_enabled) guild.widgetEnabled = payload.widget_enabled; + if (props.unavailable && payload.unavailable) guild.unavailable = payload.unavailable; + if (props.iconHash && payload.icon_hash) guild.iconHash = iconHashToBigInt(payload.icon_hash); if (props.presences && payload.presences) - guild.presences = payload.presences?.map((presence) => bot.transformers.presence(bot, presence as DiscordPresenceUpdate)) + guild.presences = payload.presences?.map((presence) => bot.transformers.presence(bot, presence as DiscordPresenceUpdate)); if (props.safetyAlertsChannelId && payload.safety_alerts_channel_id) - guild.safetyAlertsChannelId = bot.transformers.snowflake(payload.safety_alerts_channel_id) - if (props.incidentsData && payload.incidents_data) guild.incidentsData = bot.transformers.incidentsData(bot, payload.incidents_data) + guild.safetyAlertsChannelId = bot.transformers.snowflake(payload.safety_alerts_channel_id); + if (props.incidentsData && payload.incidents_data) guild.incidentsData = bot.transformers.incidentsData(bot, payload.incidents_data); - return bot.transformers.customizers.guild(bot, payload, guild, extra) + return bot.transformers.customizers.guild(bot, payload, guild, extra); } diff --git a/packages/bot/src/transformers/incidentsData.ts b/packages/bot/src/transformers/incidentsData.ts index b7f108ef7..4c1a1952d 100644 --- a/packages/bot/src/transformers/incidentsData.ts +++ b/packages/bot/src/transformers/incidentsData.ts @@ -1,16 +1,16 @@ -import type { DiscordIncidentsData } from '@discordeno/types' -import type { Bot } from '../bot.js' -import type { DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from '../desiredProperties.js' -import type { IncidentsData } from './types.js' +import type { DiscordIncidentsData } from '@discordeno/types'; +import type { Bot } from '../bot.js'; +import type { DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from '../desiredProperties.js'; +import type { IncidentsData } from './types.js'; export function transformIncidentsData(bot: Bot, payload: DiscordIncidentsData): IncidentsData { - const props = bot.transformers.desiredProperties.incidentsData - const incidentsData = {} as SetupDesiredProps + const props = bot.transformers.desiredProperties.incidentsData; + const incidentsData = {} as SetupDesiredProps; - if (props.invitesDisabledUntil && payload.invites_disabled_until) incidentsData.invitesDisabledUntil = Date.parse(payload.invites_disabled_until) - if (props.dmsDisabledUntil && payload.dms_disabled_until) incidentsData.dmsDisabledUntil = Date.parse(payload.dms_disabled_until) - if (props.dmSpamDetectedAt && payload.dm_spam_detected_at) incidentsData.dmSpamDetectedAt = Date.parse(payload.dm_spam_detected_at) - if (props.raidDetectedAt && payload.raid_detected_at) incidentsData.raidDetectedAt = Date.parse(payload.raid_detected_at) + if (props.invitesDisabledUntil && payload.invites_disabled_until) incidentsData.invitesDisabledUntil = Date.parse(payload.invites_disabled_until); + if (props.dmsDisabledUntil && payload.dms_disabled_until) incidentsData.dmsDisabledUntil = Date.parse(payload.dms_disabled_until); + if (props.dmSpamDetectedAt && payload.dm_spam_detected_at) incidentsData.dmSpamDetectedAt = Date.parse(payload.dm_spam_detected_at); + if (props.raidDetectedAt && payload.raid_detected_at) incidentsData.raidDetectedAt = Date.parse(payload.raid_detected_at); - return bot.transformers.customizers.incidentsData(bot, payload, incidentsData) + return bot.transformers.customizers.incidentsData(bot, payload, incidentsData); } diff --git a/packages/bot/src/transformers/index.ts b/packages/bot/src/transformers/index.ts index b01822923..03a3fef3c 100644 --- a/packages/bot/src/transformers/index.ts +++ b/packages/bot/src/transformers/index.ts @@ -1,50 +1,50 @@ -export * from './activity.js' -export * from './application.js' -export * from './applicationCommand.js' -export * from './applicationCommandOption.js' -export * from './applicationCommandOptionChoice.js' -export * from './applicationCommandPermission.js' -export * from './attachment.js' -export * from './auditLogEntry.js' -export * from './automodActionExecution.js' -export * from './automodRule.js' -export * from './avatarDecorationData.js' -export * from './channel.js' -export * from './component.js' -export * from './embed.js' -export * from './emoji.js' -export * from './entitlement.js' -export * from './gatewayBot.js' -export * from './guild.js' -export * from './incidentsData.js' -export * from './integration.js' -export * from './interaction.js' -export * from './invite.js' -export * from './lobby.js' -export * from './member.js' -export * from './message.js' -export * from './onboarding.js' -export * from './poll.js' -export * from './presence.js' -export * from './reverse/index.js' -export * from './role.js' -export * from './scheduledEvent.js' -export * from './sku.js' -export * from './soundboardSound.js' -export * from './stageInstance.js' -export * from './stageInviteInstance.js' -export * from './sticker.js' -export * from './subscription.js' -export * from './subscription.js' -export * from './team.js' -export * from './template.js' -export * from './threadMember.js' -export * from './toggles/index.js' -export * from './types.js' -export * from './user.js' -export * from './voiceRegion.js' -export * from './voiceState.js' -export * from './webhook.js' -export * from './welcomeScreen.js' -export * from './widget.js' -export * from './widgetSettings.js' +export * from './activity.js'; +export * from './application.js'; +export * from './applicationCommand.js'; +export * from './applicationCommandOption.js'; +export * from './applicationCommandOptionChoice.js'; +export * from './applicationCommandPermission.js'; +export * from './attachment.js'; +export * from './auditLogEntry.js'; +export * from './automodActionExecution.js'; +export * from './automodRule.js'; +export * from './avatarDecorationData.js'; +export * from './channel.js'; +export * from './component.js'; +export * from './embed.js'; +export * from './emoji.js'; +export * from './entitlement.js'; +export * from './gatewayBot.js'; +export * from './guild.js'; +export * from './incidentsData.js'; +export * from './integration.js'; +export * from './interaction.js'; +export * from './invite.js'; +export * from './lobby.js'; +export * from './member.js'; +export * from './message.js'; +export * from './onboarding.js'; +export * from './poll.js'; +export * from './presence.js'; +export * from './reverse/index.js'; +export * from './role.js'; +export * from './scheduledEvent.js'; +export * from './sku.js'; +export * from './soundboardSound.js'; +export * from './stageInstance.js'; +export * from './stageInviteInstance.js'; +export * from './sticker.js'; +export * from './subscription.js'; +export * from './subscription.js'; +export * from './team.js'; +export * from './template.js'; +export * from './threadMember.js'; +export * from './toggles/index.js'; +export * from './types.js'; +export * from './user.js'; +export * from './voiceRegion.js'; +export * from './voiceState.js'; +export * from './webhook.js'; +export * from './welcomeScreen.js'; +export * from './widget.js'; +export * from './widgetSettings.js'; diff --git a/packages/bot/src/transformers/integration.ts b/packages/bot/src/transformers/integration.ts index 3e7bf644a..2c9468201 100644 --- a/packages/bot/src/transformers/integration.ts +++ b/packages/bot/src/transformers/integration.ts @@ -1,7 +1,7 @@ -import type { DiscordIntegrationCreateUpdate } from '@discordeno/types' -import { iconHashToBigInt } from '@discordeno/utils' -import type { Bot } from '../bot.js' -import type { Integration } from './types.js' +import type { DiscordIntegrationCreateUpdate } from '@discordeno/types'; +import { iconHashToBigInt } from '@discordeno/utils'; +import type { Bot } from '../bot.js'; +import type { Integration } from './types.js'; export function transformIntegration(bot: Bot, payload: DiscordIntegrationCreateUpdate): Integration { const integration = { @@ -33,7 +33,7 @@ export function transformIntegration(bot: Bot, payload: DiscordIntegrationCreate } : undefined, scopes: payload.scopes, - } as Integration + } as Integration; - return bot.transformers.customizers.integration(bot, payload, integration) + return bot.transformers.customizers.integration(bot, payload, integration); } diff --git a/packages/bot/src/transformers/interaction.ts b/packages/bot/src/transformers/interaction.ts index 5811520be..04337e424 100644 --- a/packages/bot/src/transformers/interaction.ts +++ b/packages/bot/src/transformers/interaction.ts @@ -10,17 +10,17 @@ import { InteractionResponseTypes, InteractionTypes, MessageFlags, -} from '@discordeno/types' -import { Collection } from '@discordeno/utils' -import type { Bot } from '../bot.js' -import type { InteractionResolvedDataChannel } from '../commandOptionsParser.js' +} from '@discordeno/types'; +import { Collection } from '@discordeno/utils'; +import type { Bot } from '../bot.js'; +import type { InteractionResolvedDataChannel } from '../commandOptionsParser.js'; import type { CompleteDesiredProperties, DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties, TransformProperty, -} from '../desiredProperties.js' +} from '../desiredProperties.js'; import type { Interaction, InteractionCallback, @@ -28,7 +28,7 @@ import type { InteractionDataOption, InteractionDataResolved, InteractionResource, -} from './types.js' +} from './types.js'; // Assume we have all desired properties for this or else typescript will get very confused for the return types of these functions. // This is used as a prototype, so the actual type with the user desired properties will be set later. @@ -37,79 +37,84 @@ export const baseInteraction: SetupDesiredProps, DesiredPropertiesBehavior.RemoveKey>), async respond(response, options) { - let type = InteractionResponseTypes.ChannelMessageWithSource + let type = InteractionResponseTypes.ChannelMessageWithSource; // If user provides a string, change it to a response object - if (typeof response === 'string') response = { content: response } + if (typeof response === 'string') response = { content: response }; - // If user provides an object, determine if it should be an autocomplete or a modal response - if (response.title) type = InteractionResponseTypes.Modal - if (this.type === InteractionTypes.ApplicationCommandAutocomplete) type = InteractionResponseTypes.ApplicationCommandAutocompleteResult - if (type === InteractionResponseTypes.ChannelMessageWithSource && options?.isPrivate) { - response.flags ??= 0 - response.flags |= MessageFlags.Ephemeral + // If user provides a type, use it + if (options?.type) type = options.type; + // Otherwise, determine if it should be an autocomplete or a modal response + else { + if (response.title) type = InteractionResponseTypes.Modal; + if (this.type === InteractionTypes.ApplicationCommandAutocomplete) type = InteractionResponseTypes.ApplicationCommandAutocompleteResult; } - // Since this has already been given a response, any further responses must be followups. - if (this.acknowledged) return await this.bot.helpers.sendFollowupMessage(this.token, response) - // Modals cannot be chained if (this.type === InteractionTypes.ModalSubmit && type === InteractionResponseTypes.Modal) - throw new Error('Cannot respond to a modal interaction with another modal.') + throw new Error('Cannot respond to a modal interaction with another modal.'); + + if (type === InteractionResponseTypes.ChannelMessageWithSource && options?.isPrivate) { + response.flags ??= 0; + response.flags |= MessageFlags.Ephemeral; + } + + // Since this has already been given a response, any further responses must be followups. + if (this.acknowledged) return await this.bot.helpers.sendFollowupMessage(this.token, response); const result = await this.bot.helpers.sendInteractionResponse( this.id, this.token, { type, data: response }, { withResponse: options?.withResponse }, - ) - this.acknowledged = true - return result + ); + this.acknowledged = true; + return result; }, async edit(response, messageId, options) { - if (this.type === InteractionTypes.ApplicationCommandAutocomplete) throw new Error('Cannot edit an autocomplete interaction.') + if (this.type === InteractionTypes.ApplicationCommandAutocomplete) throw new Error('Cannot edit an autocomplete interaction.'); // If user provides a string, change it to a response object - if (typeof response === 'string') response = { content: response } + if (typeof response === 'string') response = { content: response }; if (messageId) { - return await this.bot?.helpers.editFollowupMessage(this.token, messageId, response) + return await this.bot?.helpers.editFollowupMessage(this.token, messageId, response); } if (!this.acknowledged) { if (this.type !== InteractionTypes.MessageComponent && this.type !== InteractionTypes.ModalSubmit) - throw new Error("This interaction has not been responded to yet and this isn't a MessageComponent or ModalSubmit interaction.") + throw new Error("This interaction has not been responded to yet and this isn't a MessageComponent or ModalSubmit interaction."); const result = await this.bot.helpers.sendInteractionResponse( this.id, this.token, { type: InteractionResponseTypes.UpdateMessage, data: response }, options, - ) - this.acknowledged = true - return result + ); + this.acknowledged = true; + return result; } - return await this.bot.helpers.editOriginalInteractionResponse(this.token, response) + return await this.bot.helpers.editOriginalInteractionResponse(this.token, response); }, async deferEdit(options) { - if (this.type === InteractionTypes.ApplicationCommandAutocomplete) throw new Error('Cannot edit an autocomplete interaction.') - if (this.acknowledged) throw new Error('Cannot defer an already responded interaction.') + if (this.type === InteractionTypes.ApplicationCommandAutocomplete) throw new Error('Cannot edit an autocomplete interaction.'); + if (this.acknowledged) throw new Error('Cannot defer an already responded interaction.'); if (this.type !== InteractionTypes.MessageComponent && this.type !== InteractionTypes.ModalSubmit) - throw new Error("Cannot defer to then edit an interaction that isn't a MessageComponent or ModalSubmit interaction.") + throw new Error("Cannot defer to then edit an interaction that isn't a MessageComponent or ModalSubmit interaction."); const result = await this.bot.helpers.sendInteractionResponse( this.id, this.token, { type: InteractionResponseTypes.DeferredUpdateMessage }, options, - ) - this.acknowledged = true - return result + ); + this.acknowledged = true; + return result; }, async defer(isPrivate, options) { - if (this.acknowledged) throw new Error('Cannot defer an already responded interaction.') + if (this.acknowledged) throw new Error('Cannot defer an already responded interaction.'); const result = await this.bot.helpers.sendInteractionResponse( this.id, @@ -121,68 +126,68 @@ export const baseInteraction: SetupDesiredProps = Object.create(baseInteraction) - const props = bot.transformers.desiredProperties.interaction + const interaction: SetupDesiredProps = Object.create(baseInteraction); + const props = bot.transformers.desiredProperties.interaction; - interaction.bot = bot - interaction.acknowledged = false + interaction.bot = bot; + interaction.acknowledged = false; - if (props.id && payload.id) interaction.id = bot.transformers.snowflake(payload.id) - if (props.applicationId && payload.application_id) interaction.applicationId = bot.transformers.snowflake(payload.application_id) - if (props.type && payload.type) interaction.type = payload.type - if (props.token && payload.token) interaction.token = payload.token - if (props.version && payload.version) interaction.version = payload.version - if (props.locale && payload.locale) interaction.locale = payload.locale - if (props.guildLocale && payload.guild_locale) interaction.guildLocale = payload.guild_locale + if (props.id && payload.id) interaction.id = bot.transformers.snowflake(payload.id); + if (props.applicationId && payload.application_id) interaction.applicationId = bot.transformers.snowflake(payload.application_id); + if (props.type && payload.type) interaction.type = payload.type; + if (props.token && payload.token) interaction.token = payload.token; + if (props.version && payload.version) interaction.version = payload.version; + if (props.locale && payload.locale) interaction.locale = payload.locale; + if (props.guildLocale && payload.guild_locale) interaction.guildLocale = payload.guild_locale; if (props.guild && payload.guild) // @ts-expect-error payload.guild is a Partial - interaction.guild = bot.transformers.guild(bot, payload.guild, { shardId: extra?.shardId }) - if (props.guildId && guildId) interaction.guildId = guildId + interaction.guild = bot.transformers.guild(bot, payload.guild, { shardId: extra?.shardId }); + if (props.guildId && guildId) interaction.guildId = guildId; if (props.user) { - if (payload.member?.user) interaction.user = bot.transformers.user(bot, payload.member?.user) - else if (payload.user) interaction.user = bot.transformers.user(bot, payload.user) + if (payload.member?.user) interaction.user = bot.transformers.user(bot, payload.member?.user); + else if (payload.user) interaction.user = bot.transformers.user(bot, payload.user); } - if (props.appPermissions && payload.app_permissions) interaction.appPermissions = bot.transformers.snowflake(payload.app_permissions) - if (props.message && payload.message) interaction.message = bot.transformers.message(bot, payload.message, { shardId: extra?.shardId }) + if (props.appPermissions && payload.app_permissions) interaction.appPermissions = bot.transformers.snowflake(payload.app_permissions); + if (props.message && payload.message) interaction.message = bot.transformers.message(bot, payload.message, { shardId: extra?.shardId }); if (props.channel && payload.channel) // @ts-expect-error payload.channel is a Partial<> - interaction.channel = bot.transformers.channel(bot, payload.channel, { guildId }) - if (props.channelId && payload.channel_id) interaction.channelId = bot.transformers.snowflake(payload.channel_id) + interaction.channel = bot.transformers.channel(bot, payload.channel, { guildId }); + if (props.channelId && payload.channel_id) interaction.channelId = bot.transformers.snowflake(payload.channel_id); if (props.member && guildId && payload.member) interaction.member = bot.transformers.member(bot, payload.member, { guildId, userId: payload.member?.user.id ?? payload.user?.id, - }) - if (props.entitlements && payload.entitlements) interaction.entitlements = payload.entitlements.map((e) => bot.transformers.entitlement(bot, e)) + }); + if (props.entitlements && payload.entitlements) interaction.entitlements = payload.entitlements.map((e) => bot.transformers.entitlement(bot, e)); if (props.authorizingIntegrationOwners && payload.authorizing_integration_owners) { - interaction.authorizingIntegrationOwners = {} + interaction.authorizingIntegrationOwners = {}; if (payload.authorizing_integration_owners['0']) interaction.authorizingIntegrationOwners[DiscordApplicationIntegrationType.GuildInstall] = bot.transformers.snowflake( payload.authorizing_integration_owners['0'], - ) + ); if (payload.authorizing_integration_owners['1']) interaction.authorizingIntegrationOwners[DiscordApplicationIntegrationType.UserInstall] = bot.transformers.snowflake( payload.authorizing_integration_owners['1'], - ) + ); } - if (props.context && payload.context) interaction.context = payload.context - if (props.attachmentSizeLimit && payload.attachment_size_limit) interaction.attachmentSizeLimit = payload.attachment_size_limit + if (props.context && payload.context) interaction.context = payload.context; + if (props.attachmentSizeLimit && payload.attachment_size_limit) interaction.attachmentSizeLimit = payload.attachment_size_limit; if (props.data && payload.data) { interaction.data = { type: payload.data.type, @@ -197,11 +202,11 @@ export function transformInteraction(bot: Bot, payload: DiscordInteraction, extr : undefined, options: payload.data.options?.map((opt) => bot.transformers.interactionDataOptions(bot, opt)), targetId: payload.data.target_id ? bot.transformers.snowflake(payload.data.target_id) : undefined, - } + }; } // Typescript has an hard time with interaction.bot, so we need to tell him for sure this interaction is the of the correct type - return bot.transformers.customizers.interaction(bot, payload, interaction as unknown as typeof bot.transformers.$inferredTypes.interaction, extra) + return bot.transformers.customizers.interaction(bot, payload, interaction as unknown as typeof bot.transformers.$inferredTypes.interaction, extra); } export function transformInteractionDataOption(bot: Bot, option: DiscordInteractionDataOption): InteractionDataOption { @@ -211,9 +216,9 @@ export function transformInteractionDataOption(bot: Bot, option: DiscordInteract value: option.value, options: option.options, focused: option.focused, - } as InteractionDataOption + } as InteractionDataOption; - return bot.transformers.customizers.interactionDataOptions(bot, option, opt) + return bot.transformers.customizers.interactionDataOptions(bot, option, opt); } export function transformInteractionDataResolved( @@ -221,29 +226,29 @@ export function transformInteractionDataResolved( payload: DiscordInteractionDataResolved, extra?: { shardId?: number; guildId?: BigString }, ): TransformProperty { - const transformed: TransformProperty = {} + const transformed: TransformProperty = {}; if (payload.messages) { transformed.messages = new Collection( Object.entries(payload.messages).map(([key, value]) => { // @ts-expect-error TODO: Deal with partials - const message = bot.transformers.message(bot, value, { shardId: extra?.shardId }) - const id = bot.transformers.snowflake(key) + const message = bot.transformers.message(bot, value, { shardId: extra?.shardId }); + const id = bot.transformers.snowflake(key); - return [id, message] + return [id, message]; }), - ) + ); } if (payload.users) { transformed.users = new Collection( Object.entries(payload.users).map(([key, value]) => { - const user = bot.transformers.user(bot, value) - const id = bot.transformers.snowflake(key) + const user = bot.transformers.user(bot, value); + const id = bot.transformers.snowflake(key); - return [id, user] + return [id, user]; }), - ) + ); } if (extra?.guildId && payload.members) { @@ -253,23 +258,23 @@ export function transformInteractionDataResolved( const member = bot.transformers.member(bot, value, { guildId: extra.guildId, userId: bot.transformers.snowflake(key), - }) - const id = bot.transformers.snowflake(key) + }); + const id = bot.transformers.snowflake(key); - return [id, member] + return [id, member]; }), - ) + ); } if (extra?.guildId && payload.roles) { transformed.roles = new Collection( Object.entries(payload.roles).map(([key, value]) => { - const role = bot.transformers.role(bot, value, { guildId: extra.guildId }) - const id = bot.transformers.snowflake(key) + const role = bot.transformers.role(bot, value, { guildId: extra.guildId }); + const id = bot.transformers.snowflake(key); - return [id, role] + return [id, role]; }), - ) + ); } if (payload.channels) { @@ -278,29 +283,29 @@ export function transformInteractionDataResolved( const channel = bot.transformers.channel(bot, value) as InteractionResolvedDataChannel< TransformersDesiredProperties, DesiredPropertiesBehavior.RemoveKey - > - const id = bot.transformers.snowflake(key) + >; + const id = bot.transformers.snowflake(key); - return [id, channel] + return [id, channel]; }), - ) + ); } if (payload.attachments) { transformed.attachments = new Collection( Object.entries(payload.attachments).map(([key, value]) => { - const id = bot.transformers.snowflake(key) - const attachment = bot.transformers.attachment(bot, value) + const id = bot.transformers.snowflake(key); + const attachment = bot.transformers.attachment(bot, value); - return [id, attachment] + return [id, attachment]; }), - ) + ); } return bot.transformers.customizers.interactionDataResolved(bot, payload, transformed, { shardId: extra?.shardId, guildId: extra?.guildId ? bot.transformers.snowflake(extra.guildId) : undefined, - }) + }); } export function transformInteractionCallbackResponse( @@ -308,36 +313,37 @@ export function transformInteractionCallbackResponse( payload: DiscordInteractionCallbackResponse, extra?: { shardId?: number }, ): InteractionCallbackResponse { - const props = bot.transformers.desiredProperties.interactionCallbackResponse - const response = {} as SetupDesiredProps + const props = bot.transformers.desiredProperties.interactionCallbackResponse; + const response = {} as SetupDesiredProps; - if (props.interaction && payload.interaction) response.interaction = bot.transformers.interactionCallback(bot, payload.interaction) - if (props.resource && payload.resource) response.resource = bot.transformers.interactionResource(bot, payload.resource, { shardId: extra?.shardId }) + if (props.interaction && payload.interaction) response.interaction = bot.transformers.interactionCallback(bot, payload.interaction); + if (props.resource && payload.resource) + response.resource = bot.transformers.interactionResource(bot, payload.resource, { shardId: extra?.shardId }); - return bot.transformers.customizers.interactionCallbackResponse(bot, payload, response, extra) + return bot.transformers.customizers.interactionCallbackResponse(bot, payload, response, extra); } export function transformInteractionCallback(bot: Bot, payload: DiscordInteractionCallback): InteractionCallback { - const props = bot.transformers.desiredProperties.interactionCallback - const callback = {} as SetupDesiredProps + const props = bot.transformers.desiredProperties.interactionCallback; + const callback = {} as SetupDesiredProps; - if (props.id && payload.id) callback.id = bot.transformers.snowflake(payload.id) - if (props.type && payload.type) callback.type = payload.type - if (props.activityInstanceId && payload.activity_instance_id) callback.activityInstanceId = payload.activity_instance_id - if (props.responseMessageId && payload.response_message_id) callback.responseMessageId = bot.transformers.snowflake(payload.response_message_id) - if (props.responseMessageEphemeral && payload.response_message_ephemeral) callback.responseMessageEphemeral = payload.response_message_ephemeral - if (props.responseMessageLoading && payload.response_message_loading) callback.responseMessageLoading = payload.response_message_loading + if (props.id && payload.id) callback.id = bot.transformers.snowflake(payload.id); + if (props.type && payload.type) callback.type = payload.type; + if (props.activityInstanceId && payload.activity_instance_id) callback.activityInstanceId = payload.activity_instance_id; + if (props.responseMessageId && payload.response_message_id) callback.responseMessageId = bot.transformers.snowflake(payload.response_message_id); + if (props.responseMessageEphemeral && payload.response_message_ephemeral) callback.responseMessageEphemeral = payload.response_message_ephemeral; + if (props.responseMessageLoading && payload.response_message_loading) callback.responseMessageLoading = payload.response_message_loading; - return bot.transformers.customizers.interactionCallback(bot, payload, callback) + return bot.transformers.customizers.interactionCallback(bot, payload, callback); } export function transformInteractionResource(bot: Bot, payload: DiscordInteractionResource, extra?: { shardId?: number }): InteractionResource { - const props = bot.transformers.desiredProperties.interactionResource - const resource = {} as SetupDesiredProps + const props = bot.transformers.desiredProperties.interactionResource; + const resource = {} as SetupDesiredProps; - if (props.type && payload.type) resource.type = payload.type - if (props.activityInstance && payload.activity_instance) resource.activityInstance = payload.activity_instance - if (props.message && payload.message) resource.message = bot.transformers.message(bot, payload.message, { shardId: extra?.shardId }) + if (props.type && payload.type) resource.type = payload.type; + if (props.activityInstance && payload.activity_instance) resource.activityInstance = payload.activity_instance; + if (props.message && payload.message) resource.message = bot.transformers.message(bot, payload.message, { shardId: extra?.shardId }); - return bot.transformers.customizers.interactionResource(bot, payload, resource, extra) + return bot.transformers.customizers.interactionResource(bot, payload, resource, extra); } diff --git a/packages/bot/src/transformers/invite.ts b/packages/bot/src/transformers/invite.ts index 29f756778..42655e7c1 100644 --- a/packages/bot/src/transformers/invite.ts +++ b/packages/bot/src/transformers/invite.ts @@ -1,44 +1,44 @@ -import type { DiscordInviteCreate, DiscordInviteMetadata } from '@discordeno/types' -import { isInviteWithMetadata } from '@discordeno/utils' -import type { Bot } from '../bot.js' -import type { DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from '../desiredProperties.js' -import { ToggleBitfield } from './toggles/ToggleBitfield.js' -import type { Invite } from './types.js' +import type { DiscordInviteCreate, DiscordInviteMetadata } from '@discordeno/types'; +import { isInviteWithMetadata } from '@discordeno/utils'; +import type { Bot } from '../bot.js'; +import type { DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from '../desiredProperties.js'; +import { ToggleBitfield } from './toggles/ToggleBitfield.js'; +import type { Invite } from './types.js'; export function transformInvite(bot: Bot, payload: DiscordInviteCreate | DiscordInviteMetadata, extra?: { shardId?: number }): Invite { - const props = bot.transformers.desiredProperties.invite - const invite = {} as SetupDesiredProps + const props = bot.transformers.desiredProperties.invite; + const invite = {} as SetupDesiredProps; - if (props.type && 'type' in payload) invite.type = payload.type - if (props.code && payload.code) invite.code = payload.code - if (props.createdAt && payload.created_at) invite.createdAt = Date.parse(payload.created_at) - if (props.inviter && payload.inviter) invite.inviter = bot.transformers.user(bot, payload.inviter) - if (props.maxAge) invite.maxAge = payload.max_age - if (props.maxUses) invite.maxUses = payload.max_uses - if (props.targetType && payload.target_type) invite.targetType = payload.target_type - if (props.targetUser && payload.target_user) invite.targetUser = bot.transformers.user(bot, payload.target_user) + if (props.type && 'type' in payload) invite.type = payload.type; + if (props.code && payload.code) invite.code = payload.code; + if (props.createdAt && payload.created_at) invite.createdAt = Date.parse(payload.created_at); + if (props.inviter && payload.inviter) invite.inviter = bot.transformers.user(bot, payload.inviter); + if (props.maxAge) invite.maxAge = payload.max_age; + if (props.maxUses) invite.maxUses = payload.max_uses; + if (props.targetType && payload.target_type) invite.targetType = payload.target_type; + if (props.targetUser && payload.target_user) invite.targetUser = bot.transformers.user(bot, payload.target_user); if (props.targetApplication && payload.target_application) // @ts-expect-error TODO: Partials - invite.targetApplication = bot.transformers.application(bot, payload.target_application, { shardId: extra?.shardId }) - if (props.temporary && payload.temporary) invite.temporary = payload.temporary - if (props.uses && payload.uses) invite.uses = payload.uses + invite.targetApplication = bot.transformers.application(bot, payload.target_application, { shardId: extra?.shardId }); + if (props.temporary && payload.temporary) invite.temporary = payload.temporary; + if (props.uses && payload.uses) invite.uses = payload.uses; if (isInviteWithMetadata(payload)) { - if (props.channelId && payload.channel?.id) invite.channelId = bot.transformers.snowflake(payload.channel.id) - if (props.guildId && payload.guild?.id) invite.guildId = bot.transformers.snowflake(payload.guild.id) - if (props.approximateMemberCount && payload.approximate_member_count) invite.approximateMemberCount = payload.approximate_member_count + if (props.channelId && payload.channel?.id) invite.channelId = bot.transformers.snowflake(payload.channel.id); + if (props.guildId && payload.guild?.id) invite.guildId = bot.transformers.snowflake(payload.guild.id); + if (props.approximateMemberCount && payload.approximate_member_count) invite.approximateMemberCount = payload.approximate_member_count; if (props.approximatePresenceCount && payload.approximate_presence_count !== undefined) - invite.approximatePresenceCount = payload.approximate_presence_count + invite.approximatePresenceCount = payload.approximate_presence_count; if (props.guildScheduledEvent && payload.guild_scheduled_event) - invite.guildScheduledEvent = bot.transformers.scheduledEvent(bot, payload.guild_scheduled_event) + invite.guildScheduledEvent = bot.transformers.scheduledEvent(bot, payload.guild_scheduled_event); if (props.expiresAt && payload.expires_at) { - invite.expiresAt = Date.parse(payload.expires_at) + invite.expiresAt = Date.parse(payload.expires_at); } - if (props.flags && payload.flags) invite.flags = new ToggleBitfield(payload.flags) + if (props.flags && payload.flags) invite.flags = new ToggleBitfield(payload.flags); } else { - if (props.channelId && payload.channel_id) invite.channelId = bot.transformers.snowflake(payload.channel_id) - if (props.guildId && payload.guild_id) invite.guildId = bot.transformers.snowflake(payload.guild_id) + if (props.channelId && payload.channel_id) invite.channelId = bot.transformers.snowflake(payload.channel_id); + if (props.guildId && payload.guild_id) invite.guildId = bot.transformers.snowflake(payload.guild_id); } - return bot.transformers.customizers.invite(bot, payload, invite, extra) + return bot.transformers.customizers.invite(bot, payload, invite, extra); } diff --git a/packages/bot/src/transformers/lobby.ts b/packages/bot/src/transformers/lobby.ts index 5370eb322..d3edfed2e 100644 --- a/packages/bot/src/transformers/lobby.ts +++ b/packages/bot/src/transformers/lobby.ts @@ -1,29 +1,29 @@ -import type { DiscordLobby, DiscordLobbyMember } from '@discordeno/types' -import type { Bot } from '../bot.js' -import type { DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from '../desiredProperties.js' -import { ToggleBitfield } from './toggles/ToggleBitfield.js' -import type { Lobby, LobbyMember } from './types.js' +import type { DiscordLobby, DiscordLobbyMember } from '@discordeno/types'; +import type { Bot } from '../bot.js'; +import type { DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from '../desiredProperties.js'; +import { ToggleBitfield } from './toggles/ToggleBitfield.js'; +import type { Lobby, LobbyMember } from './types.js'; export function transformLobby(bot: Bot, payload: DiscordLobby): Lobby { - const props = bot.transformers.desiredProperties.lobby - const lobby = {} as SetupDesiredProps + const props = bot.transformers.desiredProperties.lobby; + const lobby = {} as SetupDesiredProps; - if (props.id && payload.id) lobby.id = bot.transformers.snowflake(payload.id) - if (props.applicationId && payload.application_id) lobby.applicationId = bot.transformers.snowflake(payload.application_id) - if (props.metadata && payload.metadata) lobby.metadata = payload.metadata - if (props.members && payload.members) lobby.members = payload.members.map((member) => bot.transformers.lobbyMember(bot, member)) - if (props.linkedChannel && payload.linked_channel) lobby.linkedChannel = bot.transformers.channel(bot, payload.linked_channel) + if (props.id && payload.id) lobby.id = bot.transformers.snowflake(payload.id); + if (props.applicationId && payload.application_id) lobby.applicationId = bot.transformers.snowflake(payload.application_id); + if (props.metadata && payload.metadata) lobby.metadata = payload.metadata; + if (props.members && payload.members) lobby.members = payload.members.map((member) => bot.transformers.lobbyMember(bot, member)); + if (props.linkedChannel && payload.linked_channel) lobby.linkedChannel = bot.transformers.channel(bot, payload.linked_channel); - return bot.transformers.customizers.lobby(bot, payload, lobby) + return bot.transformers.customizers.lobby(bot, payload, lobby); } export function transformLobbyMember(bot: Bot, payload: DiscordLobbyMember): LobbyMember { - const props = bot.transformers.desiredProperties.lobbyMember - const lobbyMember = {} as SetupDesiredProps + const props = bot.transformers.desiredProperties.lobbyMember; + const lobbyMember = {} as SetupDesiredProps; - if (props.id && payload.id) lobbyMember.id = bot.transformers.snowflake(payload.id) - if (props.metadata && payload.metadata) lobbyMember.metadata = payload.metadata - if (props.flags && payload.flags) lobbyMember.flags = new ToggleBitfield(payload.flags) + if (props.id && payload.id) lobbyMember.id = bot.transformers.snowflake(payload.id); + if (props.metadata && payload.metadata) lobbyMember.metadata = payload.metadata; + if (props.flags && payload.flags) lobbyMember.flags = new ToggleBitfield(payload.flags); - return bot.transformers.customizers.lobbyMember(bot, payload, lobbyMember) + return bot.transformers.customizers.lobbyMember(bot, payload, lobbyMember); } diff --git a/packages/bot/src/transformers/member.ts b/packages/bot/src/transformers/member.ts index 63e8673c5..e7f2ab7af 100644 --- a/packages/bot/src/transformers/member.ts +++ b/packages/bot/src/transformers/member.ts @@ -1,63 +1,63 @@ -import type { BigString, DiscordMember } from '@discordeno/types' -import { iconHashToBigInt } from '@discordeno/utils' -import type { Bot } from '../bot.js' -import type { DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from '../desiredProperties.js' -import { MemberToggles } from './toggles/member.js' -import { Permissions } from './toggles/Permissions.js' -import type { Member } from './types.js' +import type { BigString, DiscordMember } from '@discordeno/types'; +import { iconHashToBigInt } from '@discordeno/utils'; +import type { Bot } from '../bot.js'; +import type { DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from '../desiredProperties.js'; +import { MemberToggles } from './toggles/member.js'; +import { Permissions } from './toggles/Permissions.js'; +import type { Member } from './types.js'; export const baseMember: Member = { // This allows typescript to still check for type errors on functions below ...(undefined as unknown as Member), get deaf() { - return !!this.toggles?.has('deaf') + return !!this.toggles?.has('deaf'); }, get mute() { - return !!this.toggles?.has('mute') + return !!this.toggles?.has('mute'); }, get pending() { - return !!this.toggles?.has('pending') + return !!this.toggles?.has('pending'); }, get flags() { - return this.toggles?.flags ?? 0 + return this.toggles?.flags ?? 0; }, get didRejoin() { - return !!this.toggles?.didRejoin + return !!this.toggles?.didRejoin; }, get startedOnboarding() { - return !!this.toggles?.startedOnboarding + return !!this.toggles?.startedOnboarding; }, get bypassesVerification() { - return !!this.toggles?.bypassesVerification + return !!this.toggles?.bypassesVerification; }, get completedOnboarding() { - return !!this.toggles?.completedOnboarding + return !!this.toggles?.completedOnboarding; }, -} +}; export function transformMember(bot: Bot, payload: DiscordMember, extra?: { guildId?: BigString; userId?: BigString }): Member { - const member: SetupDesiredProps = Object.create(baseMember) - const props = bot.transformers.desiredProperties.member + const member: SetupDesiredProps = Object.create(baseMember); + const props = bot.transformers.desiredProperties.member; - if (props.id && extra?.userId) member.id = typeof extra.userId === 'string' ? bot.transformers.snowflake(extra.userId) : extra.userId - if (props.guildId && extra?.guildId) member.guildId = typeof extra.guildId === 'string' ? bot.transformers.snowflake(extra.guildId) : extra.guildId - if (props.user && payload.user) member.user = bot.transformers.user(bot, payload.user) - if (props.nick && payload.nick) member.nick = payload.nick - if (props.roles && payload.roles) member.roles = payload.roles.map((id) => bot.transformers.snowflake(id)) - if (props.joinedAt && payload.joined_at) member.joinedAt = Date.parse(payload.joined_at) - if (props.premiumSince && payload.premium_since) member.premiumSince = Date.parse(payload.premium_since) + if (props.id && extra?.userId) member.id = typeof extra.userId === 'string' ? bot.transformers.snowflake(extra.userId) : extra.userId; + if (props.guildId && extra?.guildId) member.guildId = typeof extra.guildId === 'string' ? bot.transformers.snowflake(extra.guildId) : extra.guildId; + if (props.user && payload.user) member.user = bot.transformers.user(bot, payload.user); + if (props.nick && payload.nick) member.nick = payload.nick; + if (props.roles && payload.roles) member.roles = payload.roles.map((id) => bot.transformers.snowflake(id)); + if (props.joinedAt && payload.joined_at) member.joinedAt = Date.parse(payload.joined_at); + if (props.premiumSince && payload.premium_since) member.premiumSince = Date.parse(payload.premium_since); if (props.communicationDisabledUntil && payload.communication_disabled_until) - member.communicationDisabledUntil = Date.parse(payload.communication_disabled_until) - if (props.avatar && payload.avatar) member.avatar = iconHashToBigInt(payload.avatar) - if (props.banner && payload.banner) member.banner = iconHashToBigInt(payload.banner) - if (props.permissions && payload.permissions) member.permissions = new Permissions(payload.permissions) - if (props.toggles) member.toggles = new MemberToggles(payload) + member.communicationDisabledUntil = Date.parse(payload.communication_disabled_until); + if (props.avatar && payload.avatar) member.avatar = iconHashToBigInt(payload.avatar); + if (props.banner && payload.banner) member.banner = iconHashToBigInt(payload.banner); + if (props.permissions && payload.permissions) member.permissions = new Permissions(payload.permissions); + if (props.toggles) member.toggles = new MemberToggles(payload); if (props.avatarDecorationData && payload.avatar_decoration_data) - member.avatarDecorationData = bot.transformers.avatarDecorationData(bot, payload.avatar_decoration_data) + member.avatarDecorationData = bot.transformers.avatarDecorationData(bot, payload.avatar_decoration_data); return bot.transformers.customizers.member(bot, payload, member, { guildId: extra?.guildId ? bot.transformers.snowflake(extra.guildId) : undefined, userId: extra?.userId ? bot.transformers.snowflake(extra.userId) : undefined, - }) + }); } diff --git a/packages/bot/src/transformers/message.ts b/packages/bot/src/transformers/message.ts index 6a9657ddf..609ccb729 100644 --- a/packages/bot/src/transformers/message.ts +++ b/packages/bot/src/transformers/message.ts @@ -6,185 +6,185 @@ import { type DiscordMessagePin, type DiscordMessageSnapshot, MessageFlags, -} from '@discordeno/types' -import { snowflakeToTimestamp } from '@discordeno/utils' -import type { Bot } from '../bot.js' -import { CHANNEL_MENTION_REGEX } from '../constants.js' -import type { DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from '../desiredProperties.js' -import { ToggleBitfield } from './toggles/ToggleBitfield.js' -import type { Message, MessageCall, MessageInteraction, MessageInteractionMetadata, MessagePin, MessageSnapshot } from './types.js' +} from '@discordeno/types'; +import { snowflakeToTimestamp } from '@discordeno/utils'; +import type { Bot } from '../bot.js'; +import { CHANNEL_MENTION_REGEX } from '../constants.js'; +import type { DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from '../desiredProperties.js'; +import { ToggleBitfield } from './toggles/ToggleBitfield.js'; +import type { Message, MessageCall, MessageInteraction, MessageInteractionMetadata, MessagePin, MessageSnapshot } from './types.js'; -const EMPTY_STRING = '' +const EMPTY_STRING = ''; export const baseMessage: Message = { // This allows typescript to still check for type errors on functions below ...(undefined as unknown as Message), get crossposted() { - return this.flags?.contains(MessageFlags.Crossposted) ?? false + return this.flags?.contains(MessageFlags.Crossposted) ?? false; }, set crossposted(value: boolean) { - if (!this.flags) return - if (value) this.flags.add(MessageFlags.Crossposted) - else this.flags.remove(MessageFlags.Crossposted) + if (!this.flags) return; + if (value) this.flags.add(MessageFlags.Crossposted); + else this.flags.remove(MessageFlags.Crossposted); }, get ephemeral() { - return this.flags?.contains(MessageFlags.Ephemeral) ?? false + return this.flags?.contains(MessageFlags.Ephemeral) ?? false; }, set ephemeral(value: boolean) { - if (!this.flags) return - if (value) this.flags.add(MessageFlags.Ephemeral) - else this.flags.remove(MessageFlags.Ephemeral) + if (!this.flags) return; + if (value) this.flags.add(MessageFlags.Ephemeral); + else this.flags.remove(MessageFlags.Ephemeral); }, get failedToMentionSomeRolesInThread() { - return this.flags?.contains(MessageFlags.FailedToMentionSomeRolesInThread) ?? false + return this.flags?.contains(MessageFlags.FailedToMentionSomeRolesInThread) ?? false; }, set failedToMentionSomeRolesInThread(value: boolean) { - if (!this.flags) return - if (value) this.flags.add(MessageFlags.FailedToMentionSomeRolesInThread) - else this.flags.remove(MessageFlags.FailedToMentionSomeRolesInThread) + if (!this.flags) return; + if (value) this.flags.add(MessageFlags.FailedToMentionSomeRolesInThread); + else this.flags.remove(MessageFlags.FailedToMentionSomeRolesInThread); }, get hasThread() { - return this.flags?.contains(MessageFlags.HasThread) ?? false + return this.flags?.contains(MessageFlags.HasThread) ?? false; }, set hasThread(value: boolean) { - if (!this.flags) return - if (value) this.flags.add(MessageFlags.HasThread) - else this.flags.remove(MessageFlags.HasThread) + if (!this.flags) return; + if (value) this.flags.add(MessageFlags.HasThread); + else this.flags.remove(MessageFlags.HasThread); }, get isCrosspost() { - return this.flags?.contains(MessageFlags.IsCrosspost) ?? false + return this.flags?.contains(MessageFlags.IsCrosspost) ?? false; }, set isCrosspost(value: boolean) { - if (!this.flags) return - if (value) this.flags.add(MessageFlags.IsCrosspost) - else this.flags.remove(MessageFlags.IsCrosspost) + if (!this.flags) return; + if (value) this.flags.add(MessageFlags.IsCrosspost); + else this.flags.remove(MessageFlags.IsCrosspost); }, get loading() { - return this.flags?.contains(MessageFlags.Loading) ?? false + return this.flags?.contains(MessageFlags.Loading) ?? false; }, set loading(value: boolean) { - if (!this.flags) return - if (value) this.flags.add(MessageFlags.Loading) - else this.flags.remove(MessageFlags.Loading) + if (!this.flags) return; + if (value) this.flags.add(MessageFlags.Loading); + else this.flags.remove(MessageFlags.Loading); }, get mentionedUserIds() { - return this.mentions?.map((user) => user.id) ?? [] + return this.mentions?.map((user) => user.id) ?? []; }, get mentionEveryone() { - return this.bitfield?.contains(2) ?? false + return this.bitfield?.contains(2) ?? false; }, set mentionEveryone(value: boolean) { - if (!this.bitfield) return - if (value) this.bitfield.add(2) - else this.bitfield.remove(2) + if (!this.bitfield) return; + if (value) this.bitfield.add(2); + else this.bitfield.remove(2); }, get pinned() { - return this.bitfield?.contains(3) ?? false + return this.bitfield?.contains(3) ?? false; }, set pinned(value: boolean) { - if (!this.bitfield) return - if (value) this.bitfield.add(3) - else this.bitfield.remove(3) + if (!this.bitfield) return; + if (value) this.bitfield.add(3); + else this.bitfield.remove(3); }, get sourceMessageDeleted() { - return this.flags?.contains(MessageFlags.SourceMessageDeleted) ?? false + return this.flags?.contains(MessageFlags.SourceMessageDeleted) ?? false; }, set sourceMessageDeleted(value: boolean) { - if (!this.flags) return - if (value) this.flags.add(MessageFlags.SourceMessageDeleted) - else this.flags.remove(MessageFlags.SourceMessageDeleted) + if (!this.flags) return; + if (value) this.flags.add(MessageFlags.SourceMessageDeleted); + else this.flags.remove(MessageFlags.SourceMessageDeleted); }, get suppressEmbeds() { - return this.flags?.contains(MessageFlags.SuppressEmbeds) ?? false + return this.flags?.contains(MessageFlags.SuppressEmbeds) ?? false; }, set suppressEmbeds(value: boolean) { - if (!this.flags) return - if (value) this.flags.add(MessageFlags.SuppressEmbeds) - else this.flags.remove(MessageFlags.SuppressEmbeds) + if (!this.flags) return; + if (value) this.flags.add(MessageFlags.SuppressEmbeds); + else this.flags.remove(MessageFlags.SuppressEmbeds); }, get suppressNotifications() { - return this.flags?.contains(MessageFlags.SuppressNotifications) ?? false + return this.flags?.contains(MessageFlags.SuppressNotifications) ?? false; }, set suppressNotifications(value: boolean) { - if (!this.flags) return - if (value) this.flags.add(MessageFlags.SuppressNotifications) - else this.flags.remove(MessageFlags.SuppressNotifications) + if (!this.flags) return; + if (value) this.flags.add(MessageFlags.SuppressNotifications); + else this.flags.remove(MessageFlags.SuppressNotifications); }, get timestamp() { - return this.id ? snowflakeToTimestamp(this.id) : 0 + return this.id ? snowflakeToTimestamp(this.id) : 0; }, get tts() { - return this.bitfield?.contains(1) ?? false + return this.bitfield?.contains(1) ?? false; }, set tts(value: boolean) { - if (!this.bitfield) return - if (value) this.bitfield.add(1) - else this.bitfield.remove(1) + if (!this.bitfield) return; + if (value) this.bitfield.add(1); + else this.bitfield.remove(1); }, get urgent() { - return this.flags?.contains(MessageFlags.Urgent) ?? false + return this.flags?.contains(MessageFlags.Urgent) ?? false; }, set urgent(value: boolean) { - if (!this.flags) return - if (value) this.flags.add(MessageFlags.Urgent) - else this.flags.remove(MessageFlags.Urgent) + if (!this.flags) return; + if (value) this.flags.add(MessageFlags.Urgent); + else this.flags.remove(MessageFlags.Urgent); }, -} +}; export function transformMessage(bot: Bot, payload: DiscordMessage, extra?: { shardId?: number }): Message { - const guildId = payload.guild_id ? bot.transformers.snowflake(payload.guild_id) : undefined - const userId = payload.author?.id ? bot.transformers.snowflake(payload.author.id) : undefined + const guildId = payload.guild_id ? bot.transformers.snowflake(payload.guild_id) : undefined; + const userId = payload.author?.id ? bot.transformers.snowflake(payload.author.id) : undefined; - const message: SetupDesiredProps = Object.create(baseMessage) - message.bitfield = new ToggleBitfield() - message.flags = new ToggleBitfield(payload.flags) + const message: SetupDesiredProps = Object.create(baseMessage); + message.bitfield = new ToggleBitfield(); + message.flags = new ToggleBitfield(payload.flags); - const props = bot.transformers.desiredProperties.message + const props = bot.transformers.desiredProperties.message; - if (props.author && payload.author) message.author = bot.transformers.user(bot, payload.author) + if (props.author && payload.author) message.author = bot.transformers.user(bot, payload.author); if (props.application && payload.application) // @ts-expect-error TODO: Partials - message.application = bot.transformers.application(bot, payload.application, { shardId: extra?.shardId }) - if (props.applicationId && payload.application_id) message.applicationId = bot.transformers.snowflake(payload.application_id) + message.application = bot.transformers.application(bot, payload.application, { shardId: extra?.shardId }); + if (props.applicationId && payload.application_id) message.applicationId = bot.transformers.snowflake(payload.application_id); if (props.attachments && payload.attachments?.length) - message.attachments = payload.attachments.map((attachment) => bot.transformers.attachment(bot, attachment)) - if (props.channelId && payload.channel_id) message.channelId = bot.transformers.snowflake(payload.channel_id) - if (props.components && payload.components?.length) message.components = payload.components.map((comp) => bot.transformers.component(bot, comp)) - if (props.content) message.content = payload.content ?? EMPTY_STRING - if (props.editedTimestamp && payload.edited_timestamp) message.editedTimestamp = Date.parse(payload.edited_timestamp) - if (props.embeds && payload.embeds?.length) message.embeds = payload.embeds.map((embed) => bot.transformers.embed(bot, embed)) - if (props.guildId && guildId) message.guildId = guildId - if (props.id && payload.id) message.id = bot.transformers.snowflake(payload.id) + message.attachments = payload.attachments.map((attachment) => bot.transformers.attachment(bot, attachment)); + if (props.channelId && payload.channel_id) message.channelId = bot.transformers.snowflake(payload.channel_id); + if (props.components && payload.components?.length) message.components = payload.components.map((comp) => bot.transformers.component(bot, comp)); + if (props.content) message.content = payload.content ?? EMPTY_STRING; + if (props.editedTimestamp && payload.edited_timestamp) message.editedTimestamp = Date.parse(payload.edited_timestamp); + if (props.embeds && payload.embeds?.length) message.embeds = payload.embeds.map((embed) => bot.transformers.embed(bot, embed)); + if (props.guildId && guildId) message.guildId = guildId; + if (props.id && payload.id) message.id = bot.transformers.snowflake(payload.id); if (props.interactionMetadata && payload.interaction_metadata) - message.interactionMetadata = bot.transformers.messageInteractionMetadata(bot, payload.interaction_metadata) + message.interactionMetadata = bot.transformers.messageInteractionMetadata(bot, payload.interaction_metadata); if (props.interaction && payload.interaction) { - const interaction = {} as SetupDesiredProps - const messageInteractionProps = bot.transformers.desiredProperties.messageInteraction + const interaction = {} as SetupDesiredProps; + const messageInteractionProps = bot.transformers.desiredProperties.messageInteraction; if (messageInteractionProps.id) { - interaction.id = bot.transformers.snowflake(payload.interaction.id) + interaction.id = bot.transformers.snowflake(payload.interaction.id); } if (messageInteractionProps.member && payload.interaction.member) { // @ts-expect-error TODO: partial - check why this is partial and handle as needed - interaction.member = bot.transformers.member(bot, payload.interaction.member, { guildId, userId: payload.interaction.user.id }) + interaction.member = bot.transformers.member(bot, payload.interaction.member, { guildId, userId: payload.interaction.user.id }); } if (messageInteractionProps.name) { - interaction.name = payload.interaction.name + interaction.name = payload.interaction.name; } if (messageInteractionProps.type) { - interaction.type = payload.interaction.type + interaction.type = payload.interaction.type; } if (messageInteractionProps.user) { - interaction.user = bot.transformers.user(bot, payload.interaction.user) + interaction.user = bot.transformers.user(bot, payload.interaction.user); } - message.interaction = interaction + message.interaction = interaction; } if (props.member && guildId && userId && payload.member) // @ts-expect-error TODO: partial - message.member = bot.transformers.member(bot, payload.member, { guildId, userId }) - if (payload.mention_everyone) message.mentionEveryone = true + message.member = bot.transformers.member(bot, payload.member, { guildId, userId }); + if (payload.mention_everyone) message.mentionEveryone = true; if (props.mentionedChannelIds && payload.mention_channels?.length) { message.mentionedChannelIds = [ // Keep any ids tht discord sends @@ -194,33 +194,33 @@ export function transformMessage(bot: Bot, payload: DiscordMessage, extra?: { sh // converts the <#123> into 123 bot.transformers.snowflake(text.substring(2, text.length - 1)), ), - ] + ]; } if (props.mentionedRoleIds && payload.mention_roles?.length) - message.mentionedRoleIds = payload.mention_roles.map((id) => bot.transformers.snowflake(id)) - if (props.mentions && payload.mentions?.length) message.mentions = payload.mentions.map((user) => bot.transformers.user(bot, user)) + message.mentionedRoleIds = payload.mention_roles.map((id) => bot.transformers.snowflake(id)); + if (props.mentions && payload.mentions?.length) message.mentions = payload.mentions.map((user) => bot.transformers.user(bot, user)); if (props.messageReference && payload.message_reference) { - const reference = {} as NonNullable - const messageReferenceProps = bot.transformers.desiredProperties.messageReference + const reference = {} as NonNullable; + const messageReferenceProps = bot.transformers.desiredProperties.messageReference; if (messageReferenceProps.channelId && payload.message_reference.channel_id) { - reference.channelId = bot.transformers.snowflake(payload.message_reference.channel_id) + reference.channelId = bot.transformers.snowflake(payload.message_reference.channel_id); } if (messageReferenceProps.guildId && payload.message_reference.guild_id) { - reference.guildId = bot.transformers.snowflake(payload.message_reference.guild_id) + reference.guildId = bot.transformers.snowflake(payload.message_reference.guild_id); } if (messageReferenceProps.messageId && payload.message_reference.message_id) { - reference.messageId = bot.transformers.snowflake(payload.message_reference.message_id) + reference.messageId = bot.transformers.snowflake(payload.message_reference.message_id); } - message.messageReference = reference + message.messageReference = reference; } if (props.referencedMessage && payload.referenced_message) - message.referencedMessage = bot.transformers.message(bot, payload.referenced_message, { shardId: extra?.shardId }) + message.referencedMessage = bot.transformers.message(bot, payload.referenced_message, { shardId: extra?.shardId }); if (props.messageSnapshots && payload.message_snapshots) - message.messageSnapshots = payload.message_snapshots.map((snap) => bot.transformers.messageSnapshot(bot, snap, { shardId: extra?.shardId })) - if (props.nonce && payload.nonce) message.nonce = payload.nonce - if (payload.pinned) message.pinned = true + message.messageSnapshots = payload.message_snapshots.map((snap) => bot.transformers.messageSnapshot(bot, snap, { shardId: extra?.shardId })); + if (props.nonce && payload.nonce) message.nonce = payload.nonce; + if (payload.pinned) message.pinned = true; if (props.reactions && payload.reactions?.length) { message.reactions = payload.reactions.map((reaction) => ({ me: reaction.me, @@ -233,90 +233,90 @@ export function transformMessage(bot: Bot, payload: DiscordMessage, extra?: { sh // @ts-expect-error TODO: Deal with partials emoji: bot.transformers.emoji(bot, reaction.emoji), burstColors: reaction.burst_colors, - })) + })); } if (props.stickerItems && payload.sticker_items?.length) message.stickerItems = payload.sticker_items.map((item) => ({ id: bot.transformers.snowflake(item.id), name: item.name, formatType: item.format_type, - })) - if (payload.tts) message.tts = true - if (props.thread && payload.thread) message.thread = bot.transformers.channel(bot, payload.thread, { guildId }) - if (props.type) message.type = payload.type - if (props.webhookId && payload.webhook_id) message.webhookId = bot.transformers.snowflake(payload.webhook_id) - if (props.poll && payload.poll) message.poll = bot.transformers.poll(bot, payload.poll) - if (props.call && payload.call) message.call = bot.transformers.messageCall(bot, payload.call) + })); + if (payload.tts) message.tts = true; + if (props.thread && payload.thread) message.thread = bot.transformers.channel(bot, payload.thread, { guildId }); + if (props.type) message.type = payload.type; + if (props.webhookId && payload.webhook_id) message.webhookId = bot.transformers.snowflake(payload.webhook_id); + if (props.poll && payload.poll) message.poll = bot.transformers.poll(bot, payload.poll); + if (props.call && payload.call) message.call = bot.transformers.messageCall(bot, payload.call); - return bot.transformers.customizers.message(bot, payload, message, extra) + return bot.transformers.customizers.message(bot, payload, message, extra); } export function transformMessagePin(bot: Bot, payload: DiscordMessagePin, extra?: { shardId?: number }): MessagePin { - const props = bot.transformers.desiredProperties.messagePin - const messagePin = {} as SetupDesiredProps + const props = bot.transformers.desiredProperties.messagePin; + const messagePin = {} as SetupDesiredProps; - if (props.pinnedAt && payload.pinned_at) messagePin.pinnedAt = Date.parse(payload.pinned_at) - if (props.message && payload.message) messagePin.message = bot.transformers.message(bot, payload.message, { shardId: extra?.shardId }) + if (props.pinnedAt && payload.pinned_at) messagePin.pinnedAt = Date.parse(payload.pinned_at); + if (props.message && payload.message) messagePin.message = bot.transformers.message(bot, payload.message, { shardId: extra?.shardId }); - return bot.transformers.customizers.messagePin(bot, payload, messagePin, extra) + return bot.transformers.customizers.messagePin(bot, payload, messagePin, extra); } export function transformMessageSnapshot(bot: Bot, payload: DiscordMessageSnapshot, extra?: { shardId?: number }): MessageSnapshot { - const props = bot.transformers.desiredProperties.messageSnapshot - const messageSnapshot = {} as SetupDesiredProps + const props = bot.transformers.desiredProperties.messageSnapshot; + const messageSnapshot = {} as SetupDesiredProps; if (props.message && payload.message) // @ts-expect-error TODO: Partials - messageSnapshot.message = bot.transformers.message(bot, payload.message, { shardId: extra?.shardId }) as Message + messageSnapshot.message = bot.transformers.message(bot, payload.message, { shardId: extra?.shardId }) as Message; - return bot.transformers.customizers.messageSnapshot(bot, payload, messageSnapshot, extra) + return bot.transformers.customizers.messageSnapshot(bot, payload, messageSnapshot, extra); } export function transformMessageInteractionMetadata(bot: Bot, payload: DiscordMessageInteractionMetadata): MessageInteractionMetadata { - const props = bot.transformers.desiredProperties.messageInteractionMetadata - const metadata = {} as SetupDesiredProps + const props = bot.transformers.desiredProperties.messageInteractionMetadata; + const metadata = {} as SetupDesiredProps; - if (props.id) metadata.id = bot.transformers.snowflake(payload.id) + if (props.id) metadata.id = bot.transformers.snowflake(payload.id); if (props.authorizingIntegrationOwners) { - metadata.authorizingIntegrationOwners = {} + metadata.authorizingIntegrationOwners = {}; if (payload.authorizing_integration_owners['0']) metadata.authorizingIntegrationOwners[DiscordApplicationIntegrationType.GuildInstall] = bot.transformers.snowflake( payload.authorizing_integration_owners['0'], - ) + ); if (payload.authorizing_integration_owners['1']) metadata.authorizingIntegrationOwners[DiscordApplicationIntegrationType.UserInstall] = bot.transformers.snowflake( payload.authorizing_integration_owners['1'], - ) + ); } if (props.originalResponseMessageId && payload.original_response_message_id) - metadata.originalResponseMessageId = bot.transformers.snowflake(payload.original_response_message_id) - if (props.type) metadata.type = payload.type - if (props.user && payload.user) metadata.user = bot.transformers.user(bot, payload.user) + metadata.originalResponseMessageId = bot.transformers.snowflake(payload.original_response_message_id); + if (props.type) metadata.type = payload.type; + if (props.user && payload.user) metadata.user = bot.transformers.user(bot, payload.user); // Application command metadata if ('target_user' in payload) { - if (props.targetUser && payload.target_user) metadata.targetUser = bot.transformers.user(bot, payload.target_user) - if (props.targetMessageId && payload.target_message_id) metadata.targetMessageId = bot.transformers.snowflake(payload.target_message_id) + if (props.targetUser && payload.target_user) metadata.targetUser = bot.transformers.user(bot, payload.target_user); + if (props.targetMessageId && payload.target_message_id) metadata.targetMessageId = bot.transformers.snowflake(payload.target_message_id); } // Message component metadata if ('interacted_message_id' in payload) { if (props.interactedMessageId && payload.interacted_message_id) - metadata.interactedMessageId = bot.transformers.snowflake(payload.interacted_message_id) + metadata.interactedMessageId = bot.transformers.snowflake(payload.interacted_message_id); } // Modal submit metadata if ('triggering_interaction_metadata' in payload) { if (props.triggeringInteractionMetadata && payload.triggering_interaction_metadata) - metadata.triggeringInteractionMetadata = bot.transformers.messageInteractionMetadata(bot, payload.triggering_interaction_metadata) + metadata.triggeringInteractionMetadata = bot.transformers.messageInteractionMetadata(bot, payload.triggering_interaction_metadata); } - return bot.transformers.customizers.messageInteractionMetadata(bot, payload, metadata) + return bot.transformers.customizers.messageInteractionMetadata(bot, payload, metadata); } export function transformMessageCall(bot: Bot, payload: DiscordMessageCall): MessageCall { - const call = {} as SetupDesiredProps - const props = bot.transformers.desiredProperties.messageCall + const call = {} as SetupDesiredProps; + const props = bot.transformers.desiredProperties.messageCall; - if (props.participants && payload.participants) call.participants = payload.participants.map((x) => bot.transformers.snowflake(x)) - if (props.endedTimestamp && payload.ended_timestamp) call.endedTimestamp = Date.parse(payload.ended_timestamp) + if (props.participants && payload.participants) call.participants = payload.participants.map((x) => bot.transformers.snowflake(x)); + if (props.endedTimestamp && payload.ended_timestamp) call.endedTimestamp = Date.parse(payload.ended_timestamp); - return bot.transformers.customizers.messageCall(bot, payload, call) + return bot.transformers.customizers.messageCall(bot, payload, call); } diff --git a/packages/bot/src/transformers/onboarding.ts b/packages/bot/src/transformers/onboarding.ts index aea2d3575..49fc3c98a 100644 --- a/packages/bot/src/transformers/onboarding.ts +++ b/packages/bot/src/transformers/onboarding.ts @@ -1,47 +1,48 @@ -import type { DiscordGuildOnboarding, DiscordGuildOnboardingPrompt, DiscordGuildOnboardingPromptOption } from '@discordeno/types' -import type { Bot } from '../bot.js' -import type { DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from '../desiredProperties.js' -import type { GuildOnboarding, GuildOnboardingPrompt, GuildOnboardingPromptOption } from './types.js' +import type { DiscordGuildOnboarding, DiscordGuildOnboardingPrompt, DiscordGuildOnboardingPromptOption } from '@discordeno/types'; +import type { Bot } from '../bot.js'; +import type { DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from '../desiredProperties.js'; +import type { GuildOnboarding, GuildOnboardingPrompt, GuildOnboardingPromptOption } from './types.js'; export function transformGuildOnboarding(bot: Bot, payload: DiscordGuildOnboarding): GuildOnboarding { - const props = bot.transformers.desiredProperties.guildOnboarding - const guildOnboarding = {} as SetupDesiredProps + const props = bot.transformers.desiredProperties.guildOnboarding; + const guildOnboarding = {} as SetupDesiredProps; - if (props.guildId && payload.guild_id) guildOnboarding.guildId = bot.transformers.snowflake(payload.guild_id) + if (props.guildId && payload.guild_id) guildOnboarding.guildId = bot.transformers.snowflake(payload.guild_id); if (props.defaultChannelIds && payload.default_channel_ids) - guildOnboarding.defaultChannelIds = payload.default_channel_ids.map(bot.transformers.snowflake) - if (props.enabled) guildOnboarding.enabled = payload.enabled - if (props.mode) guildOnboarding.mode = payload.mode - if (props.prompts && payload.prompts) guildOnboarding.prompts = payload.prompts.map((prompt) => bot.transformers.guildOnboardingPrompt(bot, prompt)) + guildOnboarding.defaultChannelIds = payload.default_channel_ids.map(bot.transformers.snowflake); + if (props.enabled) guildOnboarding.enabled = payload.enabled; + if (props.mode) guildOnboarding.mode = payload.mode; + if (props.prompts && payload.prompts) + guildOnboarding.prompts = payload.prompts.map((prompt) => bot.transformers.guildOnboardingPrompt(bot, prompt)); - return bot.transformers.customizers.guildOnboarding(bot, payload, guildOnboarding) + return bot.transformers.customizers.guildOnboarding(bot, payload, guildOnboarding); } export function transformGuildOnboardingPrompt(bot: Bot, payload: DiscordGuildOnboardingPrompt): GuildOnboardingPrompt { - const props = bot.transformers.desiredProperties.guildOnboardingPrompt - const prompt = {} as SetupDesiredProps + const props = bot.transformers.desiredProperties.guildOnboardingPrompt; + const prompt = {} as SetupDesiredProps; - if (props.id && payload.id) prompt.id = bot.transformers.snowflake(payload.id) - if (props.inOnboarding && payload.in_onboarding) prompt.inOnboarding = payload.in_onboarding - if (props.required && payload.required) prompt.required = payload.required - if (props.singleSelect && payload.single_select) prompt.singleSelect = payload.single_select - if (props.title && payload.title) prompt.title = payload.title - if (props.type) prompt.type = payload.type - if (props.options && payload.options) prompt.options = payload.options.map((option) => bot.transformers.guildOnboardingPromptOption(bot, option)) + if (props.id && payload.id) prompt.id = bot.transformers.snowflake(payload.id); + if (props.inOnboarding && payload.in_onboarding) prompt.inOnboarding = payload.in_onboarding; + if (props.required && payload.required) prompt.required = payload.required; + if (props.singleSelect && payload.single_select) prompt.singleSelect = payload.single_select; + if (props.title && payload.title) prompt.title = payload.title; + if (props.type) prompt.type = payload.type; + if (props.options && payload.options) prompt.options = payload.options.map((option) => bot.transformers.guildOnboardingPromptOption(bot, option)); - return bot.transformers.customizers.guildOnboardingPrompt(bot, payload, prompt) + return bot.transformers.customizers.guildOnboardingPrompt(bot, payload, prompt); } export function transformGuildOnboardingPromptOption(bot: Bot, payload: DiscordGuildOnboardingPromptOption): GuildOnboardingPromptOption { - const props = bot.transformers.desiredProperties.guildOnboardingPromptOption - const option = {} as SetupDesiredProps + const props = bot.transformers.desiredProperties.guildOnboardingPromptOption; + const option = {} as SetupDesiredProps; - if (props.id && payload.id) option.id = bot.transformers.snowflake(payload.id) - if (props.channelIds && payload.channel_ids) option.channelIds = payload.channel_ids.map(bot.transformers.snowflake) - if (props.roleIds && payload.role_ids) option.roleIds = payload.role_ids.map(bot.transformers.snowflake) - if (props.emoji && payload.emoji) option.emoji = bot.transformers.emoji(bot, payload.emoji) - if (props.title && payload.title) option.title = payload.title - if (props.description && payload.description) option.description = payload.description + if (props.id && payload.id) option.id = bot.transformers.snowflake(payload.id); + if (props.channelIds && payload.channel_ids) option.channelIds = payload.channel_ids.map(bot.transformers.snowflake); + if (props.roleIds && payload.role_ids) option.roleIds = payload.role_ids.map(bot.transformers.snowflake); + if (props.emoji && payload.emoji) option.emoji = bot.transformers.emoji(bot, payload.emoji); + if (props.title && payload.title) option.title = payload.title; + if (props.description && payload.description) option.description = payload.description; - return bot.transformers.customizers.guildOnboardingPromptOption(bot, payload, option) + return bot.transformers.customizers.guildOnboardingPromptOption(bot, payload, option); } diff --git a/packages/bot/src/transformers/poll.ts b/packages/bot/src/transformers/poll.ts index 8993525a9..e48fd1062 100644 --- a/packages/bot/src/transformers/poll.ts +++ b/packages/bot/src/transformers/poll.ts @@ -1,38 +1,38 @@ -import type { DiscordEmoji, DiscordPoll, DiscordPollMedia } from '@discordeno/types' -import type { Bot } from '../bot.js' -import type { DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from '../desiredProperties.js' -import type { Poll, PollMedia, PollResult } from './types.js' +import type { DiscordEmoji, DiscordPoll, DiscordPollMedia } from '@discordeno/types'; +import type { Bot } from '../bot.js'; +import type { DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from '../desiredProperties.js'; +import type { Poll, PollMedia, PollResult } from './types.js'; export function transformPoll(bot: Bot, payload: DiscordPoll): Poll { - const props = bot.transformers.desiredProperties.poll - const poll = {} as SetupDesiredProps + const props = bot.transformers.desiredProperties.poll; + const poll = {} as SetupDesiredProps; - if (props.question && payload.question) poll.question = bot.transformers.pollMedia(bot, payload.question) + if (props.question && payload.question) poll.question = bot.transformers.pollMedia(bot, payload.question); if (props.answers && payload.answers) - poll.answers = payload.answers.map((x) => ({ answerId: x.answer_id, pollMedia: bot.transformers.pollMedia(bot, x.poll_media) })) - if (props.expiry && payload.expiry) poll.expiry = Date.parse(payload.expiry) - if (props.allowMultiselect && payload.allow_multiselect) poll.allowMultiselect = payload.allow_multiselect - if (props.layoutType) poll.layoutType = payload.layout_type + poll.answers = payload.answers.map((x) => ({ answerId: x.answer_id, pollMedia: bot.transformers.pollMedia(bot, x.poll_media) })); + if (props.expiry && payload.expiry) poll.expiry = Date.parse(payload.expiry); + if (props.allowMultiselect && payload.allow_multiselect) poll.allowMultiselect = payload.allow_multiselect; + if (props.layoutType) poll.layoutType = payload.layout_type; if (props.results && payload.results) { - const results = {} as SetupDesiredProps - const pollResultProps = bot.transformers.desiredProperties.pollResult + const results = {} as SetupDesiredProps; + const pollResultProps = bot.transformers.desiredProperties.pollResult; - if (pollResultProps.isFinalized && payload.results.is_finalized) results.isFinalized = payload.results.is_finalized + if (pollResultProps.isFinalized && payload.results.is_finalized) results.isFinalized = payload.results.is_finalized; if (pollResultProps.answerCounts && payload.results.answer_counts) - results.answerCounts = payload.results.answer_counts.map((x) => ({ id: x.id, count: x.count, meVoted: x.me_voted })) + results.answerCounts = payload.results.answer_counts.map((x) => ({ id: x.id, count: x.count, meVoted: x.me_voted })); - poll.results = results + poll.results = results; } - return bot.transformers.customizers.poll(bot, payload, poll) + return bot.transformers.customizers.poll(bot, payload, poll); } export function transformPollMedia(bot: Bot, payload: DiscordPollMedia): PollMedia { - const props = bot.transformers.desiredProperties.pollMedia - const pollMedia = {} as SetupDesiredProps + const props = bot.transformers.desiredProperties.pollMedia; + const pollMedia = {} as SetupDesiredProps; - if (props.text && payload.text) pollMedia.text = payload.text - if (props.emoji && payload.emoji) pollMedia.emoji = bot.transformers.emoji(bot, payload.emoji as DiscordEmoji) + if (props.text && payload.text) pollMedia.text = payload.text; + if (props.emoji && payload.emoji) pollMedia.emoji = bot.transformers.emoji(bot, payload.emoji as DiscordEmoji); - return bot.transformers.customizers.pollMedia(bot, payload, pollMedia) + return bot.transformers.customizers.pollMedia(bot, payload, pollMedia); } diff --git a/packages/bot/src/transformers/presence.ts b/packages/bot/src/transformers/presence.ts index 07a2c8269..e24cf284f 100644 --- a/packages/bot/src/transformers/presence.ts +++ b/packages/bot/src/transformers/presence.ts @@ -1,18 +1,18 @@ -import { type DiscordPresenceUpdate, PresenceStatus } from '@discordeno/types' -import type { Bot } from '../bot.js' -import type { DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from '../desiredProperties.js' -import type { PresenceUpdate, User } from './types.js' +import { type DiscordPresenceUpdate, PresenceStatus } from '@discordeno/types'; +import type { Bot } from '../bot.js'; +import type { DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from '../desiredProperties.js'; +import type { PresenceUpdate, User } from './types.js'; export function transformPresence(bot: Bot, payload: DiscordPresenceUpdate): PresenceUpdate { - const presence = {} as SetupDesiredProps + const presence = {} as SetupDesiredProps; - if (payload.user) presence.user = bot.transformers.user(bot, payload.user) as User - if (payload.guild_id) presence.guildId = bot.transformers.snowflake(payload.guild_id) - if (payload.status) presence.status = PresenceStatus[payload.status] - if (payload.activities) presence.activities = payload.activities.map((activity) => bot.transformers.activity(bot, activity)) - if (payload.client_status.desktop) presence.desktop = payload.client_status.desktop - if (payload.client_status.mobile) presence.mobile = payload.client_status.mobile - if (payload.client_status.web) presence.web = payload.client_status.web + if (payload.user) presence.user = bot.transformers.user(bot, payload.user) as User; + if (payload.guild_id) presence.guildId = bot.transformers.snowflake(payload.guild_id); + if (payload.status) presence.status = PresenceStatus[payload.status]; + if (payload.activities) presence.activities = payload.activities.map((activity) => bot.transformers.activity(bot, activity)); + if (payload.client_status.desktop) presence.desktop = payload.client_status.desktop; + if (payload.client_status.mobile) presence.mobile = payload.client_status.mobile; + if (payload.client_status.web) presence.web = payload.client_status.web; - return bot.transformers.customizers.presence(bot, payload, presence) + return bot.transformers.customizers.presence(bot, payload, presence); } diff --git a/packages/bot/src/transformers/reverse/activity.ts b/packages/bot/src/transformers/reverse/activity.ts index 38439c0eb..1903053ee 100644 --- a/packages/bot/src/transformers/reverse/activity.ts +++ b/packages/bot/src/transformers/reverse/activity.ts @@ -1,6 +1,6 @@ -import type { DiscordActivity } from '@discordeno/types' -import type { Bot } from '../../bot.js' -import type { Activity } from '../types.js' +import type { DiscordActivity } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; +import type { Activity } from '../types.js'; export function transformActivityToDiscordActivity(_bot: Bot, payload: Activity): DiscordActivity { return { @@ -40,5 +40,5 @@ export function transformActivityToDiscordActivity(_bot: Bot, payload: Activity) instance: payload.instance, flags: payload.flags, buttons: payload.buttons, - } + }; } diff --git a/packages/bot/src/transformers/reverse/allowedMentions.ts b/packages/bot/src/transformers/reverse/allowedMentions.ts index c0409c9ff..ab414cef4 100644 --- a/packages/bot/src/transformers/reverse/allowedMentions.ts +++ b/packages/bot/src/transformers/reverse/allowedMentions.ts @@ -1,5 +1,5 @@ -import type { AllowedMentions, DiscordAllowedMentions } from '@discordeno/types' -import type { Bot } from '../../bot.js' +import type { AllowedMentions, DiscordAllowedMentions } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; export function transformAllowedMentionsToDiscordAllowedMentions(_bot: Bot, mentions: AllowedMentions): DiscordAllowedMentions { return { @@ -7,5 +7,5 @@ export function transformAllowedMentionsToDiscordAllowedMentions(_bot: Bot, ment replied_user: mentions.repliedUser, users: mentions.users?.map((id) => id.toString()), roles: mentions.roles?.map((id) => id.toString()), - } + }; } diff --git a/packages/bot/src/transformers/reverse/application.ts b/packages/bot/src/transformers/reverse/application.ts index 3f1f19436..eaeaa8f18 100644 --- a/packages/bot/src/transformers/reverse/application.ts +++ b/packages/bot/src/transformers/reverse/application.ts @@ -1,7 +1,7 @@ -import type { DiscordApplication } from '@discordeno/types' -import { iconBigintToHash } from '@discordeno/utils' -import type { Bot } from '../../bot.js' -import type { Application } from '../types.js' +import type { DiscordApplication } from '@discordeno/types'; +import { iconBigintToHash } from '@discordeno/utils'; +import type { Bot } from '../../bot.js'; +import type { Application } from '../types.js'; export function transformApplicationToDiscordApplication(bot: Bot, payload: Application): DiscordApplication { return { @@ -27,5 +27,5 @@ export function transformApplicationToDiscordApplication(bot: Bot, payload: Appl event_webhooks_url: payload.eventWebhooksUrl, event_webhooks_status: payload.eventWebhooksStatus, event_webhooks_types: payload.eventWebhooksTypes, - } + }; } diff --git a/packages/bot/src/transformers/reverse/applicationCommand.ts b/packages/bot/src/transformers/reverse/applicationCommand.ts index 4a0c4e968..14c64322b 100644 --- a/packages/bot/src/transformers/reverse/applicationCommand.ts +++ b/packages/bot/src/transformers/reverse/applicationCommand.ts @@ -1,6 +1,6 @@ -import type { DiscordApplicationCommand } from '@discordeno/types' -import type { Bot } from '../../bot.js' -import type { ApplicationCommand } from '../types.js' +import type { DiscordApplicationCommand } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; +import type { ApplicationCommand } from '../types.js'; export function transformApplicationCommandToDiscordApplicationCommand(bot: Bot, payload: ApplicationCommand): DiscordApplicationCommand { return { @@ -16,5 +16,5 @@ export function transformApplicationCommandToDiscordApplicationCommand(bot: Bot, default_member_permissions: payload.defaultMemberPermissions ? bot.transformers.reverse.snowflake(payload.defaultMemberPermissions) : null, dm_permission: payload.dmPermission, version: payload.version, - } + }; } diff --git a/packages/bot/src/transformers/reverse/applicationCommandOption.ts b/packages/bot/src/transformers/reverse/applicationCommandOption.ts index 3ec22db38..9dc828b81 100644 --- a/packages/bot/src/transformers/reverse/applicationCommandOption.ts +++ b/packages/bot/src/transformers/reverse/applicationCommandOption.ts @@ -1,6 +1,6 @@ -import type { DiscordApplicationCommandOption } from '@discordeno/types' -import type { Bot } from '../../bot.js' -import type { ApplicationCommandOption } from '../types.js' +import type { DiscordApplicationCommandOption } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; +import type { ApplicationCommandOption } from '../types.js'; export function transformApplicationCommandOptionToDiscordApplicationCommandOption( bot: Bot, @@ -21,5 +21,5 @@ export function transformApplicationCommandOptionToDiscordApplicationCommandOpti min_length: payload.minLength, max_length: payload.maxLength, autocomplete: payload.autocomplete, - } + }; } diff --git a/packages/bot/src/transformers/reverse/applicationCommandOptionChoice.ts b/packages/bot/src/transformers/reverse/applicationCommandOptionChoice.ts index 0f3d945a7..f1da75396 100644 --- a/packages/bot/src/transformers/reverse/applicationCommandOptionChoice.ts +++ b/packages/bot/src/transformers/reverse/applicationCommandOptionChoice.ts @@ -1,6 +1,6 @@ -import type { Camelize, DiscordApplicationCommandOptionChoice } from '@discordeno/types' -import type { Bot } from '../../bot.js' -import type { ApplicationCommandOptionChoice } from '../types.js' +import type { Camelize, DiscordApplicationCommandOptionChoice } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; +import type { ApplicationCommandOptionChoice } from '../types.js'; export function transformApplicationCommandOptionChoiceToDiscordApplicationCommandOptionChoice( _bot: Bot, @@ -10,5 +10,5 @@ export function transformApplicationCommandOptionChoiceToDiscordApplicationComma name: payload.name, name_localizations: payload.nameLocalizations, value: payload.value, - } + }; } diff --git a/packages/bot/src/transformers/reverse/applicationCommandPermission.ts b/packages/bot/src/transformers/reverse/applicationCommandPermission.ts index f8d1c8235..fffa0875e 100644 --- a/packages/bot/src/transformers/reverse/applicationCommandPermission.ts +++ b/packages/bot/src/transformers/reverse/applicationCommandPermission.ts @@ -1,6 +1,6 @@ -import type { DiscordGuildApplicationCommandPermissions } from '@discordeno/types' -import type { Bot } from '../../bot.js' -import type { GuildApplicationCommandPermissions } from '../types.js' +import type { DiscordGuildApplicationCommandPermissions } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; +import type { GuildApplicationCommandPermissions } from '../types.js'; export function transformApplicationCommandPermissionToDiscordApplicationCommandPermission( bot: Bot, @@ -15,5 +15,5 @@ export function transformApplicationCommandPermissionToDiscordApplicationCommand type: perm.type, permission: perm.permission, })), - } + }; } diff --git a/packages/bot/src/transformers/reverse/attachment.ts b/packages/bot/src/transformers/reverse/attachment.ts index 9a7005aa1..cd20c26ee 100644 --- a/packages/bot/src/transformers/reverse/attachment.ts +++ b/packages/bot/src/transformers/reverse/attachment.ts @@ -1,9 +1,9 @@ -import type { DiscordAttachment } from '@discordeno/types' -import type { Bot } from '../../bot.js' -import type { Attachment } from '../types.js' +import type { DiscordAttachment } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; +import type { Attachment } from '../types.js'; export function transformAttachmentToDiscordAttachment(bot: Bot, payload: typeof bot.transformers.$inferredTypes.attachment): DiscordAttachment { - const _payload = payload as Partial + const _payload = payload as Partial; return { id: _payload.id ? bot.transformers.reverse.snowflake(_payload.id) : undefined!, @@ -19,5 +19,5 @@ export function transformAttachmentToDiscordAttachment(bot: Bot, payload: typeof duration_secs: _payload.duration_secs, waveform: _payload.waveform, flags: _payload.flags, - } + }; } diff --git a/packages/bot/src/transformers/reverse/auditLogEntry.ts b/packages/bot/src/transformers/reverse/auditLogEntry.ts index 0d316fd53..fba93deae 100644 --- a/packages/bot/src/transformers/reverse/auditLogEntry.ts +++ b/packages/bot/src/transformers/reverse/auditLogEntry.ts @@ -1,7 +1,7 @@ -import type { DiscordAuditLogEntry } from '@discordeno/types' -import { snakelize } from '@discordeno/utils' -import type { Bot } from '../../bot.js' -import type { AuditLogEntry } from '../types.js' +import type { DiscordAuditLogEntry } from '@discordeno/types'; +import { snakelize } from '@discordeno/utils'; +import type { Bot } from '../../bot.js'; +import type { AuditLogEntry } from '../types.js'; export function transformAuditLogEntryToDiscordAuditLogEntry(bot: Bot, payload: AuditLogEntry): DiscordAuditLogEntry { return { @@ -29,5 +29,5 @@ export function transformAuditLogEntryToDiscordAuditLogEntry(bot: Bot, payload: } : undefined, reason: payload.reason, - } + }; } diff --git a/packages/bot/src/transformers/reverse/component.ts b/packages/bot/src/transformers/reverse/component.ts index 995b464ec..a6e88b9c3 100644 --- a/packages/bot/src/transformers/reverse/component.ts +++ b/packages/bot/src/transformers/reverse/component.ts @@ -20,9 +20,9 @@ import { type DiscordUnfurledMediaItem, MessageComponentTypes, type TextStyles, -} from '@discordeno/types' -import type { Bot } from '../../bot.js' -import type { Component, MediaGalleryItem, UnfurledMediaItem } from '../types.js' +} from '@discordeno/types'; +import type { Bot } from '../../bot.js'; +import type { Component, MediaGalleryItem, UnfurledMediaItem } from '../types.js'; export function transformComponentToDiscordComponent( bot: Bot, @@ -31,35 +31,35 @@ export function transformComponentToDiscordComponent( // This switch should include all cases switch (payload.type) { case MessageComponentTypes.ActionRow: - return transformActionRow(bot, payload) + return transformActionRow(bot, payload); case MessageComponentTypes.Button: - return transformButtonComponent(bot, payload) + return transformButtonComponent(bot, payload); case MessageComponentTypes.Container: - return transformContainerComponent(bot, payload) + return transformContainerComponent(bot, payload); case MessageComponentTypes.TextInput: - return transformInputTextComponent(bot, payload) + return transformInputTextComponent(bot, payload); case MessageComponentTypes.StringSelect: case MessageComponentTypes.ChannelSelect: case MessageComponentTypes.RoleSelect: case MessageComponentTypes.UserSelect: case MessageComponentTypes.MentionableSelect: - return transformSelectMenuComponent(bot, payload) + return transformSelectMenuComponent(bot, payload); case MessageComponentTypes.Section: - return transformSectionComponent(bot, payload) + return transformSectionComponent(bot, payload); case MessageComponentTypes.File: - return transformFileComponent(bot, payload) + return transformFileComponent(bot, payload); case MessageComponentTypes.MediaGallery: - return transformMediaGalleryComponent(bot, payload) + return transformMediaGalleryComponent(bot, payload); case MessageComponentTypes.Thumbnail: - return transformThumbnailComponent(bot, payload) + return transformThumbnailComponent(bot, payload); case MessageComponentTypes.Label: - return transformLabelComponent(bot, payload) + return transformLabelComponent(bot, payload); case MessageComponentTypes.FileUpload: - return transformFileUploadComponent(bot, payload) + return transformFileUploadComponent(bot, payload); case MessageComponentTypes.Separator: case MessageComponentTypes.TextDisplay: // As of now they are compatible - return payload as DiscordMessageComponent + return payload as DiscordMessageComponent; } } @@ -71,7 +71,7 @@ export function transformUnfurledMediaItemToDiscordUnfurledMediaItem(bot: Bot, p width: payload.width, content_type: payload.contentType, attachment_id: payload.attachmentId ? bot.transformers.reverse.snowflake(payload.attachmentId) : undefined, - } + }; } export function transformMediaGalleryItemToDiscordMediaGalleryItem(bot: Bot, payload: MediaGalleryItem): DiscordMediaGalleryItem { @@ -79,7 +79,7 @@ export function transformMediaGalleryItemToDiscordMediaGalleryItem(bot: Bot, pay media: bot.transformers.reverse.unfurledMediaItem(bot, payload.media), description: payload.description, spoiler: payload.spoiler, - } + }; } function transformActionRow(bot: Bot, payload: Component): DiscordActionRow { @@ -88,7 +88,7 @@ function transformActionRow(bot: Bot, payload: Component): DiscordActionRow { id: payload.id, // The actionRow.components type is kinda annoying, so we need a cast for this components: (payload.components?.map((component) => bot.transformers.reverse.component(bot, component)) ?? []) as DiscordActionRow['components'], - } + }; } function transformContainerComponent(bot: Bot, payload: Component): DiscordContainerComponent { @@ -99,7 +99,7 @@ function transformContainerComponent(bot: Bot, payload: Component): DiscordConta spoiler: payload.spoiler, components: (payload.components?.map((component) => bot.transformers.reverse.component(bot, component)) ?? []) as DiscordContainerComponent['components'], - } + }; } function transformButtonComponent(bot: Bot, payload: Component): DiscordButtonComponent { @@ -120,7 +120,7 @@ function transformButtonComponent(bot: Bot, payload: Component): DiscordButtonCo label: payload.label, url: payload.url, sku_id: payload.skuId ? bot.transformers.reverse.snowflake(payload.skuId) : undefined, - } + }; } function transformInputTextComponent(_bot: Bot, payload: Component): DiscordTextInputComponent | DiscordTextInputInteractionResponse { @@ -136,7 +136,7 @@ function transformInputTextComponent(_bot: Bot, payload: Component): DiscordText min_length: payload.minLength, placeholder: payload.placeholder, required: payload.required, - } + }; } function transformSelectMenuComponent(bot: Bot, payload: Component): DiscordSelectMenuComponent | DiscordStringSelectInteractionResponseFromModal { @@ -146,7 +146,7 @@ function transformSelectMenuComponent(bot: Bot, payload: Component): DiscordSele values: payload.values, custom_id: payload.customId!, id: payload.id!, - } + }; } return { @@ -176,7 +176,7 @@ function transformSelectMenuComponent(bot: Bot, payload: Component): DiscordSele })), placeholder: payload.placeholder, required: payload.required, - } + }; } function transformSectionComponent(bot: Bot, payload: Component): DiscordSectionComponent { @@ -185,7 +185,7 @@ function transformSectionComponent(bot: Bot, payload: Component): DiscordSection id: payload.id, components: payload.components?.map((component) => bot.transformers.reverse.component(bot, component)) as DiscordTextDisplayComponent[], accessory: (payload.accessory ? bot.transformers.reverse.component(bot, payload.accessory) : undefined) as DiscordSectionComponent['accessory'], - } + }; } function transformFileComponent(bot: Bot, payload: Component): DiscordFileComponent { @@ -196,7 +196,7 @@ function transformFileComponent(bot: Bot, payload: Component): DiscordFileCompon spoiler: payload.spoiler, name: payload.name!, size: payload.size!, - } + }; } function transformMediaGalleryComponent(bot: Bot, payload: Component): DiscordMediaGalleryComponent { @@ -204,7 +204,7 @@ function transformMediaGalleryComponent(bot: Bot, payload: Component): DiscordMe type: MessageComponentTypes.MediaGallery, id: payload.id, items: payload.items?.map((item) => bot.transformers.reverse.mediaGalleryItem(bot, item)) ?? [], - } + }; } function transformThumbnailComponent(bot: Bot, payload: Component): DiscordThumbnailComponent { @@ -214,7 +214,7 @@ function transformThumbnailComponent(bot: Bot, payload: Component): DiscordThumb media: bot.transformers.reverse.unfurledMediaItem(bot, payload.media!), description: payload.description, spoiler: payload.spoiler, - } + }; } function transformLabelComponent(bot: Bot, payload: Component): DiscordLabelComponent { @@ -224,7 +224,7 @@ function transformLabelComponent(bot: Bot, payload: Component): DiscordLabelComp label: payload.label!, description: payload.description, component: bot.transformers.reverse.component(bot, payload.component!) as DiscordLabelComponent['component'], - } + }; } function transformFileUploadComponent(bot: Bot, payload: Component): DiscordFileUploadComponent { @@ -235,5 +235,5 @@ function transformFileUploadComponent(bot: Bot, payload: Component): DiscordFile max_values: payload.maxValues, min_values: payload.minValues, required: payload.required, - } + }; } diff --git a/packages/bot/src/transformers/reverse/embed.ts b/packages/bot/src/transformers/reverse/embed.ts index c497678a4..c58598517 100644 --- a/packages/bot/src/transformers/reverse/embed.ts +++ b/packages/bot/src/transformers/reverse/embed.ts @@ -1,6 +1,6 @@ -import type { DiscordEmbed } from '@discordeno/types' -import type { Bot } from '../../bot.js' -import type { Embed } from '../types.js' +import type { DiscordEmbed } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; +import type { Embed } from '../types.js'; export function transformEmbedToDiscordEmbed(_bot: Bot, payload: Embed): DiscordEmbed { return { @@ -51,5 +51,5 @@ export function transformEmbedToDiscordEmbed(_bot: Bot, payload: Embed): Discord } : undefined, fields: payload.fields, - } + }; } diff --git a/packages/bot/src/transformers/reverse/emoji.ts b/packages/bot/src/transformers/reverse/emoji.ts index d487ff208..cd4349ac2 100644 --- a/packages/bot/src/transformers/reverse/emoji.ts +++ b/packages/bot/src/transformers/reverse/emoji.ts @@ -1,6 +1,6 @@ -import type { DiscordEmoji } from '@discordeno/types' -import type { Bot } from '../../bot.js' -import type { Emoji } from '../types.js' +import type { DiscordEmoji } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; +import type { Emoji } from '../types.js'; export function transformEmojiToDiscordEmoji(bot: Bot, payload: Emoji): DiscordEmoji { return { @@ -12,5 +12,5 @@ export function transformEmojiToDiscordEmoji(bot: Bot, payload: Emoji): DiscordE managed: payload.toggles.managed, animated: payload.toggles.animated, available: payload.toggles.available, - } + }; } diff --git a/packages/bot/src/transformers/reverse/gatewayBot.ts b/packages/bot/src/transformers/reverse/gatewayBot.ts index e444c1be3..d6fba7390 100644 --- a/packages/bot/src/transformers/reverse/gatewayBot.ts +++ b/packages/bot/src/transformers/reverse/gatewayBot.ts @@ -1,5 +1,5 @@ -import type { DiscordGetGatewayBot } from '@discordeno/types' -import type { GetGatewayBot } from '../types.js' +import type { DiscordGetGatewayBot } from '@discordeno/types'; +import type { GetGatewayBot } from '../types.js'; export function transformGatewayBotToDiscordGatewayBot(payload: GetGatewayBot): DiscordGetGatewayBot { return { @@ -11,5 +11,5 @@ export function transformGatewayBotToDiscordGatewayBot(payload: GetGatewayBot): reset_after: payload.sessionStartLimit.resetAfter, max_concurrency: payload.sessionStartLimit.maxConcurrency, }, - } + }; } diff --git a/packages/bot/src/transformers/reverse/index.ts b/packages/bot/src/transformers/reverse/index.ts index ec9f5f926..8c96a1c1f 100644 --- a/packages/bot/src/transformers/reverse/index.ts +++ b/packages/bot/src/transformers/reverse/index.ts @@ -1,17 +1,17 @@ -export * from './activity.js' -export * from './allowedMentions.js' -export * from './application.js' -export * from './applicationCommand.js' -export * from './applicationCommandOption.js' -export * from './applicationCommandOptionChoice.js' -export * from './applicationCommandPermission.js' -export * from './attachment.js' -export * from './auditLogEntry.js' -export * from './component.js' -export * from './embed.js' -export * from './emoji.js' -export * from './gatewayBot.js' -export * from './member.js' -export * from './presence.js' -export * from './team.js' -export * from './widgetSettings.js' +export * from './activity.js'; +export * from './allowedMentions.js'; +export * from './application.js'; +export * from './applicationCommand.js'; +export * from './applicationCommandOption.js'; +export * from './applicationCommandOptionChoice.js'; +export * from './applicationCommandPermission.js'; +export * from './attachment.js'; +export * from './auditLogEntry.js'; +export * from './component.js'; +export * from './embed.js'; +export * from './emoji.js'; +export * from './gatewayBot.js'; +export * from './member.js'; +export * from './presence.js'; +export * from './team.js'; +export * from './widgetSettings.js'; diff --git a/packages/bot/src/transformers/reverse/member.ts b/packages/bot/src/transformers/reverse/member.ts index a91c20faa..4ef1cdf3e 100644 --- a/packages/bot/src/transformers/reverse/member.ts +++ b/packages/bot/src/transformers/reverse/member.ts @@ -1,10 +1,10 @@ -import type { DiscordMember, DiscordUser } from '@discordeno/types' -import { iconBigintToHash } from '@discordeno/utils' -import type { Bot } from '../../bot.js' -import type { Member, User } from '../types.js' +import type { DiscordMember, DiscordUser } from '@discordeno/types'; +import { iconBigintToHash } from '@discordeno/utils'; +import type { Bot } from '../../bot.js'; +import type { Member, User } from '../types.js'; export function transformUserToDiscordUser(bot: Bot, payload: typeof bot.transformers.$inferredTypes.user): DiscordUser { - const _payload = payload as Partial + const _payload = payload as Partial; return { id: _payload.id!.toString(), @@ -21,11 +21,11 @@ export function transformUserToDiscordUser(bot: Bot, payload: typeof bot.transfo system: _payload.toggles?.system, mfa_enabled: _payload.toggles?.mfaEnabled, verified: _payload.toggles?.verified, - } + }; } export function transformMemberToDiscordMember(bot: Bot, payload: typeof bot.transformers.$inferredTypes.member): DiscordMember { - const _payload = payload as Partial + const _payload = payload as Partial; return { nick: _payload.nick ?? undefined, @@ -46,5 +46,5 @@ export function transformMemberToDiscordMember(bot: Bot, payload: typeof bot.tra } : undefined, user: _payload.user ? bot.transformers.reverse.user(bot, _payload.user) : undefined, - } + }; } diff --git a/packages/bot/src/transformers/reverse/presence.ts b/packages/bot/src/transformers/reverse/presence.ts index ce97cc3ad..b92b79ea2 100644 --- a/packages/bot/src/transformers/reverse/presence.ts +++ b/packages/bot/src/transformers/reverse/presence.ts @@ -1,13 +1,13 @@ -import { type DiscordPresenceUpdate, PresenceStatus } from '@discordeno/types' -import type { Bot } from '../../bot.js' -import type { PresenceUpdate } from '../types.js' +import { type DiscordPresenceUpdate, PresenceStatus } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; +import type { PresenceUpdate } from '../types.js'; export const reverseStatusTypes = Object.freeze({ 0: 'online', 1: 'dnd', 2: 'idle', 4: 'offline', -} as const) +} as const); export function transformPresenceToDiscordPresence(bot: Bot, payload: PresenceUpdate): DiscordPresenceUpdate { return { @@ -21,5 +21,5 @@ export function transformPresenceToDiscordPresence(bot: Bot, payload: PresenceUp mobile: payload.mobile, web: payload.web, }, - } + }; } diff --git a/packages/bot/src/transformers/reverse/team.ts b/packages/bot/src/transformers/reverse/team.ts index bf0a75c7d..2104c8d23 100644 --- a/packages/bot/src/transformers/reverse/team.ts +++ b/packages/bot/src/transformers/reverse/team.ts @@ -1,10 +1,10 @@ -import type { DiscordTeam } from '@discordeno/types' -import { iconBigintToHash } from '@discordeno/utils' -import type { Bot } from '../../bot.js' -import type { Team } from '../types.js' +import type { DiscordTeam } from '@discordeno/types'; +import { iconBigintToHash } from '@discordeno/utils'; +import type { Bot } from '../../bot.js'; +import type { Team } from '../types.js'; export function transformTeamToDiscordTeam(bot: Bot, payload: Team): DiscordTeam { - const id = payload.id.toString() + const id = payload.id.toString(); return { name: payload.name, @@ -18,5 +18,5 @@ export function transformTeamToDiscordTeam(bot: Bot, payload: Team): DiscordTeam user: bot.transformers.reverse.user(bot, member.user), role: member.role, })), - } + }; } diff --git a/packages/bot/src/transformers/reverse/widgetSettings.ts b/packages/bot/src/transformers/reverse/widgetSettings.ts index cf3121b5b..fc00d0b35 100644 --- a/packages/bot/src/transformers/reverse/widgetSettings.ts +++ b/packages/bot/src/transformers/reverse/widgetSettings.ts @@ -1,10 +1,10 @@ -import type { DiscordGuildWidgetSettings } from '@discordeno/types' -import type { Bot } from '../../bot.js' -import type { GuildWidgetSettings } from '../types.js' +import type { DiscordGuildWidgetSettings } from '@discordeno/types'; +import type { Bot } from '../../bot.js'; +import type { GuildWidgetSettings } from '../types.js'; export function transformWidgetSettingsToDiscordWidgetSettings(_bot: Bot, payload: GuildWidgetSettings): DiscordGuildWidgetSettings { return { enabled: payload.enabled, channel_id: payload.channelId ?? null, - } + }; } diff --git a/packages/bot/src/transformers/role.ts b/packages/bot/src/transformers/role.ts index 18b4d04b3..15af61ff8 100644 --- a/packages/bot/src/transformers/role.ts +++ b/packages/bot/src/transformers/role.ts @@ -1,10 +1,10 @@ -import type { BigString, DiscordRole, DiscordRoleColors } from '@discordeno/types' -import { iconHashToBigInt } from '@discordeno/utils' -import type { Bot } from '../bot.js' -import type { DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from '../desiredProperties.js' -import { Permissions } from './toggles/Permissions.js' -import { RoleToggles } from './toggles/role.js' -import type { Role, RoleColors } from './types.js' +import type { BigString, DiscordRole, DiscordRoleColors } from '@discordeno/types'; +import { iconHashToBigInt } from '@discordeno/utils'; +import type { Bot } from '../bot.js'; +import type { DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from '../desiredProperties.js'; +import { Permissions } from './toggles/Permissions.js'; +import { RoleToggles } from './toggles/role.js'; +import type { Role, RoleColors } from './types.js'; export const baseRole: Role = { // This allows typescript to still check for type errors on functions below @@ -18,71 +18,71 @@ export const baseRole: Role = { availableForPurchase: this.toggles?.availableForPurchase, guildConnections: this.toggles?.guildConnections, premiumSubscriber: this.toggles?.premiumSubscriber, - } + }; }, /** If this role is showed separately in the user listing */ get hoist() { - return !!this.toggles?.has('hoist') + return !!this.toggles?.has('hoist'); }, /** Whether this role is managed by an integration */ get managed() { - return !!this.toggles?.has('managed') + return !!this.toggles?.has('managed'); }, /** Whether this role is mentionable */ get mentionable() { - return !!this.toggles?.has('mentionable') + return !!this.toggles?.has('mentionable'); }, /** Whether this is the guilds premium subscriber role */ get premiumSubscriber() { - return !!this.toggles?.has('premiumSubscriber') + return !!this.toggles?.has('premiumSubscriber'); }, /** Whether this role is available for purchase. */ get availableForPurchase() { - return !!this.toggles?.has('availableForPurchase') + return !!this.toggles?.has('availableForPurchase'); }, /** Whether this is a guild's linked role. */ get guildConnections() { - return !!this.toggles?.has('guildConnections') + return !!this.toggles?.has('guildConnections'); }, -} +}; export function transformRole(bot: Bot, payload: DiscordRole, extra?: { guildId?: BigString }): Role { - const role: SetupDesiredProps = Object.create(baseRole) - const props = bot.transformers.desiredProperties.role - if (props.id && payload.id) role.id = bot.transformers.snowflake(payload.id) + const role: SetupDesiredProps = Object.create(baseRole); + const props = bot.transformers.desiredProperties.role; + if (props.id && payload.id) role.id = bot.transformers.snowflake(payload.id); // Role name can be an empty string - if (props.name && payload.name !== undefined) role.name = payload.name - if (props.position) role.position = payload.position - if (props.guildId && extra?.guildId) role.guildId = bot.transformers.snowflake(extra?.guildId) - if (props.color && payload.color !== undefined) role.color = payload.color - if (props.colors && payload.colors) role.colors = bot.transformers.roleColors(bot, payload.colors) - if (props.permissions && payload.permissions) role.permissions = new Permissions(payload.permissions) - if (props.icon && payload.icon) role.icon = iconHashToBigInt(payload.icon) - if (props.unicodeEmoji && payload.unicode_emoji) role.unicodeEmoji = payload.unicode_emoji - if (props.flags) role.flags = payload.flags + if (props.name && payload.name !== undefined) role.name = payload.name; + if (props.position) role.position = payload.position; + if (props.guildId && extra?.guildId) role.guildId = bot.transformers.snowflake(extra?.guildId); + if (props.color && payload.color !== undefined) role.color = payload.color; + if (props.colors && payload.colors) role.colors = bot.transformers.roleColors(bot, payload.colors); + if (props.permissions && payload.permissions) role.permissions = new Permissions(payload.permissions); + if (props.icon && payload.icon) role.icon = iconHashToBigInt(payload.icon); + if (props.unicodeEmoji && payload.unicode_emoji) role.unicodeEmoji = payload.unicode_emoji; + if (props.flags) role.flags = payload.flags; if (props.tags && payload.tags) { - role.internalTags = {} - if (payload.tags.bot_id) role.internalTags.botId = bot.transformers.snowflake(payload.tags.bot_id) - if (payload.tags.integration_id) role.internalTags.integrationId = bot.transformers.snowflake(payload.tags.integration_id) + role.internalTags = {}; + if (payload.tags.bot_id) role.internalTags.botId = bot.transformers.snowflake(payload.tags.bot_id); + if (payload.tags.integration_id) role.internalTags.integrationId = bot.transformers.snowflake(payload.tags.integration_id); if (payload.tags.subscription_listing_id) - role.internalTags.subscriptionListingId = bot.transformers.snowflake(payload.tags.subscription_listing_id) + role.internalTags.subscriptionListingId = bot.transformers.snowflake(payload.tags.subscription_listing_id); } - if (props.toggles) role.toggles = new RoleToggles(payload) + if (props.toggles) role.toggles = new RoleToggles(payload); return bot.transformers.customizers.role(bot, payload, role, { guildId: extra?.guildId ? bot.transformers.snowflake(extra.guildId) : undefined, - }) + }); } export function transformRoleColors(bot: Bot, payload: DiscordRoleColors): RoleColors { - const roleColors = {} as SetupDesiredProps - const props = bot.transformers.desiredProperties.roleColors + const roleColors = {} as SetupDesiredProps; + const props = bot.transformers.desiredProperties.roleColors; - if (props.primaryColor && payload.primary_color !== undefined) roleColors.primaryColor = payload.primary_color + if (props.primaryColor && payload.primary_color !== undefined) roleColors.primaryColor = payload.primary_color; if (props.secondaryColor && payload.secondary_color !== undefined && payload.secondary_color !== null) - roleColors.secondaryColor = payload.secondary_color + roleColors.secondaryColor = payload.secondary_color; if (props.tertiaryColor && payload.tertiary_color !== undefined && payload.tertiary_color !== null) - roleColors.tertiaryColor = payload.tertiary_color + roleColors.tertiaryColor = payload.tertiary_color; - return bot.transformers.customizers.roleColors(bot, payload, roleColors) + return bot.transformers.customizers.roleColors(bot, payload, roleColors); } diff --git a/packages/bot/src/transformers/scheduledEvent.ts b/packages/bot/src/transformers/scheduledEvent.ts index 7d37101bb..9f9ecc808 100644 --- a/packages/bot/src/transformers/scheduledEvent.ts +++ b/packages/bot/src/transformers/scheduledEvent.ts @@ -1,49 +1,49 @@ -import type { DiscordScheduledEvent, DiscordScheduledEventRecurrenceRule } from '@discordeno/types' -import { iconHashToBigInt } from '@discordeno/utils' -import type { Bot } from '../bot.js' -import type { DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from '../desiredProperties.js' -import type { ScheduledEvent, ScheduledEventRecurrenceRule } from './types.js' +import type { DiscordScheduledEvent, DiscordScheduledEventRecurrenceRule } from '@discordeno/types'; +import { iconHashToBigInt } from '@discordeno/utils'; +import type { Bot } from '../bot.js'; +import type { DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from '../desiredProperties.js'; +import type { ScheduledEvent, ScheduledEventRecurrenceRule } from './types.js'; export function transformScheduledEvent(bot: Bot, payload: DiscordScheduledEvent): ScheduledEvent { - const props = bot.transformers.desiredProperties.scheduledEvent - const scheduledEvent = {} as SetupDesiredProps + const props = bot.transformers.desiredProperties.scheduledEvent; + const scheduledEvent = {} as SetupDesiredProps; - if (props.id && payload.id) scheduledEvent.id = bot.transformers.snowflake(payload.id) - if (props.guildId && payload.guild_id) scheduledEvent.guildId = bot.transformers.snowflake(payload.guild_id) - if (props.channelId && payload.channel_id) scheduledEvent.channelId = bot.transformers.snowflake(payload.channel_id) - if (props.creatorId && payload.creator_id) scheduledEvent.creatorId = bot.transformers.snowflake(payload.creator_id) - if (props.scheduledStartTime && payload.scheduled_start_time) scheduledEvent.scheduledStartTime = Date.parse(payload.scheduled_start_time) - if (props.scheduledEndTime && payload.scheduled_end_time) scheduledEvent.scheduledEndTime = Date.parse(payload.scheduled_end_time) - if (props.entityId && payload.entity_id) scheduledEvent.entityId = bot.transformers.snowflake(payload.entity_id) - if (props.creator && payload.creator) scheduledEvent.creator = bot.transformers.user(bot, payload.creator) - if (props.name && payload.name) scheduledEvent.name = payload.name - if (props.description && payload.description) scheduledEvent.description = payload.description - if (props.privacyLevel && payload.privacy_level) scheduledEvent.privacyLevel = payload.privacy_level - if (props.status && payload.status) scheduledEvent.status = payload.status - if (props.entityType && payload.entity_type) scheduledEvent.entityType = payload.entity_type - if (props.userCount) scheduledEvent.userCount = payload.user_count ?? 0 - if (props.location && payload.entity_metadata?.location) scheduledEvent.location = payload.entity_metadata.location - if (props.image && payload.image) scheduledEvent.image = iconHashToBigInt(payload.image) + if (props.id && payload.id) scheduledEvent.id = bot.transformers.snowflake(payload.id); + if (props.guildId && payload.guild_id) scheduledEvent.guildId = bot.transformers.snowflake(payload.guild_id); + if (props.channelId && payload.channel_id) scheduledEvent.channelId = bot.transformers.snowflake(payload.channel_id); + if (props.creatorId && payload.creator_id) scheduledEvent.creatorId = bot.transformers.snowflake(payload.creator_id); + if (props.scheduledStartTime && payload.scheduled_start_time) scheduledEvent.scheduledStartTime = Date.parse(payload.scheduled_start_time); + if (props.scheduledEndTime && payload.scheduled_end_time) scheduledEvent.scheduledEndTime = Date.parse(payload.scheduled_end_time); + if (props.entityId && payload.entity_id) scheduledEvent.entityId = bot.transformers.snowflake(payload.entity_id); + if (props.creator && payload.creator) scheduledEvent.creator = bot.transformers.user(bot, payload.creator); + if (props.name && payload.name) scheduledEvent.name = payload.name; + if (props.description && payload.description) scheduledEvent.description = payload.description; + if (props.privacyLevel && payload.privacy_level) scheduledEvent.privacyLevel = payload.privacy_level; + if (props.status && payload.status) scheduledEvent.status = payload.status; + if (props.entityType && payload.entity_type) scheduledEvent.entityType = payload.entity_type; + if (props.userCount) scheduledEvent.userCount = payload.user_count ?? 0; + if (props.location && payload.entity_metadata?.location) scheduledEvent.location = payload.entity_metadata.location; + if (props.image && payload.image) scheduledEvent.image = iconHashToBigInt(payload.image); if (props.recurrenceRule && payload.recurrence_rule) - scheduledEvent.recurrenceRule = bot.transformers.scheduledEventRecurrenceRule(bot, payload.recurrence_rule) + scheduledEvent.recurrenceRule = bot.transformers.scheduledEventRecurrenceRule(bot, payload.recurrence_rule); - return bot.transformers.customizers.scheduledEvent(bot, payload, scheduledEvent) + return bot.transformers.customizers.scheduledEvent(bot, payload, scheduledEvent); } export function transformScheduledEventRecurrenceRule(bot: Bot, payload: DiscordScheduledEventRecurrenceRule): ScheduledEventRecurrenceRule { - const props = bot.transformers.desiredProperties.scheduledEventRecurrenceRule - const recurrenceRule = {} as SetupDesiredProps + const props = bot.transformers.desiredProperties.scheduledEventRecurrenceRule; + const recurrenceRule = {} as SetupDesiredProps; - if (props.start && payload.start) recurrenceRule.start = Date.parse(payload.start) - if (props.end && payload.end) recurrenceRule.end = Date.parse(payload.end) - if (props.frequency && payload.frequency) recurrenceRule.frequency = payload.frequency - if (props.interval && payload.interval) recurrenceRule.interval = payload.interval - if (props.byWeekday && payload.by_weekday) recurrenceRule.byWeekday = payload.by_weekday - if (props.byNWeekday && payload.by_n_weekday) recurrenceRule.byNWeekday = payload.by_n_weekday - if (props.byMonth && payload.by_month) recurrenceRule.byMonth = payload.by_month - if (props.byMonthDay && payload.by_month_day) recurrenceRule.byMonthDay = payload.by_month_day - if (props.byYearDay && payload.by_year_day) recurrenceRule.byYearDay = payload.by_year_day - if (props.count && payload.count) recurrenceRule.count = payload.count + if (props.start && payload.start) recurrenceRule.start = Date.parse(payload.start); + if (props.end && payload.end) recurrenceRule.end = Date.parse(payload.end); + if (props.frequency && payload.frequency) recurrenceRule.frequency = payload.frequency; + if (props.interval && payload.interval) recurrenceRule.interval = payload.interval; + if (props.byWeekday && payload.by_weekday) recurrenceRule.byWeekday = payload.by_weekday; + if (props.byNWeekday && payload.by_n_weekday) recurrenceRule.byNWeekday = payload.by_n_weekday; + if (props.byMonth && payload.by_month) recurrenceRule.byMonth = payload.by_month; + if (props.byMonthDay && payload.by_month_day) recurrenceRule.byMonthDay = payload.by_month_day; + if (props.byYearDay && payload.by_year_day) recurrenceRule.byYearDay = payload.by_year_day; + if (props.count && payload.count) recurrenceRule.count = payload.count; - return bot.transformers.customizers.scheduledEventRecurrenceRule(bot, payload, recurrenceRule) + return bot.transformers.customizers.scheduledEventRecurrenceRule(bot, payload, recurrenceRule); } diff --git a/packages/bot/src/transformers/sku.ts b/packages/bot/src/transformers/sku.ts index 08b3bcc22..03e3a8a49 100644 --- a/packages/bot/src/transformers/sku.ts +++ b/packages/bot/src/transformers/sku.ts @@ -1,18 +1,18 @@ -import type { DiscordSku } from '@discordeno/types' -import type { Bot } from '../bot.js' -import type { DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from '../desiredProperties.js' -import type { Sku } from './types.js' +import type { DiscordSku } from '@discordeno/types'; +import type { Bot } from '../bot.js'; +import type { DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from '../desiredProperties.js'; +import type { Sku } from './types.js'; export function transformSku(bot: Bot, payload: DiscordSku): Sku { - const props = bot.transformers.desiredProperties.sku - const sku = {} as SetupDesiredProps + const props = bot.transformers.desiredProperties.sku; + const sku = {} as SetupDesiredProps; - if (props.id && payload.id) sku.id = bot.transformers.snowflake(payload.id) - if (props.type && payload.type) sku.type = payload.type - if (props.applicationId && payload.application_id) sku.applicationId = bot.transformers.snowflake(payload.application_id) - if (props.name && payload.name) sku.name = payload.name - if (props.slug && payload.slug) sku.slug = payload.slug - if (props.flags && payload.flags) sku.flags = payload.flags + if (props.id && payload.id) sku.id = bot.transformers.snowflake(payload.id); + if (props.type && payload.type) sku.type = payload.type; + if (props.applicationId && payload.application_id) sku.applicationId = bot.transformers.snowflake(payload.application_id); + if (props.name && payload.name) sku.name = payload.name; + if (props.slug && payload.slug) sku.slug = payload.slug; + if (props.flags && payload.flags) sku.flags = payload.flags; - return bot.transformers.customizers.sku(bot, payload, sku) + return bot.transformers.customizers.sku(bot, payload, sku); } diff --git a/packages/bot/src/transformers/soundboardSound.ts b/packages/bot/src/transformers/soundboardSound.ts index 92dadfd75..74d4537c3 100644 --- a/packages/bot/src/transformers/soundboardSound.ts +++ b/packages/bot/src/transformers/soundboardSound.ts @@ -1,20 +1,20 @@ -import type { DiscordSoundboardSound } from '@discordeno/types' -import type { Bot } from '../bot.js' -import type { DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from '../desiredProperties.js' -import type { SoundboardSound } from './types.js' +import type { DiscordSoundboardSound } from '@discordeno/types'; +import type { Bot } from '../bot.js'; +import type { DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from '../desiredProperties.js'; +import type { SoundboardSound } from './types.js'; export function transformSoundboardSound(bot: Bot, payload: DiscordSoundboardSound): SoundboardSound { - const props = bot.transformers.desiredProperties.soundboardSound - const soundboardSound = {} as SetupDesiredProps + const props = bot.transformers.desiredProperties.soundboardSound; + const soundboardSound = {} as SetupDesiredProps; - if (props.name && payload.name) soundboardSound.name = payload.name - if (props.soundId && payload.sound_id) soundboardSound.soundId = bot.transformers.snowflake(payload.sound_id) - if (props.volume && payload.volume) soundboardSound.volume = payload.volume - if (props.emojiId && payload.emoji_id) soundboardSound.emojiId = bot.transformers.snowflake(payload.emoji_id) - if (props.emojiName && payload.emoji_name) soundboardSound.emojiName = payload.emoji_name - if (props.guildId && payload.guild_id) soundboardSound.guildId = bot.transformers.snowflake(payload.guild_id) - if (props.available && payload.available) soundboardSound.available = payload.available - if (props.user && payload.user) soundboardSound.user = bot.transformers.user(bot, payload.user) + if (props.name && payload.name) soundboardSound.name = payload.name; + if (props.soundId && payload.sound_id) soundboardSound.soundId = bot.transformers.snowflake(payload.sound_id); + if (props.volume && payload.volume) soundboardSound.volume = payload.volume; + if (props.emojiId && payload.emoji_id) soundboardSound.emojiId = bot.transformers.snowflake(payload.emoji_id); + if (props.emojiName && payload.emoji_name) soundboardSound.emojiName = payload.emoji_name; + if (props.guildId && payload.guild_id) soundboardSound.guildId = bot.transformers.snowflake(payload.guild_id); + if (props.available && payload.available) soundboardSound.available = payload.available; + if (props.user && payload.user) soundboardSound.user = bot.transformers.user(bot, payload.user); - return bot.transformers.customizers.soundboardSound(bot, payload, soundboardSound) + return bot.transformers.customizers.soundboardSound(bot, payload, soundboardSound); } diff --git a/packages/bot/src/transformers/stageInstance.ts b/packages/bot/src/transformers/stageInstance.ts index bad16cc5b..296294d99 100644 --- a/packages/bot/src/transformers/stageInstance.ts +++ b/packages/bot/src/transformers/stageInstance.ts @@ -1,18 +1,18 @@ -import type { DiscordStageInstance } from '@discordeno/types' -import type { Bot } from '../bot.js' -import type { DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from '../desiredProperties.js' -import type { StageInstance } from './types.js' +import type { DiscordStageInstance } from '@discordeno/types'; +import type { Bot } from '../bot.js'; +import type { DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from '../desiredProperties.js'; +import type { StageInstance } from './types.js'; export function transformStageInstance(bot: Bot, payload: DiscordStageInstance): StageInstance { - const props = bot.transformers.desiredProperties.stageInstance - const stageInstance = {} as SetupDesiredProps + const props = bot.transformers.desiredProperties.stageInstance; + const stageInstance = {} as SetupDesiredProps; - if (props.id && payload.id) stageInstance.id = bot.transformers.snowflake(payload.id) - if (props.guildId && payload.guild_id) stageInstance.guildId = bot.transformers.snowflake(payload.guild_id) - if (props.channelId && payload.channel_id) stageInstance.channelId = bot.transformers.snowflake(payload.channel_id) - if (props.topic && payload.topic) stageInstance.topic = payload.topic + if (props.id && payload.id) stageInstance.id = bot.transformers.snowflake(payload.id); + if (props.guildId && payload.guild_id) stageInstance.guildId = bot.transformers.snowflake(payload.guild_id); + if (props.channelId && payload.channel_id) stageInstance.channelId = bot.transformers.snowflake(payload.channel_id); + if (props.topic && payload.topic) stageInstance.topic = payload.topic; if (props.guildScheduledEventId && payload.guild_scheduled_event_id) - stageInstance.guildScheduledEventId = bot.transformers.snowflake(payload.guild_scheduled_event_id) + stageInstance.guildScheduledEventId = bot.transformers.snowflake(payload.guild_scheduled_event_id); - return bot.transformers.customizers.stageInstance(bot, payload, stageInstance) + return bot.transformers.customizers.stageInstance(bot, payload, stageInstance); } diff --git a/packages/bot/src/transformers/stageInviteInstance.ts b/packages/bot/src/transformers/stageInviteInstance.ts index 4838337cc..170944705 100644 --- a/packages/bot/src/transformers/stageInviteInstance.ts +++ b/packages/bot/src/transformers/stageInviteInstance.ts @@ -1,11 +1,11 @@ -import type { BigString, DiscordInviteStageInstance } from '@discordeno/types' -import type { Bot } from '../bot.js' -import type { DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from '../desiredProperties.js' -import type { InviteStageInstance } from './types.js' +import type { BigString, DiscordInviteStageInstance } from '@discordeno/types'; +import type { Bot } from '../bot.js'; +import type { DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from '../desiredProperties.js'; +import type { InviteStageInstance } from './types.js'; export function transformInviteStageInstance(bot: Bot, payload: DiscordInviteStageInstance, extra?: { guildId?: BigString }): InviteStageInstance { - const props = bot.transformers.desiredProperties.inviteStageInstance - const inviteStageInstance = {} as SetupDesiredProps + const props = bot.transformers.desiredProperties.inviteStageInstance; + const inviteStageInstance = {} as SetupDesiredProps; if (props.members && payload.members) { inviteStageInstance.members = payload.members.map((member) => @@ -14,13 +14,13 @@ export function transformInviteStageInstance(bot: Bot, payload: DiscordInviteSta guildId: extra?.guildId, userId: member.user?.id, }), - ) + ); } - if (props.participantCount) inviteStageInstance.participantCount = payload.participant_count - if (props.speakerCount) inviteStageInstance.participantCount = payload.participant_count - if (props.topic && payload.topic) inviteStageInstance.topic = payload.topic + if (props.participantCount) inviteStageInstance.participantCount = payload.participant_count; + if (props.speakerCount) inviteStageInstance.participantCount = payload.participant_count; + if (props.topic && payload.topic) inviteStageInstance.topic = payload.topic; return bot.transformers.customizers.inviteStageInstance(bot, payload, inviteStageInstance, { guildId: extra?.guildId ? bot.transformers.snowflake(extra.guildId) : undefined, - }) + }); } diff --git a/packages/bot/src/transformers/sticker.ts b/packages/bot/src/transformers/sticker.ts index 0222e3aba..7e8ecc0e0 100644 --- a/packages/bot/src/transformers/sticker.ts +++ b/packages/bot/src/transformers/sticker.ts @@ -1,25 +1,25 @@ -import type { DiscordSticker, DiscordStickerPack } from '@discordeno/types' -import type { Bot } from '../bot.js' -import type { DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from '../desiredProperties.js' -import type { Sticker, StickerPack } from './types.js' +import type { DiscordSticker, DiscordStickerPack } from '@discordeno/types'; +import type { Bot } from '../bot.js'; +import type { DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from '../desiredProperties.js'; +import type { Sticker, StickerPack } from './types.js'; export function transformSticker(bot: Bot, payload: DiscordSticker): Sticker { - const props = bot.transformers.desiredProperties.sticker - const sticker = {} as SetupDesiredProps + const props = bot.transformers.desiredProperties.sticker; + const sticker = {} as SetupDesiredProps; - if (props.id && payload.id) sticker.id = bot.transformers.snowflake(payload.id) - if (props.packId && payload.pack_id) sticker.packId = bot.transformers.snowflake(payload.pack_id) - if (props.name && payload.name) sticker.name = payload.name - if (props.description && payload.description) sticker.description = payload.description - if (props.tags && payload.tags) sticker.tags = payload.tags - if (props.type && payload.type) sticker.type = payload.type - if (props.formatType && payload.format_type) sticker.formatType = payload.format_type - if (props.available && payload.available) sticker.available = payload.available - if (props.guildId && payload.guild_id) sticker.guildId = bot.transformers.snowflake(payload.guild_id) - if (props.user && payload.user) sticker.user = bot.transformers.user(bot, payload.user) - if (props.sortValue && payload.sort_value !== undefined) sticker.sortValue = payload.sort_value + if (props.id && payload.id) sticker.id = bot.transformers.snowflake(payload.id); + if (props.packId && payload.pack_id) sticker.packId = bot.transformers.snowflake(payload.pack_id); + if (props.name && payload.name) sticker.name = payload.name; + if (props.description && payload.description) sticker.description = payload.description; + if (props.tags && payload.tags) sticker.tags = payload.tags; + if (props.type && payload.type) sticker.type = payload.type; + if (props.formatType && payload.format_type) sticker.formatType = payload.format_type; + if (props.available && payload.available) sticker.available = payload.available; + if (props.guildId && payload.guild_id) sticker.guildId = bot.transformers.snowflake(payload.guild_id); + if (props.user && payload.user) sticker.user = bot.transformers.user(bot, payload.user); + if (props.sortValue && payload.sort_value !== undefined) sticker.sortValue = payload.sort_value; - return bot.transformers.customizers.sticker(bot, payload, sticker) + return bot.transformers.customizers.sticker(bot, payload, sticker); } export function transformStickerPack(bot: Bot, payload: DiscordStickerPack): StickerPack { @@ -31,7 +31,7 @@ export function transformStickerPack(bot: Bot, payload: DiscordStickerPack): Sti coverStickerId: payload.cover_sticker_id ? bot.transformers.snowflake(payload.cover_sticker_id) : undefined, description: payload.description, bannerAssetId: payload.banner_asset_id ? bot.transformers.snowflake(payload.banner_asset_id) : undefined, - } as StickerPack + } as StickerPack; - return bot.transformers.customizers.stickerPack(bot, payload, pack) + return bot.transformers.customizers.stickerPack(bot, payload, pack); } diff --git a/packages/bot/src/transformers/subscription.ts b/packages/bot/src/transformers/subscription.ts index 8905705c1..c81d8fa22 100644 --- a/packages/bot/src/transformers/subscription.ts +++ b/packages/bot/src/transformers/subscription.ts @@ -1,24 +1,24 @@ -import type { DiscordSubscription } from '@discordeno/types' -import type { Bot } from '../bot.js' -import type { DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from '../desiredProperties.js' -import type { Subscription } from './types.js' +import type { DiscordSubscription } from '@discordeno/types'; +import type { Bot } from '../bot.js'; +import type { DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from '../desiredProperties.js'; +import type { Subscription } from './types.js'; export function transformSubscription(bot: Bot, payload: DiscordSubscription): Subscription { - const props = bot.transformers.desiredProperties.subscription - const subscription = {} as SetupDesiredProps + const props = bot.transformers.desiredProperties.subscription; + const subscription = {} as SetupDesiredProps; - if (props.id && payload.id) subscription.id = bot.transformers.snowflake(payload.id) - if (props.userId && payload.user_id) subscription.userId = bot.transformers.snowflake(payload.user_id) - if (props.skuIds && payload.sku_ids) subscription.skuIds = payload.sku_ids.map((skuId) => bot.transformers.snowflake(skuId)) + if (props.id && payload.id) subscription.id = bot.transformers.snowflake(payload.id); + if (props.userId && payload.user_id) subscription.userId = bot.transformers.snowflake(payload.user_id); + if (props.skuIds && payload.sku_ids) subscription.skuIds = payload.sku_ids.map((skuId) => bot.transformers.snowflake(skuId)); if (props.entitlementIds && payload.entitlement_ids) - subscription.entitlementIds = payload.entitlement_ids.map((entitlementId) => bot.transformers.snowflake(entitlementId)) + subscription.entitlementIds = payload.entitlement_ids.map((entitlementId) => bot.transformers.snowflake(entitlementId)); if (props.renewalSkuIds && payload.renewal_sku_ids) - subscription.renewalSkuIds = payload.renewal_sku_ids.map((skuId) => bot.transformers.snowflake(skuId)) - if (props.currentPeriodStart && payload.current_period_start) subscription.currentPeriodStart = Date.parse(payload.current_period_start) - if (props.currentPeriodEnd && payload.current_period_end) subscription.currentPeriodEnd = Date.parse(payload.current_period_end) - if (props.status && payload.status !== undefined) subscription.status = payload.status - if (props.canceledAt && payload.canceled_at) subscription.canceledAt = Date.parse(payload.canceled_at) - if (props.country && payload.country) subscription.country = payload.country + subscription.renewalSkuIds = payload.renewal_sku_ids.map((skuId) => bot.transformers.snowflake(skuId)); + if (props.currentPeriodStart && payload.current_period_start) subscription.currentPeriodStart = Date.parse(payload.current_period_start); + if (props.currentPeriodEnd && payload.current_period_end) subscription.currentPeriodEnd = Date.parse(payload.current_period_end); + if (props.status && payload.status !== undefined) subscription.status = payload.status; + if (props.canceledAt && payload.canceled_at) subscription.canceledAt = Date.parse(payload.canceled_at); + if (props.country && payload.country) subscription.country = payload.country; - return bot.transformers.customizers.subscription(bot, payload, subscription) + return bot.transformers.customizers.subscription(bot, payload, subscription); } diff --git a/packages/bot/src/transformers/team.ts b/packages/bot/src/transformers/team.ts index d73216623..9ad7dcb1a 100644 --- a/packages/bot/src/transformers/team.ts +++ b/packages/bot/src/transformers/team.ts @@ -1,10 +1,10 @@ -import type { DiscordTeam } from '@discordeno/types' -import { iconHashToBigInt } from '@discordeno/utils' -import type { Bot } from '../bot.js' -import type { Team } from './types.js' +import type { DiscordTeam } from '@discordeno/types'; +import { iconHashToBigInt } from '@discordeno/utils'; +import type { Bot } from '../bot.js'; +import type { Team } from './types.js'; export function transformTeam(bot: Bot, payload: DiscordTeam): Team { - const id = bot.transformers.snowflake(payload.id) + const id = bot.transformers.snowflake(payload.id); const team = { name: payload.name, @@ -17,7 +17,7 @@ export function transformTeam(bot: Bot, payload: DiscordTeam): Team { user: bot.transformers.user(bot, member.user), role: member.role, })), - } as Team + } as Team; - return bot.transformers.customizers.team(bot, payload, team) + return bot.transformers.customizers.team(bot, payload, team); } diff --git a/packages/bot/src/transformers/template.ts b/packages/bot/src/transformers/template.ts index a5842a202..5b9bed818 100644 --- a/packages/bot/src/transformers/template.ts +++ b/packages/bot/src/transformers/template.ts @@ -1,6 +1,6 @@ -import type { DiscordTemplate } from '@discordeno/types' -import type { Bot } from '../bot.js' -import type { Template } from './types.js' +import type { DiscordTemplate } from '@discordeno/types'; +import type { Bot } from '../bot.js'; +import type { Template } from './types.js'; export function transformTemplate(bot: Bot, payload: DiscordTemplate): Template { const template = { code: payload.code, @@ -14,7 +14,7 @@ export function transformTemplate(bot: Bot, payload: DiscordTemplate): Template sourceGuildId: bot.transformers.snowflake(payload.source_guild_id), serializedSourceGuild: payload.serialized_source_guild, isDirty: payload.is_dirty ?? undefined, - } as Template + } as Template; - return bot.transformers.customizers.template(bot, payload, template) + return bot.transformers.customizers.template(bot, payload, template); } diff --git a/packages/bot/src/transformers/threadMember.ts b/packages/bot/src/transformers/threadMember.ts index 6e7fca576..60f8de122 100644 --- a/packages/bot/src/transformers/threadMember.ts +++ b/packages/bot/src/transformers/threadMember.ts @@ -1,6 +1,6 @@ -import type { BigString, DiscordThreadMember, DiscordThreadMemberGuildCreate } from '@discordeno/types' -import type { Bot } from '../bot.js' -import type { ThreadMember, ThreadMemberGuildCreate } from './types.js' +import type { BigString, DiscordThreadMember, DiscordThreadMemberGuildCreate } from '@discordeno/types'; +import type { Bot } from '../bot.js'; +import type { ThreadMember, ThreadMemberGuildCreate } from './types.js'; export function transformThreadMember(bot: Bot, payload: DiscordThreadMember, extra?: ThreadMemberTransformerExtra): ThreadMember { const threadMember = { @@ -14,11 +14,11 @@ export function transformThreadMember(bot: Bot, payload: DiscordThreadMember, ex userId: payload.user_id, }) : undefined, - } as ThreadMember + } as ThreadMember; return bot.transformers.customizers.threadMember(bot, payload, threadMember, { guildId: extra?.guildId ? bot.transformers.snowflake(extra?.guildId) : undefined, - }) + }); } export interface ThreadMemberTransformerExtra { @@ -28,13 +28,13 @@ export interface ThreadMemberTransformerExtra { * * This allows you to cache member objects in the member customizer. */ - guildId?: BigString + guildId?: BigString; } export function transformThreadMemberGuildCreate(bot: Bot, payload: DiscordThreadMemberGuildCreate): ThreadMemberGuildCreate { const threadMember = { joinTimestamp: Date.parse(payload.join_timestamp), - } as ThreadMemberGuildCreate + } as ThreadMemberGuildCreate; - return bot.transformers.customizers.threadMemberGuildCreate(bot, payload, threadMember) + return bot.transformers.customizers.threadMemberGuildCreate(bot, payload, threadMember); } diff --git a/packages/bot/src/transformers/toggles/Permissions.ts b/packages/bot/src/transformers/toggles/Permissions.ts index 9544b1699..690d236a8 100644 --- a/packages/bot/src/transformers/toggles/Permissions.ts +++ b/packages/bot/src/transformers/toggles/Permissions.ts @@ -1,20 +1,20 @@ -import { BitwisePermissionFlags, type PermissionStrings } from '@discordeno/types' -import { ToggleBitfieldBigint } from './ToggleBitfield.js' +import { BitwisePermissionFlags, type PermissionStrings } from '@discordeno/types'; +import { ToggleBitfieldBigint } from './ToggleBitfield.js'; export class Permissions extends ToggleBitfieldBigint { constructor(bits: string | bigint) { - super(BigInt(bits)) + super(BigInt(bits)); } has(permission: PermissionStrings): boolean { - return this.contains(BitwisePermissionFlags[permission]) + return this.contains(BitwisePermissionFlags[permission]); } hasAll(permissions: PermissionStrings[]): boolean { - return permissions.every((key) => this.has(key)) + return permissions.every((key) => this.has(key)); } missing(permissions: PermissionStrings[]): PermissionStrings[] { - return permissions.filter((key) => !this.has(key)) + return permissions.filter((key) => !this.has(key)); } } diff --git a/packages/bot/src/transformers/toggles/ToggleBitfield.ts b/packages/bot/src/transformers/toggles/ToggleBitfield.ts index 1fde6d986..4da9838d8 100644 --- a/packages/bot/src/transformers/toggles/ToggleBitfield.ts +++ b/packages/bot/src/transformers/toggles/ToggleBitfield.ts @@ -1,57 +1,57 @@ export class ToggleBitfield { - bitfield = 0 + bitfield = 0; constructor(bitfield?: number) { - if (bitfield) this.bitfield = bitfield + if (bitfield) this.bitfield = bitfield; } /** Tests whether or not this bitfield has the permission requested. */ contains(bits: number): boolean { - return Boolean(this.bitfield & bits) + return Boolean(this.bitfield & bits); } /** Adds some bits to the bitfield. */ add(bits: number): this { - this.bitfield |= bits - return this + this.bitfield |= bits; + return this; } /** Removes some bits from the bitfield. */ remove(bits: number): this { - this.bitfield &= ~bits - return this + this.bitfield &= ~bits; + return this; } toJSON(): number { - return this.bitfield + return this.bitfield; } } export class ToggleBitfieldBigint { - bitfield = 0n + bitfield = 0n; constructor(bitfield?: bigint) { - if (bitfield) this.bitfield = bitfield + if (bitfield) this.bitfield = bitfield; } /** Tests whether or not this bitfield has the permission requested. */ contains(bits: bigint): boolean { - return Boolean(this.bitfield & bits) + return Boolean(this.bitfield & bits); } /** Adds some bits to the bitfield. */ add(bits: bigint): this { - this.bitfield |= bits - return this + this.bitfield |= bits; + return this; } /** Removes some bits from the bitfield. */ remove(bits: bigint): this { - this.bitfield &= ~bits - return this + this.bitfield &= ~bits; + return this; } toJSON(): string { - return this.bitfield.toString() + return this.bitfield.toString(); } } diff --git a/packages/bot/src/transformers/toggles/channel.ts b/packages/bot/src/transformers/toggles/channel.ts index e775b5ebf..3f2ae5139 100644 --- a/packages/bot/src/transformers/toggles/channel.ts +++ b/packages/bot/src/transformers/toggles/channel.ts @@ -1,5 +1,5 @@ -import type { DiscordChannel } from '@discordeno/types' -import { ToggleBitfield } from './ToggleBitfield.js' +import type { DiscordChannel } from '@discordeno/types'; +import { ToggleBitfield } from './ToggleBitfield.js'; export const ChannelToggle = { /** Whether the channel is nsfw */ @@ -14,69 +14,69 @@ export const ChannelToggle = { newlyCreated: 1 << 4, /** for group DM channels: whether the channel is managed by an application via the `gdm.join` OAuth2 scope */ managed: 1 << 5, -} +}; export class ChannelToggles extends ToggleBitfield { constructor(channelOrBitfield: DiscordChannel | number) { - super() + super(); - if (typeof channelOrBitfield === 'number') this.bitfield = channelOrBitfield + if (typeof channelOrBitfield === 'number') this.bitfield = channelOrBitfield; else { - const channel = channelOrBitfield - if (channel.nsfw) this.add(ChannelToggle.nsfw) - if (channel.thread_metadata?.locked) this.add(ChannelToggle.locked) - if (channel.thread_metadata?.invitable) this.add(ChannelToggle.invitable) - if (channel.thread_metadata?.archived) this.add(ChannelToggle.archived) - if (channel.newly_created) this.add(ChannelToggle.newlyCreated) - if (channel.managed) this.add(ChannelToggle.managed) + const channel = channelOrBitfield; + if (channel.nsfw) this.add(ChannelToggle.nsfw); + if (channel.thread_metadata?.locked) this.add(ChannelToggle.locked); + if (channel.thread_metadata?.invitable) this.add(ChannelToggle.invitable); + if (channel.thread_metadata?.archived) this.add(ChannelToggle.archived); + if (channel.newly_created) this.add(ChannelToggle.newlyCreated); + if (channel.managed) this.add(ChannelToggle.managed); } } /** Whether or not this channel is an nsfw channel. */ get nsfw(): boolean { - return this.has('nsfw') + return this.has('nsfw'); } /** Whether or not this thread channel is locked. */ get locked(): boolean { - return this.has('locked') + return this.has('locked'); } /** Whether or not this thread channel is invitable. */ get invitable(): boolean { - return this.has('invitable') + return this.has('invitable'); } /** Whether or not this thread channel is archived. */ get archived(): boolean { - return this.has('archived') + return this.has('archived'); } /** Whether or not this thread channel is newly created. */ get newlyCreated(): boolean { - return this.has('newlyCreated') + return this.has('newlyCreated'); } get managed(): boolean { - return this.has('managed') + return this.has('managed'); } /** Checks whether or not the permissions exist in this */ has(permissions: ChannelToggleKeys | ChannelToggleKeys[]): boolean { - if (!Array.isArray(permissions)) return super.contains(ChannelToggle[permissions]) + if (!Array.isArray(permissions)) return super.contains(ChannelToggle[permissions]); - return super.contains(permissions.reduce((a, b) => (a |= ChannelToggle[b]), 0)) + return super.contains(permissions.reduce((a, b) => (a |= ChannelToggle[b]), 0)); } /** Lists all the toggles for the role and whether or not each is true or false. */ list(): Record { - const json: Record = {} + const json: Record = {}; for (const [key, value] of Object.entries(ChannelToggle)) { - json[key] = super.contains(value) + json[key] = super.contains(value); } - return json as Record + return json as Record; } } -export type ChannelToggleKeys = keyof typeof ChannelToggle +export type ChannelToggleKeys = keyof typeof ChannelToggle; diff --git a/packages/bot/src/transformers/toggles/emoji.ts b/packages/bot/src/transformers/toggles/emoji.ts index a7197c366..d46552b83 100644 --- a/packages/bot/src/transformers/toggles/emoji.ts +++ b/packages/bot/src/transformers/toggles/emoji.ts @@ -1,5 +1,5 @@ -import type { DiscordEmoji } from '@discordeno/types' -import { ToggleBitfield } from './ToggleBitfield.js' +import type { DiscordEmoji } from '@discordeno/types'; +import { ToggleBitfield } from './ToggleBitfield.js'; export const EmojiToggle = { /** Whether this emoji must be wrapped in colons */ @@ -10,59 +10,59 @@ export const EmojiToggle = { animated: 1 << 2, /** Whether this emoji can be used, may be false due to loss of Server Boosts */ available: 1 << 3, -} +}; export class EmojiToggles extends ToggleBitfield { constructor(roleOrTogglesInt: DiscordEmoji | number) { - super() + super(); - if (typeof roleOrTogglesInt === 'number') this.bitfield = roleOrTogglesInt + if (typeof roleOrTogglesInt === 'number') this.bitfield = roleOrTogglesInt; else { - const role = roleOrTogglesInt + const role = roleOrTogglesInt; - if (role.require_colons) this.add(EmojiToggle.requireColons) - if (role.managed) this.add(EmojiToggle.managed) - if (role.animated) this.add(EmojiToggle.animated) - if (role.available) this.add(EmojiToggle.available) + if (role.require_colons) this.add(EmojiToggle.requireColons); + if (role.managed) this.add(EmojiToggle.managed); + if (role.animated) this.add(EmojiToggle.animated); + if (role.available) this.add(EmojiToggle.available); } } /** Whether this emoji must be wrapped in colons */ get requireColons(): boolean { - return this.has('requireColons') + return this.has('requireColons'); } /** Whether this emoji is managed */ get managed(): boolean { - return this.has('managed') + return this.has('managed'); } /** Whether this emoji is animated */ get animated(): boolean { - return this.has('animated') + return this.has('animated'); } /** Whether this emoji can be used, may be false due to loss of Server Boosts */ get available(): boolean { - return this.has('available') + return this.has('available'); } /** Checks whether or not the permissions exist in this */ has(permissions: EmojiToggleKeys | EmojiToggleKeys[]): boolean { - if (!Array.isArray(permissions)) return super.contains(EmojiToggle[permissions]) + if (!Array.isArray(permissions)) return super.contains(EmojiToggle[permissions]); - return super.contains(permissions.reduce((a, b) => (a |= EmojiToggle[b]), 0)) + return super.contains(permissions.reduce((a, b) => (a |= EmojiToggle[b]), 0)); } /** Lists all the toggles for the role and whether or not each is true or false. */ list(): Record { - const json: Record = {} + const json: Record = {}; for (const [key, value] of Object.entries(EmojiToggle)) { - json[key] = super.contains(value) + json[key] = super.contains(value); } - return json as Record + return json as Record; } } -export type EmojiToggleKeys = keyof typeof EmojiToggle +export type EmojiToggleKeys = keyof typeof EmojiToggle; diff --git a/packages/bot/src/transformers/toggles/guild.ts b/packages/bot/src/transformers/toggles/guild.ts index 37285097a..c16c09729 100644 --- a/packages/bot/src/transformers/toggles/guild.ts +++ b/packages/bot/src/transformers/toggles/guild.ts @@ -1,5 +1,5 @@ -import { type DiscordGuild, GuildFeatures } from '@discordeno/types' -import { ToggleBitfieldBigint } from './ToggleBitfield.js' +import { type DiscordGuild, GuildFeatures } from '@discordeno/types'; +import { ToggleBitfieldBigint } from './ToggleBitfield.js'; /** @private This is subject to breaking changes without notices */ export const guildFeatureNames = [ @@ -34,7 +34,7 @@ export const guildFeatureNames = [ 'guestsEnabled', 'guildTags', 'enhancedRoleColors', -] as const +] as const; export const GuildToggle = { /** Whether the bot is the owner of the guild */ @@ -114,274 +114,274 @@ export const GuildToggle = { guildTags: 1n << 36n, /** Whether the guild is able to set gradient colors to roles */ enhancedRoleColors: 1n << 35n, -} +}; export class GuildToggles extends ToggleBitfieldBigint { constructor(guildOrTogglesBigint: DiscordGuild | bigint) { - super() + super(); - if (typeof guildOrTogglesBigint === 'bigint') this.bitfield = guildOrTogglesBigint + if (typeof guildOrTogglesBigint === 'bigint') this.bitfield = guildOrTogglesBigint; else { - const guild = guildOrTogglesBigint + const guild = guildOrTogglesBigint; // Cause discord be smart like that - if (!guild.features) guild.features = [] + if (!guild.features) guild.features = []; - if (guild.owner) this.add(GuildToggle.owner) - if (guild.widget_enabled) this.add(GuildToggle.widgetEnabled) - if (guild.large) this.add(GuildToggle.large) - if (guild.unavailable) this.add(GuildToggle.unavailable) - if (guild.premium_progress_bar_enabled) this.add(GuildToggle.premiumProgressBarEnabled) + if (guild.owner) this.add(GuildToggle.owner); + if (guild.widget_enabled) this.add(GuildToggle.widgetEnabled); + if (guild.large) this.add(GuildToggle.large); + if (guild.unavailable) this.add(GuildToggle.unavailable); + if (guild.premium_progress_bar_enabled) this.add(GuildToggle.premiumProgressBarEnabled); - if (guild.features.includes(GuildFeatures.AnimatedBanner)) this.add(GuildToggle.animatedBanner) - if (guild.features.includes(GuildFeatures.AnimatedIcon)) this.add(GuildToggle.animatedIcon) - if (guild.features.includes(GuildFeatures.ApplicationCommandPermissionsV2)) this.add(GuildToggle.applicationCommandPermissionsV2) - if (guild.features.includes(GuildFeatures.AutoModeration)) this.add(GuildToggle.autoModeration) - if (guild.features.includes(GuildFeatures.Banner)) this.add(GuildToggle.banner) - if (guild.features.includes(GuildFeatures.Community)) this.add(GuildToggle.community) - if (guild.features.includes(GuildFeatures.CreatorMonetizableProvisional)) this.add(GuildToggle.creatorMonetizableProvisional) - if (guild.features.includes(GuildFeatures.CreatorStorePage)) this.add(GuildToggle.creatorStorePage) - if (guild.features.includes(GuildFeatures.DeveloperSupportServer)) this.add(GuildToggle.developerSupportServer) - if (guild.features.includes(GuildFeatures.Discoverable)) this.add(GuildToggle.discoverable) - if (guild.features.includes(GuildFeatures.Featurable)) this.add(GuildToggle.featurable) - if (guild.features.includes(GuildFeatures.InvitesDisabled)) this.add(GuildToggle.invitesDisabled) - if (guild.features.includes(GuildFeatures.InviteSplash)) this.add(GuildToggle.inviteSplash) - if (guild.features.includes(GuildFeatures.MemberVerificationGateEnabled)) this.add(GuildToggle.memberVerificationGateEnabled) - if (guild.features.includes(GuildFeatures.MoreSoundboard)) this.add(GuildToggle.moreSoundboard) - if (guild.features.includes(GuildFeatures.MoreStickers)) this.add(GuildToggle.moreStickers) - if (guild.features.includes(GuildFeatures.News)) this.add(GuildToggle.news) - if (guild.features.includes(GuildFeatures.Partnered)) this.add(GuildToggle.partnered) - if (guild.features.includes(GuildFeatures.PreviewEnabled)) this.add(GuildToggle.previewEnabled) - if (guild.features.includes(GuildFeatures.RaidAlertsDisabled)) this.add(GuildToggle.raidAlertsDisabled) - if (guild.features.includes(GuildFeatures.RoleIcons)) this.add(GuildToggle.roleIcons) - if (guild.features.includes(GuildFeatures.RoleSubscriptionsAvailableForPurchase)) this.add(GuildToggle.roleSubscriptionsAvailableForPurchase) - if (guild.features.includes(GuildFeatures.RoleSubscriptionsEnabled)) this.add(GuildToggle.roleSubscriptionsEnabled) - if (guild.features.includes(GuildFeatures.Soundboard)) this.add(GuildToggle.soundboard) - if (guild.features.includes(GuildFeatures.TicketedEventsEnabled)) this.add(GuildToggle.ticketedEventsEnabled) - if (guild.features.includes(GuildFeatures.VanityUrl)) this.add(GuildToggle.vanityUrl) - if (guild.features.includes(GuildFeatures.Verified)) this.add(GuildToggle.verified) - if (guild.features.includes(GuildFeatures.VipRegions)) this.add(GuildToggle.vipRegions) - if (guild.features.includes(GuildFeatures.WelcomeScreenEnabled)) this.add(GuildToggle.welcomeScreenEnabled) - if (guild.features.includes(GuildFeatures.GuestsEnabled)) this.add(GuildToggle.guestsEnabled) - if (guild.features.includes(GuildFeatures.GuildTags)) this.add(GuildToggle.guildTags) - if (guild.features.includes(GuildFeatures.EnhancedRoleColors)) this.add(GuildToggle.enhancedRoleColors) + if (guild.features.includes(GuildFeatures.AnimatedBanner)) this.add(GuildToggle.animatedBanner); + if (guild.features.includes(GuildFeatures.AnimatedIcon)) this.add(GuildToggle.animatedIcon); + if (guild.features.includes(GuildFeatures.ApplicationCommandPermissionsV2)) this.add(GuildToggle.applicationCommandPermissionsV2); + if (guild.features.includes(GuildFeatures.AutoModeration)) this.add(GuildToggle.autoModeration); + if (guild.features.includes(GuildFeatures.Banner)) this.add(GuildToggle.banner); + if (guild.features.includes(GuildFeatures.Community)) this.add(GuildToggle.community); + if (guild.features.includes(GuildFeatures.CreatorMonetizableProvisional)) this.add(GuildToggle.creatorMonetizableProvisional); + if (guild.features.includes(GuildFeatures.CreatorStorePage)) this.add(GuildToggle.creatorStorePage); + if (guild.features.includes(GuildFeatures.DeveloperSupportServer)) this.add(GuildToggle.developerSupportServer); + if (guild.features.includes(GuildFeatures.Discoverable)) this.add(GuildToggle.discoverable); + if (guild.features.includes(GuildFeatures.Featurable)) this.add(GuildToggle.featurable); + if (guild.features.includes(GuildFeatures.InvitesDisabled)) this.add(GuildToggle.invitesDisabled); + if (guild.features.includes(GuildFeatures.InviteSplash)) this.add(GuildToggle.inviteSplash); + if (guild.features.includes(GuildFeatures.MemberVerificationGateEnabled)) this.add(GuildToggle.memberVerificationGateEnabled); + if (guild.features.includes(GuildFeatures.MoreSoundboard)) this.add(GuildToggle.moreSoundboard); + if (guild.features.includes(GuildFeatures.MoreStickers)) this.add(GuildToggle.moreStickers); + if (guild.features.includes(GuildFeatures.News)) this.add(GuildToggle.news); + if (guild.features.includes(GuildFeatures.Partnered)) this.add(GuildToggle.partnered); + if (guild.features.includes(GuildFeatures.PreviewEnabled)) this.add(GuildToggle.previewEnabled); + if (guild.features.includes(GuildFeatures.RaidAlertsDisabled)) this.add(GuildToggle.raidAlertsDisabled); + if (guild.features.includes(GuildFeatures.RoleIcons)) this.add(GuildToggle.roleIcons); + if (guild.features.includes(GuildFeatures.RoleSubscriptionsAvailableForPurchase)) this.add(GuildToggle.roleSubscriptionsAvailableForPurchase); + if (guild.features.includes(GuildFeatures.RoleSubscriptionsEnabled)) this.add(GuildToggle.roleSubscriptionsEnabled); + if (guild.features.includes(GuildFeatures.Soundboard)) this.add(GuildToggle.soundboard); + if (guild.features.includes(GuildFeatures.TicketedEventsEnabled)) this.add(GuildToggle.ticketedEventsEnabled); + if (guild.features.includes(GuildFeatures.VanityUrl)) this.add(GuildToggle.vanityUrl); + if (guild.features.includes(GuildFeatures.Verified)) this.add(GuildToggle.verified); + if (guild.features.includes(GuildFeatures.VipRegions)) this.add(GuildToggle.vipRegions); + if (guild.features.includes(GuildFeatures.WelcomeScreenEnabled)) this.add(GuildToggle.welcomeScreenEnabled); + if (guild.features.includes(GuildFeatures.GuestsEnabled)) this.add(GuildToggle.guestsEnabled); + if (guild.features.includes(GuildFeatures.GuildTags)) this.add(GuildToggle.guildTags); + if (guild.features.includes(GuildFeatures.EnhancedRoleColors)) this.add(GuildToggle.enhancedRoleColors); } } get features(): GuildFeatureKeys[] { - const features: GuildFeatureKeys[] = [] + const features: GuildFeatureKeys[] = []; for (const key of Object.keys(GuildToggle)) { - if (!guildFeatureNames.includes(key as GuildFeatureKeys)) continue - if (!super.contains(GuildToggle[key as GuildToggleKeys])) continue + if (!guildFeatureNames.includes(key as GuildFeatureKeys)) continue; + if (!super.contains(GuildToggle[key as GuildToggleKeys])) continue; - features.push(key as GuildFeatureKeys) + features.push(key as GuildFeatureKeys); } - return features + return features; } /** Whether the bot is the owner of the guild */ get owner(): boolean { - return this.has('owner') + return this.has('owner'); } /** Whether the server widget is enabled */ get widgetEnabled(): boolean { - return this.has('widgetEnabled') + return this.has('widgetEnabled'); } /** Whether this is considered a large guild */ get large(): boolean { - return this.has('large') + return this.has('large'); } /** Whether this guild is unavailable due to an outage */ get unavailable(): boolean { - return this.has('unavailable') + return this.has('unavailable'); } /** Whether the guild has the boost progress bar enabled */ get premiumProgressBarEnabled(): boolean { - return this.has('premiumProgressBarEnabled') + return this.has('premiumProgressBarEnabled'); } /** Whether the guild has access to set an invite splash background */ get inviteSplash(): boolean { - return this.has('inviteSplash') + return this.has('inviteSplash'); } /** Whether the guild has access to set 384 kbps bitrate in voice (previously VIP voice servers) */ get vipRegions(): boolean { - return this.has('vipRegions') + return this.has('vipRegions'); } /** Whether the guild has access to set a vanity URL */ get vanityUrl(): boolean { - return this.has('vanityUrl') + return this.has('vanityUrl'); } /** Whether the guild is verified */ get verified(): boolean { - return this.has('verified') + return this.has('verified'); } /** Whether the guild is partnered */ get partnered(): boolean { - return this.has('partnered') + return this.has('partnered'); } /** Whether the guild can enable welcome screen, Membership Screening, stage channels and discovery, and receives community updates */ get community(): boolean { - return this.has('community') + return this.has('community'); } /** Whether the Guild has been set as a support server on the App Directory */ get developerSupportServer(): boolean { - return this.has('developerSupportServer') + return this.has('developerSupportServer'); } /** Whether the guild has access to set an animated guild banner image */ get animatedBanner(): boolean { - return this.has('animatedBanner') + return this.has('animatedBanner'); } /** Whether the guild has access to create news channels */ get news(): boolean { - return this.has('news') + return this.has('news'); } /** Whether the guild is able to be discovered in the directory */ get discoverable(): boolean { - return this.has('discoverable') + return this.has('discoverable'); } /** Whether the guild is able to be featured in the directory */ get featurable(): boolean { - return this.has('featurable') + return this.has('featurable'); } /** Whether the guild has access to set an animated guild icon */ get animatedIcon(): boolean { - return this.has('animatedIcon') + return this.has('animatedIcon'); } /** Whether the guild has access to set a guild banner image */ get banner(): boolean { - return this.has('banner') + return this.has('banner'); } /** Whether the guild has enabled the welcome screen */ get welcomeScreenEnabled(): boolean { - return this.has('welcomeScreenEnabled') + return this.has('welcomeScreenEnabled'); } /** Whether the guild has enabled [Membership Screening](https://discord.com/developers/docs/resources/guild#membership-screening-object) */ get memberVerificationGateEnabled(): boolean { - return this.has('memberVerificationGateEnabled') + return this.has('memberVerificationGateEnabled'); } /** Whether the guild has more soundboard sound slot */ get moreSoundboard(): boolean { - return this.has('moreSoundboard') + return this.has('moreSoundboard'); } /** Whether the guild can be previewed before joining via Membership Screening or the directory */ get previewEnabled(): boolean { - return this.has('previewEnabled') + return this.has('previewEnabled'); } /** Whether the guild has enabled ticketed events */ get ticketedEventsEnabled(): boolean { - return this.has('ticketedEventsEnabled') + return this.has('ticketedEventsEnabled'); } /** Whether the guild has increased custom sticker slots */ get moreStickers(): boolean { - return this.has('moreStickers') + return this.has('moreStickers'); } /** Whether the guild is able to set role icons */ get roleIcons(): boolean { - return this.has('roleIcons') + return this.has('roleIcons'); } /** Whether the guild has set up auto moderation rules */ get autoModeration(): boolean { - return this.has('autoModeration') + return this.has('autoModeration'); } /** Whether the guild has paused invites, preventing new users from joining */ get invitesDisabled(): boolean { - return this.has('invitesDisabled') + return this.has('invitesDisabled'); } /** Whether the guild is using the old permissions configuration behavior */ get applicationCommandPermissionsV2(): boolean { - return this.has('applicationCommandPermissionsV2') + return this.has('applicationCommandPermissionsV2'); } /** Whether the guild has enabled monetization. */ get creatorMonetizableProvisional(): boolean { - return this.has('creatorMonetizableProvisional') + return this.has('creatorMonetizableProvisional'); } /** Whether the guild has enabled the role subscription promo page. */ get creatorStorePage(): boolean { - return this.has('creatorStorePage') + return this.has('creatorStorePage'); } /** Whether the guild has disabled alerts for join raids in the configured safety alerts channel */ get raidAlertsDisabled(): boolean { - return this.has('raidAlertsDisabled') + return this.has('raidAlertsDisabled'); } /** Whether the guild has role subscriptions that can be purchased. */ get roleSubscriptionsAvailableForPurchase(): boolean { - return this.has('roleSubscriptionsAvailableForPurchase') + return this.has('roleSubscriptionsAvailableForPurchase'); } /** Whether the guild has enabled role subscriptions. */ get roleSubscriptionsEnabled(): boolean { - return this.has('roleSubscriptionsEnabled') + return this.has('roleSubscriptionsEnabled'); } /** Whether the guild has created soundboard sounds. */ get soundboard(): boolean { - return this.has('soundboard') + return this.has('soundboard'); } /** Whether the guild has access to guest invites */ get guestsEnabled(): boolean { - return this.has('guestsEnabled') + return this.has('guestsEnabled'); } /** Whether the guild has access to set guild tags */ get guildTags(): boolean { - return this.has('guildTags') + return this.has('guildTags'); } /** Whether the guild is able to set gradient colors to roles */ get enhancedRoleColors(): boolean { - return this.has('enhancedRoleColors') + return this.has('enhancedRoleColors'); } /** Checks whether or not the permissions exist in this */ has(permissions: GuildToggleKeys | GuildToggleKeys[]): boolean { - if (!Array.isArray(permissions)) return super.contains(GuildToggle[permissions]) + if (!Array.isArray(permissions)) return super.contains(GuildToggle[permissions]); - return super.contains(permissions.reduce((a, b) => (a |= GuildToggle[b]), 0n)) + return super.contains(permissions.reduce((a, b) => (a |= GuildToggle[b]), 0n)); } /** Lists all the toggles for the role and whether or not each is true or false. */ list(): Record { - const json: Record = {} + const json: Record = {}; for (const [key, value] of Object.entries(GuildToggle)) { - json[key] = super.contains(value) + json[key] = super.contains(value); } - return json as Record + return json as Record; } } -export type GuildToggleKeys = keyof typeof GuildToggle +export type GuildToggleKeys = keyof typeof GuildToggle; -export type GuildFeatureKeys = (typeof guildFeatureNames)[number] +export type GuildFeatureKeys = (typeof guildFeatureNames)[number]; diff --git a/packages/bot/src/transformers/toggles/index.ts b/packages/bot/src/transformers/toggles/index.ts index 4c88d7d52..8f33a5306 100644 --- a/packages/bot/src/transformers/toggles/index.ts +++ b/packages/bot/src/transformers/toggles/index.ts @@ -1,9 +1,9 @@ -export * from './channel.js' -export * from './emoji.js' -export * from './guild.js' -export * from './member.js' -export * from './Permissions.js' -export * from './role.js' -export * from './ToggleBitfield.js' -export * from './user.js' -export * from './voice.js' +export * from './channel.js'; +export * from './emoji.js'; +export * from './guild.js'; +export * from './member.js'; +export * from './Permissions.js'; +export * from './role.js'; +export * from './ToggleBitfield.js'; +export * from './user.js'; +export * from './voice.js'; diff --git a/packages/bot/src/transformers/toggles/member.ts b/packages/bot/src/transformers/toggles/member.ts index 0e4efabbb..47753a4b1 100644 --- a/packages/bot/src/transformers/toggles/member.ts +++ b/packages/bot/src/transformers/toggles/member.ts @@ -1,8 +1,8 @@ -import { type DiscordMember, MemberFlags } from '@discordeno/types' -import { ToggleBitfield } from './ToggleBitfield.js' +import { type DiscordMember, MemberFlags } from '@discordeno/types'; +import { ToggleBitfield } from './ToggleBitfield.js'; /** @private This is subject to breaking changes without notices */ -export const memberFlags = ['didRejoin', 'startedOnboarding', 'bypassesVerification', 'completedOnboarding'] as const +export const memberFlags = ['didRejoin', 'startedOnboarding', 'bypassesVerification', 'completedOnboarding'] as const; export const MemberToggle = { /** Whether the user is deafened in voice channels */ @@ -34,135 +34,135 @@ export const MemberToggle = { dmSettingsUpsellAcknowledged: 1 << 11, /** Member's guild tag is blocked by AutoMod */ automodQuarantinedGuildTag: 1 << 12, -} +}; export class MemberToggles extends ToggleBitfield { constructor(memberOrTogglesInt: Partial | number) { - super() + super(); - if (typeof memberOrTogglesInt === 'number') this.bitfield = memberOrTogglesInt + if (typeof memberOrTogglesInt === 'number') this.bitfield = memberOrTogglesInt; else { - const member = memberOrTogglesInt + const member = memberOrTogglesInt; - if (member.deaf) this.add(MemberToggle.deaf) - if (member.mute) this.add(MemberToggle.mute) - if (member.pending) this.add(MemberToggle.pending) + if (member.deaf) this.add(MemberToggle.deaf); + if (member.mute) this.add(MemberToggle.mute); + if (member.pending) this.add(MemberToggle.pending); if (member.flags) { - if (member.flags & MemberFlags.DidRejoin) this.add(MemberToggle.didRejoin) - if (member.flags & MemberFlags.StartedOnboarding) this.add(MemberToggle.startedOnboarding) - if (member.flags & MemberFlags.BypassesVerification) this.add(MemberToggle.bypassesVerification) - if (member.flags & MemberFlags.CompletedOnboarding) this.add(MemberToggle.completedOnboarding) - if (member.flags & MemberFlags.IsGuest) this.add(MemberToggle.isGuest) - if (member.flags & MemberFlags.StartedHomeActions) this.add(MemberToggle.startedHomeActions) - if (member.flags & MemberFlags.CompletedHomeActions) this.add(MemberToggle.completedHomeActions) - if (member.flags & MemberFlags.AutomodQuarantinedUsername) this.add(MemberToggle.automodQuarantinedUsername) - if (member.flags & MemberFlags.DmSettingsUpsellAcknowledged) this.add(MemberToggle.dmSettingsUpsellAcknowledged) - if (member.flags & MemberFlags.AutomodQuarantinedGuildTag) this.add(MemberToggle.automodQuarantinedGuildTag) + if (member.flags & MemberFlags.DidRejoin) this.add(MemberToggle.didRejoin); + if (member.flags & MemberFlags.StartedOnboarding) this.add(MemberToggle.startedOnboarding); + if (member.flags & MemberFlags.BypassesVerification) this.add(MemberToggle.bypassesVerification); + if (member.flags & MemberFlags.CompletedOnboarding) this.add(MemberToggle.completedOnboarding); + if (member.flags & MemberFlags.IsGuest) this.add(MemberToggle.isGuest); + if (member.flags & MemberFlags.StartedHomeActions) this.add(MemberToggle.startedHomeActions); + if (member.flags & MemberFlags.CompletedHomeActions) this.add(MemberToggle.completedHomeActions); + if (member.flags & MemberFlags.AutomodQuarantinedUsername) this.add(MemberToggle.automodQuarantinedUsername); + if (member.flags & MemberFlags.DmSettingsUpsellAcknowledged) this.add(MemberToggle.dmSettingsUpsellAcknowledged); + if (member.flags & MemberFlags.AutomodQuarantinedGuildTag) this.add(MemberToggle.automodQuarantinedGuildTag); } } } get flags(): number { - let flags = 0 + let flags = 0; - if (this.didRejoin) flags |= MemberFlags.DidRejoin - if (this.startedOnboarding) flags |= MemberFlags.StartedOnboarding - if (this.bypassesVerification) flags |= MemberFlags.BypassesVerification - if (this.completedOnboarding) flags |= MemberFlags.CompletedOnboarding - if (this.isGuest) flags |= MemberFlags.IsGuest - if (this.startedHomeActions) flags |= MemberFlags.StartedHomeActions - if (this.completedHomeActions) flags |= MemberFlags.CompletedHomeActions - if (this.automodQuarantinedUsername) flags |= MemberFlags.AutomodQuarantinedUsername - if (this.dmSettingsUpsellAcknowledged) flags |= MemberFlags.DmSettingsUpsellAcknowledged - if (this.automodQuarantinedGuildTag) flags |= MemberFlags.AutomodQuarantinedGuildTag + if (this.didRejoin) flags |= MemberFlags.DidRejoin; + if (this.startedOnboarding) flags |= MemberFlags.StartedOnboarding; + if (this.bypassesVerification) flags |= MemberFlags.BypassesVerification; + if (this.completedOnboarding) flags |= MemberFlags.CompletedOnboarding; + if (this.isGuest) flags |= MemberFlags.IsGuest; + if (this.startedHomeActions) flags |= MemberFlags.StartedHomeActions; + if (this.completedHomeActions) flags |= MemberFlags.CompletedHomeActions; + if (this.automodQuarantinedUsername) flags |= MemberFlags.AutomodQuarantinedUsername; + if (this.dmSettingsUpsellAcknowledged) flags |= MemberFlags.DmSettingsUpsellAcknowledged; + if (this.automodQuarantinedGuildTag) flags |= MemberFlags.AutomodQuarantinedGuildTag; - return flags + return flags; } /** Whether the user belongs to an OAuth2 application */ get deaf(): boolean { - return this.has('deaf') + return this.has('deaf'); } /** Whether the user is muted in voice channels */ get mute(): boolean { - return this.has('mute') + return this.has('mute'); } /** Whether the user has not yet passed the guild's Membership Screening requirements */ get pending(): boolean { - return this.has('pending') + return this.has('pending'); } /** Member has left and rejoined the guild */ get didRejoin(): boolean { - return this.has('didRejoin') + return this.has('didRejoin'); } /** Member has completed onboarding */ get startedOnboarding(): boolean { - return this.has('startedOnboarding') + return this.has('startedOnboarding'); } /** Member is exempt from guild verification requirements */ get bypassesVerification(): boolean { - return this.has('bypassesVerification') + return this.has('bypassesVerification'); } /** Member has started onboarding */ get completedOnboarding(): boolean { - return this.has('completedOnboarding') + return this.has('completedOnboarding'); } /** Member is a guest and can only access the voice channel they were invited to */ get isGuest(): boolean { - return this.has('isGuest') + return this.has('isGuest'); } /** Member has started Server Guide new member actions */ get startedHomeActions(): boolean { - return this.has('startedHomeActions') + return this.has('startedHomeActions'); } /** Member has completed Server Guide new member actions */ get completedHomeActions(): boolean { - return this.has('completedHomeActions') + return this.has('completedHomeActions'); } /** Member's username, display name, or nickname is blocked by AutoMod */ get automodQuarantinedUsername(): boolean { - return this.has('automodQuarantinedUsername') + return this.has('automodQuarantinedUsername'); } /** Member has dismissed the DM settings upsell */ get dmSettingsUpsellAcknowledged(): boolean { - return this.has('dmSettingsUpsellAcknowledged') + return this.has('dmSettingsUpsellAcknowledged'); } /** Member's guild tag is blocked by AutoMod */ get automodQuarantinedGuildTag(): boolean { - return this.has('automodQuarantinedGuildTag') + return this.has('automodQuarantinedGuildTag'); } /** Checks whether or not the permissions exist in this */ has(permissions: MemberToggleKeys | MemberToggleKeys[]): boolean { - if (!Array.isArray(permissions)) return super.contains(MemberToggle[permissions]) + if (!Array.isArray(permissions)) return super.contains(MemberToggle[permissions]); - return super.contains(permissions.reduce((a, b) => (a |= MemberToggle[b]), 0)) + return super.contains(permissions.reduce((a, b) => (a |= MemberToggle[b]), 0)); } /** Lists all the toggles for the role and whether or not each is true or false. */ list(): Record { - const json: Record = {} + const json: Record = {}; for (const [key, value] of Object.entries(MemberToggle)) { - json[key] = super.contains(value) + json[key] = super.contains(value); } - return json as Record + return json as Record; } } -export type MemberToggleKeys = keyof typeof MemberToggle +export type MemberToggleKeys = keyof typeof MemberToggle; -export type MemberFlagsKeys = (typeof memberFlags)[number] +export type MemberFlagsKeys = (typeof memberFlags)[number]; diff --git a/packages/bot/src/transformers/toggles/role.ts b/packages/bot/src/transformers/toggles/role.ts index fe52c9cb7..3892e8a05 100644 --- a/packages/bot/src/transformers/toggles/role.ts +++ b/packages/bot/src/transformers/toggles/role.ts @@ -1,5 +1,5 @@ -import type { DiscordRole } from '@discordeno/types' -import { ToggleBitfield } from './ToggleBitfield.js' +import type { DiscordRole } from '@discordeno/types'; +import { ToggleBitfield } from './ToggleBitfield.js'; export const RoleToggle = { /** If this role is showed separately in the user listing */ @@ -14,71 +14,71 @@ export const RoleToggle = { availableForPurchase: 1 << 4, /** Whether this role is available for guild connections. */ guildConnections: 1 << 5, -} +}; export class RoleToggles extends ToggleBitfield { constructor(roleOrTogglesInt: DiscordRole | number) { - super() + super(); - if (typeof roleOrTogglesInt === 'number') this.bitfield = roleOrTogglesInt + if (typeof roleOrTogglesInt === 'number') this.bitfield = roleOrTogglesInt; else { - const role = roleOrTogglesInt + const role = roleOrTogglesInt; - if (role.hoist) this.add(RoleToggle.hoist) - if (role.managed) this.add(RoleToggle.managed) - if (role.mentionable) this.add(RoleToggle.mentionable) - if (role.tags?.premium_subscriber === null) this.add(RoleToggle.premiumSubscriber) - if (role.tags?.available_for_purchase === null) this.add(RoleToggle.availableForPurchase) - if (role.tags?.guild_connections === null) this.add(RoleToggle.guildConnections) + if (role.hoist) this.add(RoleToggle.hoist); + if (role.managed) this.add(RoleToggle.managed); + if (role.mentionable) this.add(RoleToggle.mentionable); + if (role.tags?.premium_subscriber === null) this.add(RoleToggle.premiumSubscriber); + if (role.tags?.available_for_purchase === null) this.add(RoleToggle.availableForPurchase); + if (role.tags?.guild_connections === null) this.add(RoleToggle.guildConnections); } } /** If this role is showed separately in the user listing */ get hoist(): boolean { - return this.has('hoist') + return this.has('hoist'); } /** Whether this role is managed by an integration */ get managed(): boolean { - return this.has('managed') + return this.has('managed'); } /** Whether this role is mentionable */ get mentionable(): boolean { - return this.has('mentionable') + return this.has('mentionable'); } /** Whether this is the guilds premium subscriber role */ get premiumSubscriber(): boolean { - return this.has('premiumSubscriber') + return this.has('premiumSubscriber'); } /** Whether this role is available for purchase. */ get availableForPurchase(): boolean { - return this.has('availableForPurchase') + return this.has('availableForPurchase'); } /** Whether this is a guild's linked role. */ get guildConnections(): boolean { - return this.has('guildConnections') + return this.has('guildConnections'); } /** Checks whether or not the permissions exist in this */ has(permissions: RoleToggleKeys | RoleToggleKeys[]): boolean { - if (!Array.isArray(permissions)) return super.contains(RoleToggle[permissions]) + if (!Array.isArray(permissions)) return super.contains(RoleToggle[permissions]); - return super.contains(permissions.reduce((a, b) => (a |= RoleToggle[b]), 0)) + return super.contains(permissions.reduce((a, b) => (a |= RoleToggle[b]), 0)); } /** Lists all the toggles for the role and whether or not each is true or false. */ list(): Record { - const json: Record = {} + const json: Record = {}; for (const [key, value] of Object.entries(RoleToggle)) { - json[key] = super.contains(value) + json[key] = super.contains(value); } - return json as Record + return json as Record; } } -export type RoleToggleKeys = keyof typeof RoleToggle +export type RoleToggleKeys = keyof typeof RoleToggle; diff --git a/packages/bot/src/transformers/toggles/user.ts b/packages/bot/src/transformers/toggles/user.ts index bd4690085..d8fdbdc7b 100644 --- a/packages/bot/src/transformers/toggles/user.ts +++ b/packages/bot/src/transformers/toggles/user.ts @@ -1,5 +1,5 @@ -import type { DiscordUser } from '@discordeno/types' -import { ToggleBitfield } from './ToggleBitfield.js' +import type { DiscordUser } from '@discordeno/types'; +import { ToggleBitfield } from './ToggleBitfield.js'; export const UserToggle = { /** Whether the user belongs to an OAuth2 application */ @@ -10,59 +10,59 @@ export const UserToggle = { mfaEnabled: 1 << 2, /** Whether the email on this account has been verified */ verified: 1 << 3, -} +}; export class UserToggles extends ToggleBitfield { constructor(userOrTogglesInt: DiscordUser | number) { - super() + super(); - if (typeof userOrTogglesInt === 'number') this.bitfield = userOrTogglesInt + if (typeof userOrTogglesInt === 'number') this.bitfield = userOrTogglesInt; else { - const user = userOrTogglesInt + const user = userOrTogglesInt; - if (user.bot) this.add(UserToggle.bot) - if (user.system) this.add(UserToggle.system) - if (user.mfa_enabled) this.add(UserToggle.mfaEnabled) - if (user.verified) this.add(UserToggle.verified) + if (user.bot) this.add(UserToggle.bot); + if (user.system) this.add(UserToggle.system); + if (user.mfa_enabled) this.add(UserToggle.mfaEnabled); + if (user.verified) this.add(UserToggle.verified); } } /** Whether the user belongs to an OAuth2 application */ get bot(): boolean { - return this.has('bot') + return this.has('bot'); } /** Whether the user is an Official Discord System user (part of the urgent message system) */ get system(): boolean { - return this.has('system') + return this.has('system'); } /** Whether the user has two factor enabled on their account */ get mfaEnabled(): boolean { - return this.has('mfaEnabled') + return this.has('mfaEnabled'); } /** Whether the email on this account has been verified */ get verified(): boolean { - return this.has('verified') + return this.has('verified'); } /** Checks whether or not the permissions exist in this */ has(permissions: UserToggleKeys | UserToggleKeys[]): boolean { - if (!Array.isArray(permissions)) return super.contains(UserToggle[permissions]) + if (!Array.isArray(permissions)) return super.contains(UserToggle[permissions]); - return super.contains(permissions.reduce((a, b) => (a |= UserToggle[b]), 0)) + return super.contains(permissions.reduce((a, b) => (a |= UserToggle[b]), 0)); } /** Lists all the toggles for the role and whether or not each is true or false. */ list(): Record { - const json: Record = {} + const json: Record = {}; for (const [key, value] of Object.entries(UserToggle)) { - json[key] = super.contains(value) + json[key] = super.contains(value); } - return json as Record + return json as Record; } } -export type UserToggleKeys = keyof typeof UserToggle +export type UserToggleKeys = keyof typeof UserToggle; diff --git a/packages/bot/src/transformers/toggles/voice.ts b/packages/bot/src/transformers/toggles/voice.ts index 7ad536d7e..20e6fb768 100644 --- a/packages/bot/src/transformers/toggles/voice.ts +++ b/packages/bot/src/transformers/toggles/voice.ts @@ -1,5 +1,5 @@ -import type { DiscordVoiceState } from '@discordeno/types' -import { ToggleBitfield } from './ToggleBitfield.js' +import type { DiscordVoiceState } from '@discordeno/types'; +import { ToggleBitfield } from './ToggleBitfield.js'; export const VoiceStateToggle = { /** Whether this user is deafened by the server */ @@ -16,77 +16,77 @@ export const VoiceStateToggle = { selfVideo: 1 << 5, /** Whether this user is muted by the current user */ suppress: 1 << 6, -} +}; export class VoiceStateToggles extends ToggleBitfield { constructor(voiceOrTogglesInt: DiscordVoiceState | number) { - super() + super(); - if (typeof voiceOrTogglesInt === 'number') this.bitfield = voiceOrTogglesInt + if (typeof voiceOrTogglesInt === 'number') this.bitfield = voiceOrTogglesInt; else { - const voice = voiceOrTogglesInt + const voice = voiceOrTogglesInt; - if (voice.deaf) this.add(VoiceStateToggle.deaf) - if (voice.mute) this.add(VoiceStateToggle.mute) - if (voice.self_deaf) this.add(VoiceStateToggle.selfDeaf) - if (voice.self_mute) this.add(VoiceStateToggle.selfMute) - if (voice.self_stream) this.add(VoiceStateToggle.selfStream) - if (voice.self_video) this.add(VoiceStateToggle.selfVideo) - if (voice.suppress) this.add(VoiceStateToggle.suppress) + if (voice.deaf) this.add(VoiceStateToggle.deaf); + if (voice.mute) this.add(VoiceStateToggle.mute); + if (voice.self_deaf) this.add(VoiceStateToggle.selfDeaf); + if (voice.self_mute) this.add(VoiceStateToggle.selfMute); + if (voice.self_stream) this.add(VoiceStateToggle.selfStream); + if (voice.self_video) this.add(VoiceStateToggle.selfVideo); + if (voice.suppress) this.add(VoiceStateToggle.suppress); } } /** Whether this user is deafened by the server */ get deaf(): boolean { - return this.has('deaf') + return this.has('deaf'); } /** Whether this user is muted by the server */ get mute(): boolean { - return this.has('mute') + return this.has('mute'); } /** Whether this user is locally deafened */ get selfDeaf(): boolean { - return this.has('selfDeaf') + return this.has('selfDeaf'); } /** Whether this user is locally muted */ get selfMute(): boolean { - return this.has('selfMute') + return this.has('selfMute'); } /** Whether this user is streaming using "Go Live" */ get selfStream(): boolean { - return this.has('selfStream') + return this.has('selfStream'); } /** Whether this user's camera is enabled */ get selfVideo(): boolean { - return this.has('selfVideo') + return this.has('selfVideo'); } /** Whether this user is muted by the current user */ get suppress(): boolean { - return this.has('suppress') + return this.has('suppress'); } /** Checks whether or not the permissions exist in this */ has(permissions: VoiceStateToggleKeys | VoiceStateToggleKeys[]): boolean { - if (!Array.isArray(permissions)) return super.contains(VoiceStateToggle[permissions]) + if (!Array.isArray(permissions)) return super.contains(VoiceStateToggle[permissions]); - return super.contains(permissions.reduce((a, b) => (a |= VoiceStateToggle[b]), 0)) + return super.contains(permissions.reduce((a, b) => (a |= VoiceStateToggle[b]), 0)); } /** Lists all the toggles for the role and whether or not each is true or false. */ list(): Record { - const json: Record = {} + const json: Record = {}; for (const [key, value] of Object.entries(VoiceStateToggle)) { - json[key] = super.contains(value) + json[key] = super.contains(value); } - return json as Record + return json as Record; } } -export type VoiceStateToggleKeys = keyof typeof VoiceStateToggle +export type VoiceStateToggleKeys = keyof typeof VoiceStateToggle; diff --git a/packages/bot/src/transformers/types.ts b/packages/bot/src/transformers/types.ts index a48bc6eca..17234c046 100644 --- a/packages/bot/src/transformers/types.ts +++ b/packages/bot/src/transformers/types.ts @@ -70,291 +70,291 @@ import type { VerificationLevels, VideoQualityModes, WebhookTypes, -} from '@discordeno/types' -import type { Collection, ImageOptions } from '@discordeno/utils' -import type { Bot } from '../bot.js' -import type { InteractionResolvedDataChannel, InteractionResolvedDataMember } from '../commandOptionsParser.js' -import type { DesiredPropertiesBehavior, TransformersDesiredProperties } from '../desiredProperties.js' -import type { ChannelToggles } from './toggles/channel.js' -import type { EmojiToggles } from './toggles/emoji.js' -import type { GuildFeatureKeys, GuildToggles } from './toggles/guild.js' -import type { MemberToggles } from './toggles/member.js' -import type { Permissions } from './toggles/Permissions.js' -import type { RoleToggles } from './toggles/role.js' -import type { ToggleBitfield } from './toggles/ToggleBitfield.js' -import type { UserToggles } from './toggles/user.js' -import type { VoiceStateToggles } from './toggles/voice.js' +} from '@discordeno/types'; +import type { Collection, ImageOptions } from '@discordeno/utils'; +import type { Bot } from '../bot.js'; +import type { InteractionResolvedDataChannel, InteractionResolvedDataMember } from '../commandOptionsParser.js'; +import type { DesiredPropertiesBehavior, TransformersDesiredProperties } from '../desiredProperties.js'; +import type { ChannelToggles } from './toggles/channel.js'; +import type { EmojiToggles } from './toggles/emoji.js'; +import type { GuildFeatureKeys, GuildToggles } from './toggles/guild.js'; +import type { MemberToggles } from './toggles/member.js'; +import type { Permissions } from './toggles/Permissions.js'; +import type { RoleToggles } from './toggles/role.js'; +import type { ToggleBitfield } from './toggles/ToggleBitfield.js'; +import type { UserToggles } from './toggles/user.js'; +import type { VoiceStateToggles } from './toggles/voice.js'; export interface Activity { - join?: string - flags?: number - applicationId?: bigint - spectate?: string - url?: string - startedAt?: number - endedAt?: number - details?: string - state?: string - emoji?: ActivityEmoji - partyId?: string - partyCurrentSize?: number - partyMaxSize?: number - largeImage?: string - largeText?: string - smallImage?: string - smallText?: string - inviteCoverImage?: string - match?: string - instance?: boolean - buttons?: ActivityButton[] - name: string - type: ActivityTypes - createdAt: number + join?: string; + flags?: number; + applicationId?: bigint; + spectate?: string; + url?: string; + startedAt?: number; + endedAt?: number; + details?: string; + state?: string; + emoji?: ActivityEmoji; + partyId?: string; + partyCurrentSize?: number; + partyMaxSize?: number; + largeImage?: string; + largeText?: string; + smallImage?: string; + smallText?: string; + inviteCoverImage?: string; + match?: string; + instance?: boolean; + buttons?: ActivityButton[]; + name: string; + type: ActivityTypes; + createdAt: number; } export interface ActivityEmoji { - id?: bigint - animated?: boolean - name: string + id?: bigint; + animated?: boolean; + name: string; } export interface ActivityButton { - url: string - label: string + url: string; + label: string; } export interface ActivityInstance { /** Application ID */ - applicationId: bigint + applicationId: bigint; /** Activity Instance ID */ - instanceId: string + instanceId: string; /** Unique identifier for the launch */ - launchId: bigint + launchId: bigint; /** The Location the instance is running in */ - location: ActivityLocation + location: ActivityLocation; /** The IDs of the Users currently connected to the instance */ - users: bigint[] + users: bigint[]; } export interface ActivityLocation { /** The unique identifier for the location */ - id: string + id: string; /** Enum describing kind of location */ - kind: DiscordActivityLocationKind + kind: DiscordActivityLocationKind; /** The id of the Channel */ - channelId: bigint + channelId: bigint; /** The id of the Guild */ - guildId?: bigint + guildId?: bigint; } export interface Application { - flags?: ApplicationFlags - icon?: bigint - rpcOrigins?: string[] - termsOfServiceUrl?: string - privacyPolicyUrl?: string - primarySkuId?: string - slug?: string - coverImage?: bigint - owner?: User - team?: Team - guildId?: bigint - guild?: Guild - id: bigint - name: string - description: string - botPublic: boolean - botRequireCodeGrant: boolean - verifyKey: string - customInstallUrl?: string - approximateGuildCount?: number - approximateUserInstallCount?: number - approximateUserAuthorizationCount?: number - installParams?: ApplicationInstallParams - bot?: User - redirectUris?: string[] - interactionsEndpointUrl?: string - integrationTypesConfig?: Partial> - roleConnectionsVerificationUrl: string - tags: string[] - eventWebhooksUrl?: string - eventWebhooksStatus: DiscordApplicationEventWebhookStatus - eventWebhooksTypes?: DiscordWebhookEventType[] + flags?: ApplicationFlags; + icon?: bigint; + rpcOrigins?: string[]; + termsOfServiceUrl?: string; + privacyPolicyUrl?: string; + primarySkuId?: string; + slug?: string; + coverImage?: bigint; + owner?: User; + team?: Team; + guildId?: bigint; + guild?: Guild; + id: bigint; + name: string; + description: string; + botPublic: boolean; + botRequireCodeGrant: boolean; + verifyKey: string; + customInstallUrl?: string; + approximateGuildCount?: number; + approximateUserInstallCount?: number; + approximateUserAuthorizationCount?: number; + installParams?: ApplicationInstallParams; + bot?: User; + redirectUris?: string[]; + interactionsEndpointUrl?: string; + integrationTypesConfig?: Partial>; + roleConnectionsVerificationUrl: string; + tags: string[]; + eventWebhooksUrl?: string; + eventWebhooksStatus: DiscordApplicationEventWebhookStatus; + eventWebhooksTypes?: DiscordWebhookEventType[]; } export interface ApplicationIntegrationTypeConfiguration { /** Install params for each installation context's default in-app authorization link */ - oauth2InstallParams?: ApplicationInstallParams + oauth2InstallParams?: ApplicationInstallParams; } export interface ApplicationInstallParams { /** Scopes to add the application to the server with */ - scopes: OAuth2Scope[] + scopes: OAuth2Scope[]; /** Permissions to request for the bot role */ - permissions: bigint + permissions: bigint; } export interface ApplicationCommand { - options?: ApplicationCommandOption[] - description: string - guildId?: bigint - nameLocalizations?: Localization - descriptionLocalizations?: Localization - defaultMemberPermissions?: bigint - type?: ApplicationCommandTypes - version: string - id: bigint - name: string - applicationId: bigint - dmPermission: boolean + options?: ApplicationCommandOption[]; + description: string; + guildId?: bigint; + nameLocalizations?: Localization; + descriptionLocalizations?: Localization; + defaultMemberPermissions?: bigint; + type?: ApplicationCommandTypes; + version: string; + id: bigint; + name: string; + applicationId: bigint; + dmPermission: boolean; } export interface ApplicationCommandOption { /** Value of Application Command Option Type */ - type: ApplicationCommandOptionTypes + type: ApplicationCommandOptionTypes; /** 1-32 character name matching lowercase `^[\w-]{1,32}$` */ - name: string + name: string; /** Localization object for the `name` field. Values follow the same restrictions as `name` */ - nameLocalizations?: Localization + nameLocalizations?: Localization; /** 1-100 character description */ - description: string + description: string; /** Localization object for the `description` field. Values follow the same restrictions as `description` */ - descriptionLocalizations?: Localization + descriptionLocalizations?: Localization; /** If the parameter is required or optional--default `false` */ - required?: boolean + required?: boolean; /** Choices for `string` and `int` types for the user to pick from */ - choices?: ApplicationCommandOptionChoice[] + choices?: ApplicationCommandOptionChoice[]; /** If the option is a subcommand or subcommand group type, this nested options will be the parameters */ - options?: ApplicationCommandOption[] + options?: ApplicationCommandOption[]; /** If the option is a channel type, the channels shown will be restricted to these types */ - channelTypes?: ChannelTypes[] + channelTypes?: ChannelTypes[]; /** Minimum number desired. */ - minValue?: number + minValue?: number; /** Maximum number desired. */ - maxValue?: number + maxValue?: number; /** Minimum length desired. */ - minLength?: number + minLength?: number; /** Maximum length desired. */ - maxLength?: number + maxLength?: number; /** if autocomplete interactions are enabled for this `String`, `Integer`, or `Number` type option */ - autocomplete?: boolean + autocomplete?: boolean; } export interface ApplicationCommandOptionChoice { - nameLocalizations?: Localization - name: string - value: string | number + nameLocalizations?: Localization; + name: string; + value: string | number; } export interface GuildApplicationCommandPermissions { - id: bigint - guildId: bigint - applicationId: bigint - permissions: ApplicationCommandPermissions[] + id: bigint; + guildId: bigint; + applicationId: bigint; + permissions: ApplicationCommandPermissions[]; } export interface ApplicationCommandPermissions { /** The id of the role or user */ - id: bigint + id: bigint; /** Role or User */ - type: ApplicationCommandPermissionTypes + type: ApplicationCommandPermissionTypes; /** `true` to allow, `false`, to disallow */ - permission: boolean + permission: boolean; } export interface Attachment { /** Name of file attached */ - filename: string + filename: string; /** The title of the file */ - title?: string + title?: string; /** The attachment's [media type](https://en.wikipedia.org/wiki/Media_type) */ - contentType?: string + contentType?: string; /** Size of file in bytes */ - size: number + size: number; /** Source url of file */ - url: string + url: string; /** A proxied url of file */ - proxyUrl: string + proxyUrl: string; /** Attachment id */ - id: bigint + id: bigint; /** description for the file (max 1024 characters) */ - description?: string + description?: string; /** Height of file (if image) */ - height?: number + height?: number; /** Width of file (if image) */ - width?: number + width?: number; /** whether this attachment is ephemeral. Ephemeral attachments will automatically be removed after a set period of time. Ephemeral attachments on messages are guaranteed to be available as long as the message itself exists. */ - ephemeral?: boolean + ephemeral?: boolean; /** The duration of the audio file for a voice message */ - duration_secs?: number + duration_secs?: number; /** A base64 encoded bytearray representing a sampled waveform for a voice message */ - waveform?: string + waveform?: string; /** Attachment flags combined as a bitfield */ - flags?: AttachmentFlags + flags?: AttachmentFlags; } export interface AuditLogEntry { - id: bigint - userId?: bigint - reason?: string - changes?: Camelize[] - targetId?: bigint - actionType: AuditLogEvents - options?: OptionalAuditEntryInfo + id: bigint; + userId?: bigint; + reason?: string; + changes?: Camelize[]; + targetId?: bigint; + actionType: AuditLogEvents; + options?: OptionalAuditEntryInfo; } export interface OptionalAuditEntryInfo { - applicationId?: bigint - autoModerationRuleName?: string - autoModerationRuleTriggerType?: string - channelId?: bigint - count?: number - deleteMemberDays?: number - id?: bigint - membersRemoved?: number - messageId?: bigint - roleName?: string - type?: number - integrationType?: string + applicationId?: bigint; + autoModerationRuleName?: string; + autoModerationRuleTriggerType?: string; + channelId?: bigint; + count?: number; + deleteMemberDays?: number; + id?: bigint; + membersRemoved?: number; + messageId?: bigint; + roleName?: string; + type?: number; + integrationType?: string; } export interface AutoModerationActionExecution { - channelId?: bigint - messageId?: bigint - alertSystemMessageId?: bigint - guildId: bigint - userId: bigint - content: string - action: AutoModerationAction - ruleTriggerType: AutoModerationTriggerTypes - ruleId: bigint - matchedKeyword: string - matchedContent: string + channelId?: bigint; + messageId?: bigint; + alertSystemMessageId?: bigint; + guildId: bigint; + userId: bigint; + content: string; + action: AutoModerationAction; + ruleTriggerType: AutoModerationTriggerTypes; + ruleId: bigint; + matchedKeyword: string; + matchedContent: string; } export interface AutoModerationAction { - type: AutoModerationActionType - metadata?: AutoModerationActionMetadata + type: AutoModerationActionType; + metadata?: AutoModerationActionMetadata; } export interface AutoModerationActionMetadata { - customMessage?: string - durationSeconds?: number - channelId?: bigint + customMessage?: string; + durationSeconds?: number; + channelId?: bigint; } export interface AutoModerationRule { - triggerMetadata?: AutoModerationRuleTriggerMetadata - id: bigint - name: string - guildId: bigint - eventType: AutoModerationEventTypes - triggerType: AutoModerationTriggerTypes - enabled: boolean - creatorId: bigint - exemptRoles: bigint[] - exemptChannels: bigint[] - actions: AutoModerationAction[] + triggerMetadata?: AutoModerationRuleTriggerMetadata; + id: bigint; + name: string; + guildId: bigint; + eventType: AutoModerationEventTypes; + triggerType: AutoModerationTriggerTypes; + enabled: boolean; + creatorId: bigint; + exemptRoles: bigint[]; + exemptChannels: bigint[]; + actions: AutoModerationAction[]; } export interface AutoModerationRuleTriggerMetadata { @@ -366,7 +366,7 @@ export interface AutoModerationRuleTriggerMetadata { * * Can have up to 1000 elements in the array and each string can have up to 60 characters. */ - keywordFilter?: string[] + keywordFilter?: string[]; /** * Regular expression patterns which will be matched against content. * @@ -375,14 +375,14 @@ export interface AutoModerationRuleTriggerMetadata { * * Only Rust flavored regex is currently supported. Can have up to 10 elements in the array and each string can have up to 260 characters. */ - regexPatterns?: string[] + regexPatterns?: string[]; /** * The Discord pre-defined wordsets which will be searched for in content. * * @remarks * Only present with {@link AutoModerationTriggerTypes.KeywordPreset}. */ - presets?: DiscordAutoModerationRuleTriggerMetadataPresets[] + presets?: DiscordAutoModerationRuleTriggerMetadataPresets[]; /** * The substrings which should not trigger the rule. * @@ -392,7 +392,7 @@ export interface AutoModerationRuleTriggerMetadata { * When used with {@link AutoModerationTriggerTypes.Keyword} and {@link AutoModerationTriggerTypes.MemberProfile}, there can be up to 100 elements in the array and each string can have up to 60 characters. * When used with {@link AutoModerationTriggerTypes.KeywordPreset}, there can be up to 1000 elements in the array and each string can have up to 60 characters. */ - allowList?: string[] + allowList?: string[]; /** * Total number of unique role and user mentions allowed per message. * @@ -401,129 +401,129 @@ export interface AutoModerationRuleTriggerMetadata { * * Maximum of 50 */ - mentionTotalLimit?: number + mentionTotalLimit?: number; /** * Whether to automatically detect mention raids. * * @remarks * Only present with {@link AutoModerationTriggerTypes.MentionSpam}. */ - mentionRaidProtectionEnabled?: boolean + mentionRaidProtectionEnabled?: boolean; } export interface AvatarDecorationData { /** the avatar decoration hash */ - asset: bigint + asset: bigint; /** id of the avatar decoration's SKU */ - skuId: bigint + skuId: bigint; } export interface Channel { /** The id of the channel */ - id: bigint + id: bigint; /** The compressed form of all the boolean values on this channel. */ - toggles: ChannelToggles + toggles: ChannelToggles; /** The type of channel */ - type: ChannelTypes + type: ChannelTypes; /** The id of the guild */ - guildId?: bigint + guildId?: bigint; /** Sorting position of the channel */ - position?: number + position?: number; /** The name of the channel (1-100 characters) */ - name?: string + name?: string; /** The channel topic (0-4096 characters for GUILD_FORUM channels, 0-1024 characters for all others) */ - topic?: string + topic?: string; /** The id of the last message sent in this channel (may not point to an existing or valid message) */ - lastMessageId?: bigint + lastMessageId?: bigint; /** The bitrate (in bits) of the voice or stage channel */ - bitrate?: number + bitrate?: number; /** The user limit of the voice or stage channel */ - userLimit?: number + userLimit?: number; /** Amount of seconds a user has to wait before sending another message (0-21600); bots, as well as users with the permission `manage_messages` or `manage_channel`, are unaffected */ - rateLimitPerUser?: number + rateLimitPerUser?: number; /** Id of the creator of the thread */ - ownerId?: bigint + ownerId?: bigint; /** For guild channels: Id of the parent category for a channel (each parent category can contain up to 50 channels), for threads: id of the text channel this thread was created */ - parentId?: bigint + parentId?: bigint; /** When the last pinned message was pinned. This may be null in events such as GUILD_CREATE when a message is not pinned. */ - lastPinTimestamp?: number + lastPinTimestamp?: number; /** Voice region id for the voice or stage channel, automatic when set to null */ - rtcRegion?: string + rtcRegion?: string; /** The camera video quality mode of the voice channel, 1 when not present */ - videoQualityMode?: VideoQualityModes + videoQualityMode?: VideoQualityModes; /** An approximate count of messages in a thread, stops counting at 50 */ - messageCount?: number + messageCount?: number; /** An approximate count of users in a thread, stops counting at 50 */ - memberCount?: number + memberCount?: number; /** * Thread-specific fields not needed by other channels. * * @private * This field is an internal field, subject to breaking changes. */ - internalThreadMetadata?: InternalChannelThreadMetadata - member?: ThreadMember + internalThreadMetadata?: InternalChannelThreadMetadata; + member?: ThreadMember; /** Default duration for newly created threads, in minutes, to automatically archive the thread after recent activity, can be set to: 60, 1440, 4320, 10080 */ - defaultAutoArchiveDuration?: number + defaultAutoArchiveDuration?: number; /** computed permissions for the invoking user in the channel, including overwrites, only included when part of the resolved data received on an interaction. This does not include implicit permissions, which may need to be checked separately. */ - permissions?: Permissions + permissions?: Permissions; /** The flags of the channel */ - flags?: number + flags?: number; /** * Explicit permission overwrites for members and roles * * @private * Use channel.permissionOverwrites. This is for internal use only, and prone to breaking changes. */ - internalOverwrites?: bigint[] + internalOverwrites?: bigint[]; /** The recipients of a group dm */ - recipients?: User[] + recipients?: User[]; /** Icon hash of the group dm */ - icon?: bigint + icon?: bigint; /** Application id of the group DM creator if it is bot-created */ - applicationId?: bigint + applicationId?: bigint; /** Number of messages ever sent in a thread, it's similar to `message_count` on message creation, but will not decrement the number when a message is deleted */ - totalMessageSent?: number + totalMessageSent?: number; /** The set of tags that can be used in a `GUILD_FORUM` or a `GUILD_MEDIA` channel */ - availableTags?: ForumTag[] + availableTags?: ForumTag[]; /** The IDs of the set of tags that have been applied to a thread in a `GUILD_FORUM` or a `GUILD_MEDIA` channel */ - appliedTags?: bigint[] + appliedTags?: bigint[]; /** The emoji to show in the add reaction button on a thread in a `GUILD_FORUM` or a `GUILD_MEDIA` channel */ - defaultReactionEmoji?: DefaultReactionEmoji + defaultReactionEmoji?: DefaultReactionEmoji; /** the initial `rateLimitPerUser` to set on newly created threads in a channel. this field is copied to the thread at creation time and does not live update. */ - defaultThreadRateLimitPerUser?: number + defaultThreadRateLimitPerUser?: number; /** The default sort order type used to order posts in `GUILD_FORUM` and `GUILD_MEDIA` channels. Defaults to null, which indicates a preferred sort order hasn't been set by a channel admin */ - defaultSortOrder?: SortOrderTypes | null - defaultForumLayout?: ForumLayout + defaultSortOrder?: SortOrderTypes | null; + defaultForumLayout?: ForumLayout; /** Whether the channel is nsfw */ - nsfw: boolean + nsfw: boolean; /** Thread-specific fields not needed by other channels */ - threadMetadata?: ChannelThreadMetadata + threadMetadata?: ChannelThreadMetadata; /** When a thread is created this will be true on that channel payload for the thread. */ - newlyCreated: boolean + newlyCreated: boolean; /** When a thread is locked, only users with `MANAGE_THREADS` can unarchive it */ - locked: boolean + locked: boolean; /** whether non-moderators can add other non-moderators to a thread; only available on private threads */ - invitable: boolean + invitable: boolean; /** Whether the thread is archived */ - archived: boolean + archived: boolean; /** for group DM channels: whether the channel is managed by an application via the `gdm.join` OAuth2 scope */ - managed: boolean + managed: boolean; /** Explicit permission overwrites for members and roles. */ - permissionOverwrites: Overwrite[] + permissionOverwrites: Overwrite[]; } export interface ForumTag { /** The id of the tag */ - id: bigint + id: bigint; /** The name of the tag (0-20 characters) */ - name: string + name: string; /** Whether this tag can only be added to or removed from threads by a member with the MANAGE_THREADS permission */ - moderated: boolean + moderated: boolean; /** The id of a guild's custom emoji At most one of emoji_id and emoji_name may be set. */ - emojiId: bigint + emojiId: bigint; /** The unicode character of the emoji */ - emojiName: string | null + emojiName: string | null; } /** @@ -532,458 +532,458 @@ export interface ForumTag { */ export interface InternalChannelThreadMetadata { /** Timestamp when the thread's archive status was last changed, used for calculating recent activity */ - archiveTimestamp: number + archiveTimestamp: number; /** Timestamp when the thread was created; only populated for threads created after 2022-01-09 */ - createTimestamp?: number + createTimestamp?: number; /** Duration in minutes to automatically archive the thread after recent activity */ - autoArchiveDuration: 60 | 1440 | 4320 | 10080 + autoArchiveDuration: 60 | 1440 | 4320 | 10080; } export interface ChannelThreadMetadata { /** Timestamp when the thread's archive status was last changed, used for calculating recent activity */ - archiveTimestamp?: number + archiveTimestamp?: number; /** Timestamp when the thread was created; only populated for threads created after 2022-01-09 */ - createTimestamp?: number + createTimestamp?: number; /** Duration in minutes to automatically archive the thread after recent activity */ - autoArchiveDuration?: 60 | 1440 | 4320 | 10080 + autoArchiveDuration?: 60 | 1440 | 4320 | 10080; /** When a thread is locked, only users with `MANAGE_THREADS` can unarchive it */ - locked: boolean + locked: boolean; /** whether non-moderators can add other non-moderators to a thread; only available on private threads */ - invitable: boolean + invitable: boolean; /** Whether the thread is archived */ - archived: boolean + archived: boolean; } export interface Component { /** component type */ - type: MessageComponentTypes + type: MessageComponentTypes; /** a developer-defined identifier for the component, max 100 characters */ - customId?: string + customId?: string; /** whether this component is required to be filled, default true */ - required?: boolean + required?: boolean; /** whether the component is disabled, default false */ - disabled?: boolean + disabled?: boolean; /** For different styles/colors of the buttons */ - style?: ButtonStyles | TextStyles + style?: ButtonStyles | TextStyles; /** text that appears on the button (max 80 characters) */ - label?: string + label?: string; /** the dev-define value of the option, max 100 characters for select or 4000 for input. */ - value?: string + value?: string; /** Emoji object that includes fields of name, id, and animated supporting unicode and custom emojis. */ - emoji?: Pick, 'id' | 'name' | 'animated'> + emoji?: Pick, 'id' | 'name' | 'animated'>; /** optional url for link-style buttons that can navigate a user to the web. Only type 5 Link buttons can have a url */ - url?: string + url?: string; /** List of channel types to include in a channel select menu options list */ - channelTypes?: ChannelTypes[] + channelTypes?: ChannelTypes[]; /** The choices! Maximum of 25 items. */ - options?: SelectOption[] + options?: SelectOption[]; /** A custom placeholder text if nothing is selected. Maximum 150 characters. */ - placeholder?: string + placeholder?: string; /** The minimum number of items that must be selected. Default 1. Between 1-25. */ - minValues?: number + minValues?: number; /** The maximum number of items that can be selected. Default 1. Between 1-25. */ - maxValues?: number + maxValues?: number; /** The minimum input length for a text input. Between 0-4000. */ - minLength?: number + minLength?: number; /** The maximum input length for a text input. Between 1-4000. */ - maxLength?: number + maxLength?: number; /** a list of child components */ - components?: Component[] + components?: Component[]; /** List of default values for auto-populated select menu components; number of default values must be in the range defined by min_values and max_values */ - defaultValues?: DiscordComponentDefaultValue[] + defaultValues?: DiscordComponentDefaultValue[]; /** Identifier for a purchasable SKU, only available when using premium-style buttons */ - skuId?: bigint + skuId?: bigint; /** Optional identifier for component */ - id?: number + id?: number; /** A thumbnail or a button component, with a future possibility of adding more compatible components */ - accessory?: Component + accessory?: Component; /** Text that will be displayed similar to a message */ - content?: string + content?: string; /** Alt text for the media */ - description?: string + description?: string; /** Whether the thumbnail should be a spoiler (or blurred out). Defaults to `false` */ - spoiler?: boolean + spoiler?: boolean; /** 1 to 10 media gallery items */ - items?: MediaGalleryItem[] + items?: MediaGalleryItem[]; /** Whether a visual divider should be displayed in the component. Defaults to `true` */ - divider?: boolean + divider?: boolean; /** Size of separator padding — `1` for small padding, `2` for large padding. Defaults to `1` */ - spacing?: SeparatorSpacingSize + spacing?: SeparatorSpacingSize; /** This unfurled media item is unique in that it only supports attachment references using the attachment:// syntax */ - file?: UnfurledMediaItem + file?: UnfurledMediaItem; /** This unfurled media item is unique in that it only supports attachment references using the attachment:// syntax */ - media?: UnfurledMediaItem + media?: UnfurledMediaItem; /** Color for the accent on the container as RGB from 0x000000 to 0xFFFFFF */ - accentColor?: number + accentColor?: number; /** The name of the file. This field is ignored and provided by the API as part of the response */ - name?: string + name?: string; /** The size of the file in bytes. This field is ignored and provided by the API as part of the response */ - size?: number + size?: number; /** The component within the label */ - component?: Component + component?: Component; /** The text of the selected options */ - values?: string[] + values?: string[]; } export interface UnfurledMediaItem { /** Supports arbitrary urls and attachment:// references */ - url: string + url: string; /** The proxied url of the media item. This field is ignored and provided by the API as part of the response */ - proxyUrl?: string + proxyUrl?: string; /** The height of the media item. This field is ignored and provided by the API as part of the response */ - height?: number | null + height?: number | null; /** The width of the media item. This field is ignored and provided by the API as part of the response */ - width?: number | null + width?: number | null; /** The media type of the content. This field is ignored and provided by the API as part of the response */ - contentType?: string + contentType?: string; /** The id of the uploaded attachment. Only present if the media was uploaded as an attachment. This field is ignored and provided by the API as part of the response */ - attachmentId?: bigint + attachmentId?: bigint; } export interface MediaGalleryItem { /** A url or attachment */ - media: UnfurledMediaItem + media: UnfurledMediaItem; /** Alt text for the media */ - description?: string + description?: string; /** Whether the media should be a spoiler (or blurred out). Defaults to `false` */ - spoiler?: boolean + spoiler?: boolean; } export interface DiscordComponentDefaultValue { /** ID of a user, role, or channel */ - id: bigint + id: bigint; /** Type of value that id represents. */ - type: 'user' | 'role' | 'channel' + type: 'user' | 'role' | 'channel'; } export interface Embed { - description?: string - type?: EmbedTypes - url?: string - image?: EmbedImage - video?: EmbedVideo - title?: string - timestamp?: number - color?: number - footer?: EmbedFooter - thumbnail?: EmbedThumbnail - provider?: EmbedProvider - author?: EmbedAuthor - fields?: EmbedField[] + description?: string; + type?: EmbedTypes; + url?: string; + image?: EmbedImage; + video?: EmbedVideo; + title?: string; + timestamp?: number; + color?: number; + footer?: EmbedFooter; + thumbnail?: EmbedThumbnail; + provider?: EmbedProvider; + author?: EmbedAuthor; + fields?: EmbedField[]; } export interface EmbedImage { - proxyUrl?: string - height?: number - width?: number - url: string + proxyUrl?: string; + height?: number; + width?: number; + url: string; } export interface EmbedVideo { - url?: string - proxyUrl?: string - height?: number - width?: number + url?: string; + proxyUrl?: string; + height?: number; + width?: number; } export interface EmbedFooter { - iconUrl?: string - proxyIconUrl?: string - text: string + iconUrl?: string; + proxyIconUrl?: string; + text: string; } export interface EmbedThumbnail { - proxyUrl?: string - height?: number - width?: number - url: string + proxyUrl?: string; + height?: number; + width?: number; + url: string; } export interface EmbedProvider { - name?: string - url?: string + name?: string; + url?: string; } export interface EmbedAuthor { - url?: string - iconUrl?: string - proxyIconUrl?: string - name: string + url?: string; + iconUrl?: string; + proxyIconUrl?: string; + name: string; } export interface EmbedField { - inline?: boolean - name: string - value: string + inline?: boolean; + name: string; + value: string; } export interface Emoji { /** Emoji name (can only be null in reaction emoji objects) */ - name?: string + name?: string; /** Emoji id */ - id?: bigint + id?: bigint; /** Roles allowed to use this emoji */ - roles?: bigint[] + roles?: bigint[]; /** User that created this emoji */ - user?: User + user?: User; /** Whether this emoji must be wrapped in colons */ - requireColons?: boolean + requireColons?: boolean; /** Whether this emoji is managed */ - managed?: boolean + managed?: boolean; /** Whether this emoji is animated */ - animated?: boolean + animated?: boolean; /** Whether this emoji can be used, may be false due to loss of Server Boosts */ - available?: boolean - toggles: EmojiToggles + available?: boolean; + toggles: EmojiToggles; } export interface DefaultReactionEmoji { /** The id of a guild's custom emoji */ - emojiId: bigint + emojiId: bigint; /** The unicode character of the emoji */ - emojiName?: string + emojiName?: string; } export interface Entitlement { /** ID of the entitlement */ - id: bigint + id: bigint; /** ID of the SKU */ - skuId: bigint + skuId: bigint; /** ID of the user that is granted access to the entitlement's sku */ - userId?: bigint + userId?: bigint; /** ID of the guild that is granted access to the entitlement's sku */ - guildId?: bigint + guildId?: bigint; /** ID of the parent application */ - applicationId: bigint + applicationId: bigint; /** Type of entitlement */ - type: DiscordEntitlementType + type: DiscordEntitlementType; /** Entitlement was deleted */ - deleted: boolean + deleted: boolean; /** Start date at which the entitlement is valid. */ - startsAt?: number + startsAt?: number; /** Date at which the entitlement is no longer valid. */ - endsAt?: number + endsAt?: number; /** For consumable items, whether or not the entitlement has been consumed */ - consumed?: boolean + consumed?: boolean; } export interface GetGatewayBot { - url: string - shards: number - sessionStartLimit: SessionStartLimit + url: string; + shards: number; + sessionStartLimit: SessionStartLimit; } export interface SessionStartLimit { - total: number - remaining: number - resetAfter: number - maxConcurrency: number + total: number; + remaining: number; + resetAfter: number; + maxConcurrency: number; } export interface Guild { /** Guild name (2-100 characters, excluding trailing and leading whitespace) */ - name: string + name: string; /** True if the user is the owner of the guild */ - owner?: boolean + owner?: boolean; /** Afk timeout in seconds */ - afkTimeout: number + afkTimeout: number; /** True if the server widget is enabled */ - widgetEnabled?: boolean + widgetEnabled?: boolean; /** Verification level required for the guild */ - verificationLevel: VerificationLevels + verificationLevel: VerificationLevels; /** Default message notifications level */ - defaultMessageNotifications: DefaultMessageNotificationLevels + defaultMessageNotifications: DefaultMessageNotificationLevels; /** Explicit content filter level */ - explicitContentFilter: ExplicitContentFilterLevels + explicitContentFilter: ExplicitContentFilterLevels; /** Enabled guild features */ - features: GuildFeatureKeys[] + features: GuildFeatureKeys[]; /** Required MFA level for the guild */ - mfaLevel: MfaLevels + mfaLevel: MfaLevels; /** System channel flags */ - systemChannelFlags: SystemChannelFlags + systemChannelFlags: SystemChannelFlags; /** True if this is considered a large guild */ - large?: boolean + large?: boolean; /** True if this guild is unavailable due to an outage */ - unavailable?: boolean + unavailable?: boolean; /** Total number of members in this guild */ - memberCount: number + memberCount: number; /** The maximum number of presences for the guild (the default value, currently 25000, is in effect when null is returned) */ - maxPresences?: number + maxPresences?: number; /** The maximum number of members for the guild */ - maxMembers?: number + maxMembers?: number; /** The vanity url code for the guild */ - vanityUrlCode?: string + vanityUrlCode?: string; /** The description of a guild */ - description?: string - toggles: GuildToggles - shardId: number + description?: string; + toggles: GuildToggles; + shardId: number; /** Premium tier (Server Boost level) */ - premiumTier: PremiumTiers + premiumTier: PremiumTiers; /** The number of boosts this guild currently has */ - premiumSubscriptionCount?: number + premiumSubscriptionCount?: number; /** The maximum amount of users in a video channel */ - maxVideoChannelUsers?: number + maxVideoChannelUsers?: number; /** Maximum amount of users in a stage video channel */ - maxStageVideoChannelUsers?: number + maxStageVideoChannelUsers?: number; /** Approximate number of members in this guild, returned from the GET /guilds/id endpoint when with_counts is true */ - approximateMemberCount?: number + approximateMemberCount?: number; /** Approximate number of non-offline members in this guild, returned from the GET /guilds/id endpoint when with_counts is true */ - approximatePresenceCount?: number + approximatePresenceCount?: number; /** Guild NSFW level */ - nsfwLevel: GuildNsfwLevel + nsfwLevel: GuildNsfwLevel; /** Whether the guild has the boost progress bar enabled */ - premiumProgressBarEnabled: boolean + premiumProgressBarEnabled: boolean; /** Guild id */ - id: bigint + id: bigint; /** Icon hash */ - icon?: bigint + icon?: bigint; /** Icon hash, returned when in the template object */ - iconHash?: bigint + iconHash?: bigint; /** Splash hash */ - splash?: bigint + splash?: bigint; /** Discovery splash hash; only present for guilds with the "DISCOVERABLE" feature */ - discoverySplash?: bigint + discoverySplash?: bigint; /** Id of the owner */ - ownerId: bigint + ownerId: bigint; /** Total permissions for the user in the guild (excludes overwrites and implicit permissions) */ - permissions: bigint + permissions: bigint; /** Id of afk channel */ - afkChannelId?: bigint + afkChannelId?: bigint; /** The channel id that the widget will generate an invite to, or null if set to no invite */ - widgetChannelId?: bigint + widgetChannelId?: bigint; /** Roles in the guild */ - roles: Collection + roles: Collection; /** Custom guild emojis */ - emojis: Collection + emojis: Collection; /** Application id of the guild creator if it is bot-created */ - applicationId?: bigint + applicationId?: bigint; /** The id of the channel where guild notices such as welcome messages and boost events are posted */ - systemChannelId?: bigint + systemChannelId?: bigint; /** The id of the channel where community guilds can display rules and/or guidelines */ - rulesChannelId?: bigint + rulesChannelId?: bigint; /** When this guild was joined at */ - joinedAt?: number + joinedAt?: number; /** States of members currently in voice channels; lacks the guild_id key */ - voiceStates: Collection + voiceStates: Collection; /** Users in the guild */ - members: Collection + members: Collection; /** Channels in the guild */ - channels: Collection + channels: Collection; /** All active threads in the guild that the current user has permission to view */ - threads: Collection + threads: Collection; /** Presences of the members in the guild, will only include non-offline members if the size is greater than large threshold */ - presences?: PresenceUpdate[] + presences?: PresenceUpdate[]; /** Banner hash */ - banner?: bigint + banner?: bigint; /** The preferred locale of a Community guild; used in server discovery and notices from Discord; defaults to "en-US" */ - preferredLocale: string + preferredLocale: string; /** The id of the channel where admins and moderators of Community guilds receive notices from Discord */ - publicUpdatesChannelId?: bigint + publicUpdatesChannelId?: bigint; /** The welcome screen of a Community guild, shown to new members, returned in an Invite's guild object */ - welcomeScreen?: WelcomeScreen + welcomeScreen?: WelcomeScreen; /** Stage instances in the guild */ - stageInstances?: StageInstance[] + stageInstances?: StageInstance[]; /** Custom guild stickers */ - stickers?: Collection + stickers?: Collection; /** The id of the channel where admins and moderators of Community guilds receive safety alerts from Discord */ - safetyAlertsChannelId?: bigint + safetyAlertsChannelId?: bigint; /** The incidents data for this guild */ - incidentsData: IncidentsData + incidentsData: IncidentsData; } export interface IncidentsData { /** When invites get enabled again */ - invitesDisabledUntil?: number + invitesDisabledUntil?: number; /** When direct messages get enabled again */ - dmsDisabledUntil?: number + dmsDisabledUntil?: number; /** When the dm spam was detected */ - dmSpamDetectedAt?: number + dmSpamDetectedAt?: number; /** When the raid was detected */ - raidDetectedAt?: number + raidDetectedAt?: number; } export interface Integration { - user?: User - enabled?: boolean - syncing?: boolean - roleId?: bigint - enableEmoticons?: boolean - expireBehavior?: IntegrationExpireBehaviors - expireGracePeriod?: number - syncedAt?: number - subscriberCount?: number - revoked?: boolean - application?: IntegrationApplication - id: bigint - name: string - guildId: bigint - type: 'twitch' | 'youtube' | 'discord' - account: IntegrationAccount - scopes: OAuth2Scope[] + user?: User; + enabled?: boolean; + syncing?: boolean; + roleId?: bigint; + enableEmoticons?: boolean; + expireBehavior?: IntegrationExpireBehaviors; + expireGracePeriod?: number; + syncedAt?: number; + subscriberCount?: number; + revoked?: boolean; + application?: IntegrationApplication; + id: bigint; + name: string; + guildId: bigint; + type: 'twitch' | 'youtube' | 'discord'; + account: IntegrationAccount; + scopes: OAuth2Scope[]; } export interface IntegrationApplication { - bot?: User - icon?: bigint - id: bigint - name: string - description: string + bot?: User; + icon?: bigint; + id: bigint; + name: string; + description: string; } export interface IntegrationAccount { - id: bigint - name: string + id: bigint; + name: string; } export interface Interaction { /** The bot object */ - bot: Bot + bot: Bot; /** Whether or not this interaction has been responded to. */ - acknowledged: boolean + acknowledged: boolean; /** Id of the interaction */ - id: bigint + id: bigint; /** Id of the application this interaction is for */ - applicationId: bigint + applicationId: bigint; /** The type of interaction */ - type: InteractionTypes + type: InteractionTypes; /** Guild that the interaction was sent from */ - guild?: Partial + guild?: Partial; /** The guild it was sent from */ - guildId?: bigint + guildId?: bigint; /** The channel it was sent from */ - channel: Partial + channel: Partial; /** * The ID of channel it was sent from * * @remarks * It is recommended that you begin using this channel field to identify the source channel of the interaction as they may deprecate the existing channel_id field in the future. */ - channelId?: bigint + channelId?: bigint; /** Guild member data for the invoking user, including permissions */ - member?: Member + member?: Member; /** User object for the invoking user, if invoked in a DM */ - user: User + user: User; /** A continuation token for responding to the interaction */ - token: string + token: string; /** Read-only property, always `1` */ - version: 1 + version: 1; /** For components or modals triggered by components, the message they were attached to */ - message?: Message + message?: Message; /** the command data payload */ - data?: InteractionData - locale?: string + data?: InteractionData; + locale?: string; /** The guild's preferred locale, if invoked in a guild */ - guildLocale?: string + guildLocale?: string; /** For monetized apps, any entitlements for the invoking user, representing access to premium SKUs */ - entitlements: Entitlement[] + entitlements: Entitlement[]; /** The computed permissions for a bot or app in the context of a specific interaction (including channel overwrites) */ - appPermissions: bigint + appPermissions: bigint; /** Mapping of installation contexts that the interaction was authorized for to related user or guild IDs. */ - authorizingIntegrationOwners: Partial> + authorizingIntegrationOwners: Partial>; /** Context where the interaction was triggered from */ - context?: DiscordInteractionContextType + context?: DiscordInteractionContextType; /** Attachment size limit in bytes */ - attachmentSizeLimit: number + attachmentSizeLimit: number; /** * Sends a response to an interaction. * @@ -994,8 +994,8 @@ export interface Interaction { */ respond: ( response: string | InteractionCallbackData, - options?: { isPrivate?: boolean; withResponse?: boolean }, - ) => Promise + options?: { isPrivate?: boolean; withResponse?: boolean; type?: InteractionResponseTypes }, + ) => Promise; /** * Edit the original response of an interaction or a followup if the message id is provided. * @@ -1006,281 +1006,281 @@ export interface Interaction { response: string | InteractionCallbackData, messageId?: BigString, options?: InteractionCallbackOptions, - ) => Promise + ) => Promise; /** * Defer the interaction for updating the referenced message at a later time with {@link edit}. * * @remarks * This will send a DeferredUpdateMessage response. */ - deferEdit: (options?: InteractionCallbackOptions) => Promise + deferEdit: (options?: InteractionCallbackOptions) => Promise; /** * Defer the interaction for updating the response at a later time with {@link edit}. * * @remarks * This will send a DeferredChannelMessageWithSource response. */ - defer: (isPrivate?: boolean, options?: InteractionCallbackOptions) => Promise + defer: (isPrivate?: boolean, options?: InteractionCallbackOptions) => Promise; /** Delete the original interaction response or a followup if the message id is provided. */ - delete: (messageId?: BigString) => Promise + delete: (messageId?: BigString) => Promise; } export interface InteractionCallbackResponse { /** The interaction object associated with the interaction response */ - interaction: InteractionCallback + interaction: InteractionCallback; /** The resource that was created by the interaction response. */ - resource?: InteractionResource + resource?: InteractionResource; } export interface InteractionCallback { - id: bigint - type: InteractionTypes + id: bigint; + type: InteractionTypes; /** Instance ID of the Activity if one was launched or joined */ - activityInstanceId?: string + activityInstanceId?: string; /** ID of the message that was created by the interaction */ - responseMessageId?: bigint + responseMessageId?: bigint; /** Whether or not the message is in a loading state */ - responseMessageLoading?: boolean + responseMessageLoading?: boolean; /** Whether or not the response message was ephemeral */ - responseMessageEphemeral?: boolean + responseMessageEphemeral?: boolean; } export interface InteractionResource { - type: InteractionResponseTypes + type: InteractionResponseTypes; /** * Represents the Activity launched by this interaction. * * @remarks * Only present if type is `LAUNCH_ACTIVITY`. */ - activityInstance?: DiscordActivityInstanceResource + activityInstance?: DiscordActivityInstanceResource; /** * Message created by the interaction. * * @remarks * Only present if type is either `CHANNEL_MESSAGE_WITH_SOURCE` or `UPDATE_MESSAGE`. */ - message?: Message + message?: Message; } export interface InteractionData { - type?: ApplicationCommandTypes - componentType?: MessageComponentTypes - customId?: string - components?: Component[] - values?: string[] - name: string - resolved?: InteractionDataResolved - options?: InteractionDataOption[] - id?: bigint - targetId?: bigint + type?: ApplicationCommandTypes; + componentType?: MessageComponentTypes; + customId?: string; + components?: Component[]; + values?: string[]; + name: string; + resolved?: InteractionDataResolved; + options?: InteractionDataOption[]; + id?: bigint; + targetId?: bigint; } export interface InteractionDataResolved { - messages?: Collection - users?: Collection - members?: Collection> - roles?: Collection - channels?: Collection> - attachments?: Collection + messages?: Collection; + users?: Collection; + members?: Collection>; + roles?: Collection; + channels?: Collection>; + attachments?: Collection; } export interface InteractionDataOption { - name: string - type: ApplicationCommandOptionTypes - value?: string | number | boolean - options?: InteractionDataOption[] - focused?: boolean + name: string; + type: ApplicationCommandOptionTypes; + value?: string | number | boolean; + options?: InteractionDataOption[]; + focused?: boolean; } export interface Invite { /** The type of invite */ - type: DiscordInviteType + type: DiscordInviteType; /** The channel the invite is for */ - channelId: bigint + channelId: bigint; /** The unique invite code */ - code: string + code: string; /** The time at which the invite was created */ - createdAt: number + createdAt: number; /** The guild of the invite */ - guildId?: bigint + guildId?: bigint; /** The user that created the invite */ - inviter?: User + inviter?: User; /** How long the invite is valid for (in seconds) */ - maxAge: number + maxAge: number; /** The maximum number of times the invite can be used */ - maxUses: number + maxUses: number; /** The type of target for this voice channel invite */ - targetType: number + targetType: number; /** The target user for this invite */ - targetUser: User + targetUser: User; /** The embedded application to open for this voice channel embedded application invite */ - targetApplication?: Application + targetApplication?: Application; /** Whether or not the invite is temporary (invited users will be kicked on disconnect unless they're assigned a role) */ - temporary: boolean + temporary: boolean; /** How many times the invite has been used (always will be 0) */ - uses: number + uses: number; /** Approximate count of online members (only present when target_user is set) */ - approximateMemberCount: number + approximateMemberCount: number; /** The expiration date of this invite, returned from the GET /invites/code endpoint when with_expiration is true */ - expiresAt?: number + expiresAt?: number; /** guild scheduled event data */ - guildScheduledEvent?: ScheduledEvent + guildScheduledEvent?: ScheduledEvent; /** Approximate count of online members (only present when target_user is set) */ - approximatePresenceCount?: number + approximatePresenceCount?: number; /** Guild invite flags for guild invites. */ - flags?: ToggleBitfield + flags?: ToggleBitfield; } export interface Member { /** The user id of the member. */ - id: bigint + id: bigint; /** The compressed form of all the boolean values on this user. */ - toggles?: MemberToggles + toggles?: MemberToggles; /** * The guild id where this member is. * * @remarks * This will always be present unless the member object is from thread member object. * */ - guildId?: bigint + guildId?: bigint; /** The user this guild member represents */ - user?: User + user?: User; /** This user's guild nickname */ - nick?: string + nick?: string; /** The member's custom avatar for this server. */ - avatar?: bigint + avatar?: bigint; /** The member's custom banner for this server. */ - banner?: bigint + banner?: bigint; /** Array of role object ids */ - roles: bigint[] + roles: bigint[]; /** When the user joined the guild */ - joinedAt?: number + joinedAt?: number; /** When the user started boosting the guild */ - premiumSince?: number + premiumSince?: number; /** The permissions this member has in the guild. Only present on interaction events. */ - permissions?: Permissions + permissions?: Permissions; /** when the user's timeout will expire and the user will be able to communicate in the guild again (set null to remove timeout), null or a time in the past if the user is not timed out */ - communicationDisabledUntil?: number + communicationDisabledUntil?: number; /** data for the member's guild avatar decoration */ - avatarDecorationData: AvatarDecorationData + avatarDecorationData: AvatarDecorationData; /** Whether the user is deafened in voice channels */ - deaf?: boolean + deaf?: boolean; /** Whether the user is muted in voice channels */ - mute?: boolean + mute?: boolean; /** Whether the user has not yet passed the guild's Membership Screening requirements */ - pending?: boolean + pending?: boolean; /** Member has left and rejoined the guild */ - didRejoin?: boolean + didRejoin?: boolean; /** Member has completed onboarding */ - startedOnboarding?: boolean + startedOnboarding?: boolean; /** Member is exempt from guild verification requirements */ - bypassesVerification?: boolean + bypassesVerification?: boolean; /** Member has started onboarding */ - completedOnboarding?: boolean + completedOnboarding?: boolean; /** Guild member flags */ - flags: number + flags: number; } export interface Message { /** Sent with Rich Presence-related chat embeds */ - activity?: MessageActivity + activity?: MessageActivity; /** Sent with Rich Presence-related chat embeds */ - application?: Partial + application?: Partial; /** If the message is an Interaction or application-owned webhook, this is the id of the application */ - applicationId?: bigint + applicationId?: bigint; /** Any attached files on this message. */ - attachments?: Attachment[] + attachments?: Attachment[]; /** The author of this message (not guaranteed to be a valid user) Note: The author object follows the structure of the user object, but is only a valid user in the case where the message is generated by a user or bot user. If the message is generated by a webhook, the author object corresponds to the webhook's id, username, and avatar. You can tell if a message is generated by a webhook by checking for the webhook_id on the message object. */ - author: User + author: User; /** id of the channel the message was sent in */ - channelId: bigint + channelId: bigint; /** The components related to this message */ - components: Component[] + components: Component[]; /** Contents of the message */ - content: string + content: string; /** The timestamp in milliseconds when this message was edited last. */ - editedTimestamp?: number + editedTimestamp?: number; /** Any embedded content */ - embeds?: Embed[] + embeds?: Embed[]; /** id of the guild the message was sent in Note: For MESSAGE_CREATE and MESSAGE_UPDATE events, the message object may not contain a guild_id or member field since the events are sent directly to the receiving user and the bot who sent the message, rather than being sent through the guild like non-ephemeral messages. */ - guildId?: bigint + guildId?: bigint; /** id of the message */ - id: bigint + id: bigint; /** sent if the message is sent as a result of an interaction */ - interactionMetadata?: MessageInteractionMetadata + interactionMetadata?: MessageInteractionMetadata; /** * Sent if the message is a response to an Interaction * * @deprecated * Deprecated in favor of {@link interactionMetadata} */ - interaction?: MessageInteraction - member?: Member + interaction?: MessageInteraction; + member?: Member; /** Users specifically mentioned in the message Note: The user objects in the mentions array will only have the partial member field present in MESSAGE_CREATE and MESSAGE_UPDATE events from text-based guild channels. */ - mentions?: User[] + mentions?: User[]; /** Channels specifically mentioned in this message Note: Not all channel mentions in a message will appear in mention_channels. Only textual channels that are visible to everyone in a discoverable guild will ever be included. Only crossposted messages (via Channel Following) currently include mention_channels at all. If no mentions in the message meet these requirements, this field will not be sent. */ - mentionedChannelIds?: bigint[] + mentionedChannelIds?: bigint[]; /** Roles specifically mentioned in this message */ - mentionedRoleIds?: bigint[] + mentionedRoleIds?: bigint[]; /** Data showing the source of a crossposted channel follow add, pin or reply message */ - messageReference?: MessageReference + messageReference?: MessageReference; /** * The message associated with the `message_reference` * Note: This field is only returned for messages with a `type` of `19` (REPLY). If the message is a reply but the `referenced_message` field is not present, the backend did not attempt to fetch the message that was being replied to, so its state is unknown. If the field exists but is null, the referenced message was deleted. */ - referencedMessage?: Message + referencedMessage?: Message; /** The message associated with the `message_reference`. This is a minimal subset of fields in a message (e.g. `author` is excluded.) */ - messageSnapshots?: MessageSnapshot[] - nonce?: string | number + messageSnapshots?: MessageSnapshot[]; + nonce?: string | number; /** Reactions on this message. */ - reactions?: Reaction[] + reactions?: Reaction[]; /** Sent if the message contains stickers */ - stickerItems?: Pick[] + stickerItems?: Pick[]; /** Type of message */ - type: MessageTypes + type: MessageTypes; /** The thread that was started from this message, includes thread member object */ - thread?: Channel + thread?: Channel; /** If the message is generated by a webhook, this is the webhook's id */ - webhookId?: bigint + webhookId?: bigint; /** A poll! */ - poll?: Poll + poll?: Poll; /** The call associated with the message */ - call?: MessageCall + call?: MessageCall; /** Holds all the boolean values on this message. */ - bitfield?: ToggleBitfield + bitfield?: ToggleBitfield; /** Whether this message has been published to subscribed channels (via Channel Following) */ - crossposted: boolean + crossposted: boolean; /** Whether this message is only visible to the user who invoked the Interaction */ - ephemeral: boolean + ephemeral: boolean; /** Whether this message failed to mention some roles and add their members to the thread */ - failedToMentionSomeRolesInThread: boolean + failedToMentionSomeRolesInThread: boolean; /** Message flags combined as a bitfield */ - flags?: ToggleBitfield + flags?: ToggleBitfield; /** Whether this message has an associated thread, with the same id as the message */ - hasThread: boolean + hasThread: boolean; /** Whether this message originated from a message in another channel (via Channel Following) */ - isCrosspost: boolean + isCrosspost: boolean; /** Whether this message is an Interaction Response and the bot is "thinking" */ - loading: boolean + loading: boolean; /** The ids of the users who were mentioned in this message. */ - mentionedUserIds: bigint[] + mentionedUserIds: bigint[]; /** Whether this message mentions everyone */ - mentionEveryone: boolean + mentionEveryone: boolean; /** Whether this message is pinned */ - pinned: boolean + pinned: boolean; /** Whether the source message for this crosspost has been deleted (via Channel Following) */ - sourceMessageDeleted: boolean + sourceMessageDeleted: boolean; /** Whether do not include any embeds when serializing this message */ - suppressEmbeds: boolean + suppressEmbeds: boolean; /** Whether this message will not trigger push and desktop notifications */ - suppressNotifications: boolean + suppressNotifications: boolean; /** The timestamp in milliseconds when this message was created */ - timestamp: number + timestamp: number; /** Whether this was a TTS message. */ - tts: boolean + tts: boolean; /** Whether this message came from the urgent message system */ - urgent: boolean + urgent: boolean; // TODO: Adding this causes errors in the interaction functions due to how `InteractionResolvedDataMember` and `InteractionResolvedDataChannel` are treated by `TransformProperty`, since they get their desired props changed // and fixing this requires a few changes in `SetupDesiredProps` and `TransformProperty` so this is going to be done in another pr // /** data for users, members, channels, and roles referenced in this message */ @@ -1289,31 +1289,31 @@ export interface Message { export interface MessageActivity { /** Type of message activity */ - type: MessageActivityTypes + type: MessageActivityTypes; /** party_id from a Rich Presence event */ - partyId?: string + partyId?: string; } export interface MessageInteraction { /** Id of the interaction */ - id: bigint + id: bigint; /** The member who invoked the interaction in the guild */ - member?: Member + member?: Member; /** The name of the ApplicationCommand including the name of the subcommand/subcommand group */ - name: string + name: string; /** The type of interaction */ - type: InteractionTypes + type: InteractionTypes; /** The user who invoked the interaction */ - user: User + user: User; } export interface MessageReference { /** id of the originating message's channel Note: channel_id is optional when creating a reply, but will always be present when receiving an event/response that includes this data model. */ - channelId?: bigint + channelId?: bigint; /** id of the originating message's guild */ - guildId?: bigint + guildId?: bigint; /** id of the originating message */ - messageId?: bigint + messageId?: bigint; } export interface MessageSnapshot { @@ -1331,146 +1331,146 @@ export interface MessageSnapshot { | 'mentionedRoleIds' | 'stickerItems' | 'components' - > + >; } export interface MessageInteractionMetadata { /** Id of the interaction */ - id: bigint + id: bigint; /** The type of interaction */ - type: InteractionTypes + type: InteractionTypes; /** User who triggered the interaction */ - user: User + user: User; /** IDs for installation context(s) related to an interaction */ - authorizingIntegrationOwners: Partial> + authorizingIntegrationOwners: Partial>; /** ID of the original response message, present only on follow-up messages */ - originalResponseMessageId?: bigint + originalResponseMessageId?: bigint; /** * The user the command was run on, present only on user command interactions * * @remarks * Only present when the interaction metadata is about an application command */ - targetUser?: User + targetUser?: User; /** * The ID of the message the command was run on, present only on message command interactions. The original response message will also have message_reference and referenced_message pointing to this message. * * @remarks * Only present when the interaction metadata is about an application command */ - targetMessageId?: bigint + targetMessageId?: bigint; /** * ID of the message that contained interactive component, present only on messages created from component interactions * * @remarks * Only present when the interaction metadata is about a message component */ - interactedMessageId?: bigint + interactedMessageId?: bigint; /** * Metadata for the interaction that was used to open the modal, present only on modal submit interactions * * @remarks * Only present when the interaction metadata is about a modal submit */ - triggeringInteractionMetadata?: MessageInteractionMetadata + triggeringInteractionMetadata?: MessageInteractionMetadata; } export interface MessageCall { /** Array of user object ids that participated in the call */ - participants: bigint[] + participants: bigint[]; /** Time when call ended */ - endedTimestamp: number + endedTimestamp: number; } export interface MessagePin { /** the time the message was pinned */ - pinnedAt: number + pinnedAt: number; /** the pinned message */ - message: Message + message: Message; } export interface Reaction { /** Whether the current user reacted using this emoji */ - me: boolean + me: boolean; /** Whether the current user super-reacted using this emoji */ - meBurst: boolean + meBurst: boolean; /** Times this emoji has been used to react */ - count: number + count: number; /** Reaction count details object */ - countDetails: ReactionCountDetails - emoji: Partial + countDetails: ReactionCountDetails; + emoji: Partial; /** HEX colors used for super reaction */ - burstColors: string[] + burstColors: string[]; } export interface ReactionCountDetails { /** Count of super reactions */ - burst: number + burst: number; /** Count of normal reactions */ - normal: number + normal: number; } export interface GuildOnboarding { /** ID of the guild this onboarding is part of */ - guildId: bigint + guildId: bigint; /** Prompts shown during onboarding and in customize community */ - prompts: GuildOnboardingPrompt[] + prompts: GuildOnboardingPrompt[]; /** Channel IDs that members get opted into automatically */ - defaultChannelIds: bigint[] + defaultChannelIds: bigint[]; /** Whether onboarding is enabled in the guild */ - enabled: boolean + enabled: boolean; /** Current mode of onboarding */ - mode: DiscordGuildOnboardingMode + mode: DiscordGuildOnboardingMode; } export interface GuildOnboardingPrompt { /** ID of the prompt */ - id: bigint + id: bigint; /** Type of prompt */ - type: DiscordGuildOnboardingPromptType + type: DiscordGuildOnboardingPromptType; /** Options available within the prompt */ - options: GuildOnboardingPromptOption[] + options: GuildOnboardingPromptOption[]; /** Title of the prompt */ - title: string + title: string; /** Indicates whether users are limited to selecting one option for the prompt */ - singleSelect: boolean + singleSelect: boolean; /** Indicates whether the prompt is required before a user completes the onboarding flow */ - required: boolean + required: boolean; /** Indicates whether the prompt is present in the onboarding flow. If `false`, the prompt will only appear in the Channels & Roles tab */ - inOnboarding: boolean + inOnboarding: boolean; } export interface GuildOnboardingPromptOption { /** ID of the prompt option */ - id: bigint + id: bigint; /** IDs for channels a member is added to when the option is selected */ - channelIds: bigint[] + channelIds: bigint[]; /** IDs for roles assigned to a member when the option is selected */ - roleIds: bigint[] + roleIds: bigint[]; /** Emoji of the option */ - emoji: Emoji + emoji: Emoji; /** Title of the option */ - title: string + title: string; /** Description of the option */ - description?: string + description?: string; } export interface Poll { /** The question of the poll. Only `text` is supported. */ - question: PollMedia + question: PollMedia; /** Each of the answers available in the poll. There is a maximum of 10 answers per poll. */ - answers: PollAnswer[] + answers: PollAnswer[]; /** * The time when the poll ends. * * @remarks * `expiry` is marked as nullable to support non-expiring polls in the future, but all polls have an expiry currently. */ - expiry: number | null + expiry: number | null; /** Whether a user can select multiple answers */ - allowMultiselect: boolean + allowMultiselect: boolean; /** The layout type of the poll */ - layoutType: DiscordPollLayoutType + layoutType: DiscordPollLayoutType; /** * The results of the poll * @@ -1478,7 +1478,7 @@ export interface Poll { * This value will not be sent by discord under specific conditions where they don't fetch them on their backend. When this value is missing it should be interpreted as "Unknown results" and not as "No results" * The results may not be totally accurate while the poll has not ended. When it ends discord will re-calculate all the results and set is_finalized to true */ - results?: PollResult + results?: PollResult; } export interface PollMedia { @@ -1489,14 +1489,14 @@ export interface PollMedia { * `text` should always be non-null for both questions and answers, but this is subject to changes. * The maximum length of `text` is 300 for the question, and 55 for any answer. */ - text?: string + text?: string; /** * The emoji of the field * * @remarks * When creating a poll answer with an emoji, one only needs to send either the `id` (custom emoji) or `name` (default emoji) as the only field. */ - emoji?: Partial + emoji?: Partial; } export interface PollAnswer { @@ -1506,82 +1506,82 @@ export interface PollAnswer { * @remarks * This id labels each answer. It starts at 1 and goes up sequentially. Discord recommend against depending on this sequence as it is an implementation detail. */ - answerId: number + answerId: number; /** The data of the answer */ - pollMedia: PollMedia + pollMedia: PollMedia; } export interface PollResult { /** Whether the votes have been precisely counted */ - isFinalized: boolean + isFinalized: boolean; /** The counts for each answer */ - answerCounts: PollAnswerCount[] + answerCounts: PollAnswerCount[]; } export interface PollAnswerCount { /** The {@link PollAnswer.answerId | answerId} */ - id: number + id: number; /** The number of votes for this answer */ - count: number + count: number; /** Whether the current user voted for this answer */ - meVoted: boolean + meVoted: boolean; } export interface PresenceUpdate { - desktop?: string - mobile?: string - web?: string - user: User - guildId: bigint - status: PresenceStatus - activities: Activity[] + desktop?: string; + mobile?: string; + web?: string; + user: User; + guildId: bigint; + status: PresenceStatus; + activities: Activity[]; } export interface Role { /** Role id */ - id: bigint + id: bigint; /** The guild id where this role is located. */ - guildId: bigint + guildId: bigint; /** The compressed version of the boolean values on this role. */ - toggles?: RoleToggles + toggles?: RoleToggles; /** If this role is showed separately in the user listing */ - hoist: boolean + hoist: boolean; /** Permission bit set */ - permissions: Permissions + permissions: Permissions; /** Whether this role is managed by an integration */ - managed: boolean + managed: boolean; /** Whether this role is mentionable */ - mentionable: boolean + mentionable: boolean; /** * Role tags * * @private * Use role.tags. This is for internal use only, and prone to breaking changes. */ - internalTags?: InternalRoleTags - icon?: bigint + internalTags?: InternalRoleTags; + icon?: bigint; /** Role name */ - name: string + name: string; /** * Integer representation of hexadecimal color code * @deprecated the {@link colors} field is recommended for use instead of this field */ - color: number + color: number; /** The role's color */ - colors: RoleColors + colors: RoleColors; /** Position of this role */ - position: number + position: number; /** role unicode emoji */ - unicodeEmoji?: string + unicodeEmoji?: string; /** Role flags combined as a bitfield */ - flags: RoleFlags + flags: RoleFlags; /** The tags this role has */ - tags?: RoleTags - premiumSubscriber: boolean + tags?: RoleTags; + premiumSubscriber: boolean; /** Whether this role is available for purchase. */ - availableForPurchase: boolean + availableForPurchase: boolean; /** Whether this is a guild's linked role. */ - guildConnections: boolean + guildConnections: boolean; } /** @@ -1590,299 +1590,299 @@ export interface Role { */ export interface InternalRoleTags { /** The id of the bot this role belongs to */ - botId?: bigint + botId?: bigint; /** The id of the integration this role belongs to */ - integrationId?: bigint + integrationId?: bigint; /** Id of this role's subscription sku and listing. */ - subscriptionListingId?: bigint + subscriptionListingId?: bigint; } export interface RoleTags { /** The id of the bot this role belongs to */ - botId?: bigint + botId?: bigint; /** The id of the integration this role belongs to */ - integrationId?: bigint + integrationId?: bigint; /** Id of this role's subscription sku and listing. */ - subscriptionListingId?: bigint + subscriptionListingId?: bigint; /** Whether this role is available for purchase. */ - availableForPurchase?: boolean + availableForPurchase?: boolean; /** Whether this is a guild's linked role */ - guildConnections?: boolean + guildConnections?: boolean; /** Whether this is the guild's premium subscriber role */ - premiumSubscriber?: boolean + premiumSubscriber?: boolean; } export interface RoleColors { /** The primary color for the role */ - primaryColor: number + primaryColor: number; /** The secondary color for the role, this will make the role a gradient between the other provided colors */ - secondaryColor?: number + secondaryColor?: number; /** The tertiary color for the role, this will turn the gradient into a holographic style */ - tertiaryColor?: number + tertiaryColor?: number; } export interface ScheduledEvent { /** the id of the scheduled event */ - id: bigint + id: bigint; /** the guild id which the scheduled event belongs to */ - guildId: bigint + guildId: bigint; /** the channel id in which the scheduled event will be hosted if specified */ - channelId?: bigint + channelId?: bigint; /** the id of the user that created the scheduled event */ - creatorId?: bigint + creatorId?: bigint; /** the name of the scheduled event */ - name: string + name: string; /** the description of the scheduled event */ - description?: string + description?: string; /** the time the scheduled event will start */ - scheduledStartTime: number + scheduledStartTime: number; /** the time the scheduled event will end if it does end. */ - scheduledEndTime?: number + scheduledEndTime?: number; /** the privacy level of the scheduled event */ - privacyLevel: ScheduledEventPrivacyLevel + privacyLevel: ScheduledEventPrivacyLevel; /** the status of the scheduled event */ - status: ScheduledEventStatus + status: ScheduledEventStatus; /** the type of hosting entity associated with a scheduled event */ - entityType: ScheduledEventEntityType + entityType: ScheduledEventEntityType; /** any additional id of the hosting entity associated with event */ - entityId?: bigint + entityId?: bigint; /** the location for the scheduled event */ - location?: string + location?: string; /** the user that created the scheduled event */ - creator?: User + creator?: User; /** the number of users subscribed to the scheduled event */ - userCount?: number + userCount?: number; /** the cover image hash of the scheduled event */ - image?: bigint + image?: bigint; /** the definition for how often this event should recur */ - recurrenceRule?: ScheduledEventRecurrenceRule + recurrenceRule?: ScheduledEventRecurrenceRule; } export interface ScheduledEventRecurrenceRule { /** Starting time of the recurrence interval */ - start: number + start: number; /** Ending time of the recurrence interval */ - end: number | null + end: number | null; /** How often the event occurs */ - frequency: DiscordScheduledEventRecurrenceRuleFrequency + frequency: DiscordScheduledEventRecurrenceRuleFrequency; /** The spacing between the events, defined by `frequency`. For example, `frequency` of `Weekly` and an `interval` of `2` would be "every-other week" */ - interval: number + interval: number; /** Set of specific days within a week for the event to recur on */ - byWeekday: DiscordScheduledEventRecurrenceRuleWeekday[] | null + byWeekday: DiscordScheduledEventRecurrenceRuleWeekday[] | null; /** List of specific days within a specific week (1-5) to recur on */ - byNWeekday: DiscordScheduledEventRecurrenceRuleNWeekday[] | null + byNWeekday: DiscordScheduledEventRecurrenceRuleNWeekday[] | null; /** Set of specific months to recur on */ - byMonth: DiscordScheduledEventRecurrenceRuleMonth[] | null + byMonth: DiscordScheduledEventRecurrenceRuleMonth[] | null; /** Set of specific dates within a month to recur on */ - byMonthDay: number[] | null + byMonthDay: number[] | null; /** Set of days within a year to recur on (1-364) */ - byYearDay: number[] | null + byYearDay: number[] | null; /** The total amount of times that the event is allowed to recur before stopping */ - count: number | null + count: number | null; } export interface Sku { /** ID of SKU */ - id: bigint + id: bigint; /** Type of SKU */ - type: DiscordSkuType + type: DiscordSkuType; /** ID of the parent application */ - applicationId: bigint + applicationId: bigint; /** Customer-facing name of your premium offering */ - name: string + name: string; /** System-generated URL slug based on the SKU's name */ - slug: string + slug: string; /** SKU flags combined as a bitfield */ - flags: SkuFlags + flags: SkuFlags; } export interface StageInstance { /** The topic of the Stage instance (1-120 characters) */ - topic: string + topic: string; /** The id of this Stage instance */ - id: bigint + id: bigint; /** The guild id of the associated Stage channel */ - guildId: bigint + guildId: bigint; /** The id of the associated Stage channel */ - channelId: bigint + channelId: bigint; /** The id of the scheduled event for this Stage instance */ - guildScheduledEventId?: bigint + guildScheduledEventId?: bigint; } export interface InviteStageInstance { /** The members speaking in the Stage */ - members: Partial[] + members: Partial[]; /** The number of users in the Stage */ - participantCount: number + participantCount: number; /** The number of users speaking in the Stage */ - speakerCount: number + speakerCount: number; /** The topic of the Stage instance (1-120 characters) */ - topic: string + topic: string; } export interface Sticker { /** [Id of the sticker](https://discord.com/developers/docs/reference#image-formatting) */ - id: bigint + id: bigint; /** Id of the pack the sticker is from */ - packId?: bigint + packId?: bigint; /** Name of the sticker */ - name: string + name: string; /** Description of the sticker */ - description: string + description: string; /** a unicode emoji representing the sticker's expression */ - tags: string + tags: string; /** [type of sticker](https://discord.com/developers/docs/resources/sticker#sticker-object-sticker-types) */ - type: StickerTypes + type: StickerTypes; /** [Type of sticker format](https://discord.com/developers/docs/resources/sticker#sticker-object-sticker-format-types) */ - formatType: StickerFormatTypes + formatType: StickerFormatTypes; /** Whether or not the sticker is available */ - available?: boolean + available?: boolean; /** Id of the guild that owns this sticker */ - guildId?: bigint + guildId?: bigint; /** The user that uploaded the sticker */ - user?: User + user?: User; /** A sticker's sort order within a pack */ - sortValue?: number + sortValue?: number; } export interface StickerPack { - coverStickerId?: bigint - bannerAssetId?: bigint - id: bigint - name: string - description: string - stickers: Sticker[] - skuId: bigint + coverStickerId?: bigint; + bannerAssetId?: bigint; + id: bigint; + name: string; + description: string; + stickers: Sticker[]; + skuId: bigint; } export interface Team { - icon?: bigint - id: bigint - name: string - ownerUserId: bigint - members: TeamMember[] + icon?: bigint; + id: bigint; + name: string; + ownerUserId: bigint; + members: TeamMember[]; } export interface TeamMember { - membershipState: TeamMembershipStates - teamId: bigint - user: User - role: DiscordTeamMemberRole + membershipState: TeamMembershipStates; + teamId: bigint; + user: User; + role: DiscordTeamMemberRole; } export interface Template { - description?: string | null - isDirty?: boolean - name: string - creatorId: bigint - createdAt: number - code: string - usageCount: number - creator: User - updatedAt: number - sourceGuildId: bigint - serializedSourceGuild: DiscordTemplateSerializedSourceGuild + description?: string | null; + isDirty?: boolean; + name: string; + creatorId: bigint; + createdAt: number; + code: string; + usageCount: number; + creator: User; + updatedAt: number; + sourceGuildId: bigint; + serializedSourceGuild: DiscordTemplateSerializedSourceGuild; } export interface ThreadMember { /** Any user-thread settings, currently only used for notifications */ - flags: number + flags: number; /** The id of the thread */ - id?: bigint + id?: bigint; /** The id of the user */ - userId?: bigint + userId?: bigint; /** The time the current user last joined the thread */ - joinTimestamp: number + joinTimestamp: number; /** The member object of the user */ - member?: Member + member?: Member; } export interface ThreadMemberGuildCreate { - joinTimestamp: number + joinTimestamp: number; } export interface User { /** Compressed version of all the booleans on a user. */ - toggles?: UserToggles + toggles?: UserToggles; /** The user's username, not unique across the platform */ - username: string + username: string; /** The user's display name, if it is set. For bots, this is the application name */ - globalName?: string + globalName?: string; /** The user's display name based on `globalName` and `username` */ - displayName: string + displayName: string; /** Get the timestamp in milliseconds of user's creation date */ - createdTimestamp: number + createdTimestamp: number; /** The user's chosen language option */ - locale?: string + locale?: string; /** The flags on a user's account */ - flags?: ToggleBitfield + flags?: ToggleBitfield; /** The type of Nitro subscription on a user's account */ - premiumType?: PremiumTypes + premiumType?: PremiumTypes; /** The public flags on a user's account */ - publicFlags?: ToggleBitfield + publicFlags?: ToggleBitfield; /** the user's banner color encoded as an integer representation of hexadecimal color code */ - accentColor?: number + accentColor?: number; /** The user's id */ - id: bigint + id: bigint; /** The user's discord-tag */ - discriminator: string + discriminator: string; /** The user's avatar hash */ - avatar?: bigint + avatar?: bigint; /** The user's email */ - email?: string + email?: string; /** the user's banner, or null if unset */ - banner?: bigint + banner?: bigint; /** data for the user's avatar decoration */ - avatarDecorationData?: AvatarDecorationData + avatarDecorationData?: AvatarDecorationData; /** The user tag in the form of `username` or `username#discriminator` for legacy username system */ - tag: string + tag: string; /** Whether the user belongs to an OAuth2 application */ - bot: boolean + bot: boolean; /** Whether the user is an Official Discord System user (part of the urgent message system) */ - system: boolean + system: boolean; /** Whether the user has two factor enabled on their account */ - mfaEnabled: boolean + mfaEnabled: boolean; /** Whether the email on this account has been verified */ - verified: boolean + verified: boolean; /** data for the user's collectibles */ - collectibles?: Collectibles + collectibles?: Collectibles; /** The user's primary guild */ - primaryGuild?: UserPrimaryGuild + primaryGuild?: UserPrimaryGuild; /** Get user's default avatar in formatted url */ - defaultAvatarUrl: string + defaultAvatarUrl: string; /** * Get user's avatar in formatted url * @param options Image format options * @returns User's avatar in formatted url */ - avatarUrl: (options?: ImageOptions) => string | undefined + avatarUrl: (options?: ImageOptions) => string | undefined; /** * Get user's display avatar in formatted url * @param options Image format options * @returns User's display avatar in formatted url */ - displayAvatarUrl: (options?: ImageOptions) => string + displayAvatarUrl: (options?: ImageOptions) => string; } export interface Collectibles { /** object mapping of nameplate data */ - nameplate?: Nameplate + nameplate?: Nameplate; } export interface Nameplate { /** the nameplate's id */ - skuId: bigint + skuId: bigint; /** path to the nameplate asset */ - asset: string + asset: string; /** the label of this nameplate. Currently unused */ - label: string + label: string; /** background color of the nameplate, one of: `crimson`, `berry`, `sky`, `teal`, `forest`, `bubble_gum`, `violet`, `cobalt`, `clover`, `lemon`, `white` */ - palette: string + palette: string; } export interface UserPrimaryGuild { /** The id of the primary guild */ - identityGuildId?: bigint + identityGuildId?: bigint; /** * Whether the user is displaying the primary guild's server tag. * @@ -1890,146 +1890,146 @@ export interface UserPrimaryGuild { * This can be `undefined` if the system clears the identity, e.g. because the server no longer supports tags. * This will be `false` if the user manually removes their tag. */ - identityEnabled?: boolean + identityEnabled?: boolean; /** The text of the user's server tag. Limited to 4 characters */ - tag?: string + tag?: string; /** The server tag badge hash */ - badge?: bigint + badge?: bigint; } export interface VoiceRegion { - id: string - name: string - custom: boolean - optimal: boolean - deprecated: boolean + id: string; + name: string; + custom: boolean; + optimal: boolean; + deprecated: boolean; } export interface VoiceState { - requestToSpeakTimestamp?: number - channelId?: bigint - guildId: bigint - toggles: VoiceStateToggles - sessionId: string - userId: bigint + requestToSpeakTimestamp?: number; + channelId?: bigint; + guildId: bigint; + toggles: VoiceStateToggles; + sessionId: string; + userId: bigint; } export interface Webhook { /** The type of the webhook */ - type: WebhookTypes + type: WebhookTypes; /** The secure token of the webhook (returned for Incoming Webhooks) */ - token?: string + token?: string; /** The url used for executing the webhook (returned by the webhooks OAuth2 flow) */ - url?: string + url?: string; /** The id of the webhook */ - id: bigint + id: bigint; /** The guild id this webhook is for */ - guildId?: bigint + guildId?: bigint; /** The channel id this webhook is for */ - channelId?: bigint + channelId?: bigint; /** The user this webhook was created by (not returned when getting a webhook with its token) */ - user?: User + user?: User; /** The default name of the webhook */ - name?: string + name?: string; /** The default user avatar hash of the webhook */ - avatar?: bigint + avatar?: bigint; /** The bot/OAuth2 application that created this webhook */ - applicationId?: bigint + applicationId?: bigint; /** The guild of the channel that this webhook is following (returned for Channel Follower Webhooks) */ - sourceGuild?: Partial + sourceGuild?: Partial; /** The channel that this webhook is following (returned for Channel Follower Webhooks) */ - sourceChannel?: Partial + sourceChannel?: Partial; } export interface WelcomeScreen { - description?: string - welcomeChannels: WelcomeScreenChannel[] + description?: string; + welcomeChannels: WelcomeScreenChannel[]; } export interface WelcomeScreenChannel { - channelId: bigint - description: string - emojiId?: bigint - emojiName?: string + channelId: bigint; + description: string; + emojiId?: bigint; + emojiName?: string; } export interface GuildWidget { - id: bigint - name: string - members: Partial[] - channels: Partial[] - instantInvite?: string - presenceCount: number + id: bigint; + name: string; + members: Partial[]; + channels: Partial[]; + instantInvite?: string; + presenceCount: number; } export interface GuildWidgetSettings { - channelId?: string - enabled: boolean + channelId?: string; + enabled: boolean; } export interface Subscription { /** ID of the subscription */ - id: bigint + id: bigint; /** ID of the user who is subscribed */ - userId: bigint + userId: bigint; /** List of SKUs subscribed to */ - skuIds: bigint[] + skuIds: bigint[]; /** List of entitlements granted for this subscription */ - entitlementIds: bigint[] + entitlementIds: bigint[]; /** List of SKUs that this user will be subscribed to at renewal */ - renewalSkuIds?: bigint[] + renewalSkuIds?: bigint[]; /** Start of the current subscription period */ - currentPeriodStart: number + currentPeriodStart: number; /** End of the current subscription period */ - currentPeriodEnd: number + currentPeriodEnd: number; /** Current status of the subscription */ - status: DiscordSubscriptionStatus + status: DiscordSubscriptionStatus; /** When the subscription was canceled */ - canceledAt: number + canceledAt: number; /** ISO3166-1 alpha-2 country code of the payment source used to purchase the subscription. Missing unless queried with a private OAuth scope. */ - country?: string + country?: string; } /** https://discord.com/developers/docs/resources/soundboard#soundboard-sound-object-soundboard-sound-structure */ export interface SoundboardSound { /** The name of this sound */ - name: string + name: string; /** The id of this sound */ - soundId: bigint + soundId: bigint; /** The volume of this sound, from 0 to 1 */ - volume: number + volume: number; /** The id of this sound's custom emoji */ - emojiId?: bigint + emojiId?: bigint; /** The unicode character of this sound's standard emoji */ - emojiName?: string + emojiName?: string; /** The id of the guild this sound is in */ - guildId?: bigint + guildId?: bigint; /** Whether this sound can be used, may be false due to loss of Server Boosts */ - available: boolean + available: boolean; /** The user who created this sound */ - user?: User + user?: User; } /** https://discord.com/developers/docs/resources/lobby#lobby-object-lobby-structure */ export interface Lobby { /** The id of this channel */ - id: bigint + id: bigint; /** application that created the lobby */ - applicationId: bigint + applicationId: bigint; /** dictionary of string key/value pairs. The max total length is 1000. */ - metadata?: Record + metadata?: Record; /** members of the lobby */ - members: LobbyMember[] + members: LobbyMember[]; /** the guild channel linked to the lobby */ - linkedChannel?: Channel + linkedChannel?: Channel; } /** https://discord.com/developers/docs/resources/lobby#lobby-member-object-lobby-member-structure */ export interface LobbyMember { /** The id of the user */ - id: bigint + id: bigint; /** dictionary of string key/value pairs. The max total length is 1000. */ - metadata?: Record + metadata?: Record; /** lobby member flags combined as as bitfield */ - flags?: ToggleBitfield + flags?: ToggleBitfield; } diff --git a/packages/bot/src/transformers/user.ts b/packages/bot/src/transformers/user.ts index 3118a0447..a32ea1add 100644 --- a/packages/bot/src/transformers/user.ts +++ b/packages/bot/src/transformers/user.ts @@ -1,103 +1,103 @@ -import type { DiscordCollectibles, DiscordNameplate, DiscordUser, DiscordUserPrimaryGuild } from '@discordeno/types' -import { avatarUrl, defaultAvatarUrl, displayAvatarUrl, iconHashToBigInt, snowflakeToTimestamp } from '@discordeno/utils' -import type { Bot } from '../bot.js' -import type { DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from '../desiredProperties.js' -import { ToggleBitfield } from './toggles/ToggleBitfield.js' -import { UserToggles } from './toggles/user.js' -import type { Collectibles, Nameplate, User, UserPrimaryGuild } from './types.js' +import type { DiscordCollectibles, DiscordNameplate, DiscordUser, DiscordUserPrimaryGuild } from '@discordeno/types'; +import { avatarUrl, defaultAvatarUrl, displayAvatarUrl, iconHashToBigInt, snowflakeToTimestamp } from '@discordeno/utils'; +import type { Bot } from '../bot.js'; +import type { DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from '../desiredProperties.js'; +import { ToggleBitfield } from './toggles/ToggleBitfield.js'; +import { UserToggles } from './toggles/user.js'; +import type { Collectibles, Nameplate, User, UserPrimaryGuild } from './types.js'; export const baseUser: User = { // This allows typescript to still check for type errors on functions below ...(undefined as unknown as User), avatarUrl(options) { - if (!this.avatar) return - return avatarUrl(this.id, this.avatar, options) + if (!this.avatar) return; + return avatarUrl(this.id, this.avatar, options); }, displayAvatarUrl(options) { - return displayAvatarUrl(this.id, this.discriminator, this.avatar, options) + return displayAvatarUrl(this.id, this.discriminator, this.avatar, options); }, get defaultAvatarUrl() { - return defaultAvatarUrl(this.id, this.discriminator) + return defaultAvatarUrl(this.id, this.discriminator); }, get displayName() { - return this.globalName ?? this.username + return this.globalName ?? this.username; }, get createdTimestamp() { - return snowflakeToTimestamp(this.id) + return snowflakeToTimestamp(this.id); }, get tag() { - const isLegacy = this.discriminator !== '0' && this.discriminator !== '0000' - return isLegacy ? `${this.username}#${this.discriminator}` : this.username + const isLegacy = this.discriminator !== '0' && this.discriminator !== '0000'; + return isLegacy ? `${this.username}#${this.discriminator}` : this.username; }, get bot() { - return !!this.toggles?.has('bot') + return !!this.toggles?.has('bot'); }, get system() { - return !!this.toggles?.has('system') + return !!this.toggles?.has('system'); }, get mfaEnabled() { - return !!this.toggles?.has('mfaEnabled') + return !!this.toggles?.has('mfaEnabled'); }, get verified() { - return !!this.toggles?.has('verified') + return !!this.toggles?.has('verified'); }, -} +}; export function transformUser(bot: Bot, payload: DiscordUser): User { - const user: SetupDesiredProps = Object.create(baseUser) - const props = bot.transformers.desiredProperties.user + const user: SetupDesiredProps = Object.create(baseUser); + const props = bot.transformers.desiredProperties.user; - if (props.toggles) user.toggles = new UserToggles(payload) - if (props.flags) user.flags = new ToggleBitfield(payload.flags) - if (props.publicFlags) user.publicFlags = new ToggleBitfield(payload.public_flags) - if (props.id && payload.id) user.id = bot.transformers.snowflake(payload.id) - if (props.username && payload.username) user.username = payload.username - if (props.globalName && payload.global_name) user.globalName = payload.global_name - if (props.discriminator && payload.discriminator) user.discriminator = payload.discriminator - if (props.locale && payload.locale) user.locale = payload.locale - if (props.email && payload.email) user.email = payload.email - if (props.premiumType && payload.premium_type) user.premiumType = payload.premium_type - if (props.avatar && payload.avatar) user.avatar = iconHashToBigInt(payload.avatar) - if (props.banner && payload.banner) user.banner = iconHashToBigInt(payload.banner) - if (props.accentColor && payload.accent_color) user.accentColor = payload.accent_color + if (props.toggles) user.toggles = new UserToggles(payload); + if (props.flags) user.flags = new ToggleBitfield(payload.flags); + if (props.publicFlags) user.publicFlags = new ToggleBitfield(payload.public_flags); + if (props.id && payload.id) user.id = bot.transformers.snowflake(payload.id); + if (props.username && payload.username) user.username = payload.username; + if (props.globalName && payload.global_name) user.globalName = payload.global_name; + if (props.discriminator && payload.discriminator) user.discriminator = payload.discriminator; + if (props.locale && payload.locale) user.locale = payload.locale; + if (props.email && payload.email) user.email = payload.email; + if (props.premiumType && payload.premium_type) user.premiumType = payload.premium_type; + if (props.avatar && payload.avatar) user.avatar = iconHashToBigInt(payload.avatar); + if (props.banner && payload.banner) user.banner = iconHashToBigInt(payload.banner); + if (props.accentColor && payload.accent_color) user.accentColor = payload.accent_color; if (props.avatarDecorationData && payload.avatar_decoration_data) - user.avatarDecorationData = bot.transformers.avatarDecorationData(bot, payload.avatar_decoration_data) - if (props.collectibles && payload.collectibles) user.collectibles = bot.transformers.collectibles(bot, payload.collectibles) - if (props.primaryGuild && payload.primary_guild) user.primaryGuild = bot.transformers.userPrimaryGuild(bot, payload.primary_guild) + user.avatarDecorationData = bot.transformers.avatarDecorationData(bot, payload.avatar_decoration_data); + if (props.collectibles && payload.collectibles) user.collectibles = bot.transformers.collectibles(bot, payload.collectibles); + if (props.primaryGuild && payload.primary_guild) user.primaryGuild = bot.transformers.userPrimaryGuild(bot, payload.primary_guild); - return bot.transformers.customizers.user(bot, payload, user) + return bot.transformers.customizers.user(bot, payload, user); } export function transformCollectibles(bot: Bot, payload: DiscordCollectibles): Collectibles { - const collectibles = {} as SetupDesiredProps - const props = bot.transformers.desiredProperties.collectibles + const collectibles = {} as SetupDesiredProps; + const props = bot.transformers.desiredProperties.collectibles; - if (props.nameplate && payload.nameplate) collectibles.nameplate = bot.transformers.nameplate(bot, payload.nameplate) + if (props.nameplate && payload.nameplate) collectibles.nameplate = bot.transformers.nameplate(bot, payload.nameplate); - return bot.transformers.customizers.collectibles(bot, payload, collectibles) + return bot.transformers.customizers.collectibles(bot, payload, collectibles); } export function transformNameplate(bot: Bot, payload: DiscordNameplate): Nameplate { - const nameplate = {} as SetupDesiredProps - const props = bot.transformers.desiredProperties.nameplate + const nameplate = {} as SetupDesiredProps; + const props = bot.transformers.desiredProperties.nameplate; - if (props.skuId && payload.sku_id) nameplate.skuId = bot.transformers.snowflake(payload.sku_id) - if (props.asset && payload.asset) nameplate.asset = payload.asset - if (props.label && payload.label) nameplate.label = payload.label - if (props.palette && payload.palette) nameplate.palette = payload.palette + if (props.skuId && payload.sku_id) nameplate.skuId = bot.transformers.snowflake(payload.sku_id); + if (props.asset && payload.asset) nameplate.asset = payload.asset; + if (props.label && payload.label) nameplate.label = payload.label; + if (props.palette && payload.palette) nameplate.palette = payload.palette; - return bot.transformers.customizers.nameplate(bot, payload, nameplate) + return bot.transformers.customizers.nameplate(bot, payload, nameplate); } export function transformUserPrimaryGuild(bot: Bot, payload: DiscordUserPrimaryGuild): UserPrimaryGuild { - const userPrimaryGuild = {} as SetupDesiredProps - const props = bot.transformers.desiredProperties.userPrimaryGuild + const userPrimaryGuild = {} as SetupDesiredProps; + const props = bot.transformers.desiredProperties.userPrimaryGuild; - if (props.identityGuildId && payload.identity_guild_id) userPrimaryGuild.identityGuildId = bot.transformers.snowflake(payload.identity_guild_id) - if (props.identityEnabled && payload.identity_enabled) userPrimaryGuild.identityEnabled = payload.identity_enabled - if (props.tag && payload.tag) userPrimaryGuild.tag = payload.tag - if (props.badge && payload.badge) userPrimaryGuild.badge = iconHashToBigInt(payload.badge) + if (props.identityGuildId && payload.identity_guild_id) userPrimaryGuild.identityGuildId = bot.transformers.snowflake(payload.identity_guild_id); + if (props.identityEnabled && payload.identity_enabled) userPrimaryGuild.identityEnabled = payload.identity_enabled; + if (props.tag && payload.tag) userPrimaryGuild.tag = payload.tag; + if (props.badge && payload.badge) userPrimaryGuild.badge = iconHashToBigInt(payload.badge); - return bot.transformers.customizers.userPrimaryGuild(bot, payload, userPrimaryGuild) + return bot.transformers.customizers.userPrimaryGuild(bot, payload, userPrimaryGuild); } diff --git a/packages/bot/src/transformers/voiceRegion.ts b/packages/bot/src/transformers/voiceRegion.ts index 56641a8b2..0f6e8c1e2 100644 --- a/packages/bot/src/transformers/voiceRegion.ts +++ b/packages/bot/src/transformers/voiceRegion.ts @@ -1,6 +1,6 @@ -import type { DiscordVoiceRegion } from '@discordeno/types' -import type { Bot } from '../bot.js' -import type { VoiceRegion } from './types.js' +import type { DiscordVoiceRegion } from '@discordeno/types'; +import type { Bot } from '../bot.js'; +import type { VoiceRegion } from './types.js'; export function transformVoiceRegion(bot: Bot, payload: DiscordVoiceRegion): VoiceRegion { const voiceRegion = { @@ -9,7 +9,7 @@ export function transformVoiceRegion(bot: Bot, payload: DiscordVoiceRegion): Voi optimal: payload.optimal, deprecated: payload.deprecated, custom: payload.custom, - } as VoiceRegion + } as VoiceRegion; - return bot.transformers.customizers.voiceRegion(bot, payload, voiceRegion) + return bot.transformers.customizers.voiceRegion(bot, payload, voiceRegion); } diff --git a/packages/bot/src/transformers/voiceState.ts b/packages/bot/src/transformers/voiceState.ts index 338d49e17..2f7eeb6a4 100644 --- a/packages/bot/src/transformers/voiceState.ts +++ b/packages/bot/src/transformers/voiceState.ts @@ -1,22 +1,22 @@ -import type { BigString, DiscordVoiceState } from '@discordeno/types' -import type { Bot } from '../bot.js' -import type { DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from '../desiredProperties.js' -import { VoiceStateToggles } from './toggles/voice.js' -import type { VoiceState } from './types.js' +import type { BigString, DiscordVoiceState } from '@discordeno/types'; +import type { Bot } from '../bot.js'; +import type { DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from '../desiredProperties.js'; +import { VoiceStateToggles } from './toggles/voice.js'; +import type { VoiceState } from './types.js'; export function transformVoiceState(bot: Bot, payload: DiscordVoiceState, extra?: { guildId?: BigString }): VoiceState { - const props = bot.transformers.desiredProperties.voiceState - const voiceState = {} as SetupDesiredProps + const props = bot.transformers.desiredProperties.voiceState; + const voiceState = {} as SetupDesiredProps; if (props.requestToSpeakTimestamp && payload.request_to_speak_timestamp) - voiceState.requestToSpeakTimestamp = Date.parse(payload.request_to_speak_timestamp) - if (props.channelId && payload.channel_id) voiceState.channelId = bot.transformers.snowflake(payload.channel_id) - if (props.guildId && extra?.guildId) voiceState.guildId = bot.transformers.snowflake(extra.guildId) - if (props.toggles) voiceState.toggles = new VoiceStateToggles(payload) - if (props.sessionId) voiceState.sessionId = payload.session_id - if (props.userId && payload.user_id) voiceState.userId = bot.transformers.snowflake(payload.user_id) + voiceState.requestToSpeakTimestamp = Date.parse(payload.request_to_speak_timestamp); + if (props.channelId && payload.channel_id) voiceState.channelId = bot.transformers.snowflake(payload.channel_id); + if (props.guildId && extra?.guildId) voiceState.guildId = bot.transformers.snowflake(extra.guildId); + if (props.toggles) voiceState.toggles = new VoiceStateToggles(payload); + if (props.sessionId) voiceState.sessionId = payload.session_id; + if (props.userId && payload.user_id) voiceState.userId = bot.transformers.snowflake(payload.user_id); return bot.transformers.customizers.voiceState(bot, payload, voiceState, { guildId: extra?.guildId ? bot.transformers.snowflake(extra.guildId) : undefined, - }) + }); } diff --git a/packages/bot/src/transformers/webhook.ts b/packages/bot/src/transformers/webhook.ts index 6cb0f8ba9..c0567eabb 100644 --- a/packages/bot/src/transformers/webhook.ts +++ b/packages/bot/src/transformers/webhook.ts @@ -1,32 +1,32 @@ -import type { DiscordWebhook } from '@discordeno/types' -import { iconHashToBigInt } from '@discordeno/utils' -import type { Bot } from '../bot.js' -import type { DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from '../desiredProperties.js' -import type { Webhook } from './types.js' +import type { DiscordWebhook } from '@discordeno/types'; +import { iconHashToBigInt } from '@discordeno/utils'; +import type { Bot } from '../bot.js'; +import type { DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from '../desiredProperties.js'; +import type { Webhook } from './types.js'; export function transformWebhook(bot: Bot, payload: DiscordWebhook): typeof bot.transformers.$inferredTypes.webhook { - const props = bot.transformers.desiredProperties.webhook - const webhook = {} as SetupDesiredProps + const props = bot.transformers.desiredProperties.webhook; + const webhook = {} as SetupDesiredProps; - if (props.id && payload.id) webhook.id = bot.transformers.snowflake(payload.id) - if (props.type && payload.type) webhook.type = payload.type - if (props.guildId && payload.guild_id) webhook.guildId = bot.transformers.snowflake(payload.guild_id) - if (props.channelId && payload.channel_id) webhook.channelId = bot.transformers.snowflake(payload.channel_id) - if (props.user && payload.user) webhook.user = bot.transformers.user(bot, payload.user) - if (props.name && payload.name) webhook.name = payload.name - if (props.avatar && payload.avatar) webhook.avatar = iconHashToBigInt(payload.avatar) - if (props.token && payload.token) webhook.token = payload.token - if (props.applicationId && payload.application_id) webhook.applicationId = bot.transformers.snowflake(payload.application_id) + if (props.id && payload.id) webhook.id = bot.transformers.snowflake(payload.id); + if (props.type && payload.type) webhook.type = payload.type; + if (props.guildId && payload.guild_id) webhook.guildId = bot.transformers.snowflake(payload.guild_id); + if (props.channelId && payload.channel_id) webhook.channelId = bot.transformers.snowflake(payload.channel_id); + if (props.user && payload.user) webhook.user = bot.transformers.user(bot, payload.user); + if (props.name && payload.name) webhook.name = payload.name; + if (props.avatar && payload.avatar) webhook.avatar = iconHashToBigInt(payload.avatar); + if (props.token && payload.token) webhook.token = payload.token; + if (props.applicationId && payload.application_id) webhook.applicationId = bot.transformers.snowflake(payload.application_id); if (props.sourceGuild && payload.source_guild) webhook.sourceGuild = { id: bot.transformers.snowflake(payload.source_guild.id!), name: payload.source_guild.name!, icon: payload.source_guild.icon ? iconHashToBigInt(payload.source_guild.icon) : undefined, - } + }; if (props.sourceChannel && payload.source_channel) // @ts-expect-error TODO: Partials - webhook.sourceChannel = bot.transformers.channel(bot, payload.source_channel, { guildId: payload.guild_id }) - if (props.url && payload.url) webhook.url = payload.url + webhook.sourceChannel = bot.transformers.channel(bot, payload.source_channel, { guildId: payload.guild_id }); + if (props.url && payload.url) webhook.url = payload.url; - return bot.transformers.customizers.webhook(bot, payload, webhook) + return bot.transformers.customizers.webhook(bot, payload, webhook); } diff --git a/packages/bot/src/transformers/welcomeScreen.ts b/packages/bot/src/transformers/welcomeScreen.ts index 92baf854b..0aba2d2d3 100644 --- a/packages/bot/src/transformers/welcomeScreen.ts +++ b/packages/bot/src/transformers/welcomeScreen.ts @@ -1,6 +1,6 @@ -import type { DiscordWelcomeScreen } from '@discordeno/types' -import type { Bot } from '../bot.js' -import type { WelcomeScreen } from './types.js' +import type { DiscordWelcomeScreen } from '@discordeno/types'; +import type { Bot } from '../bot.js'; +import type { WelcomeScreen } from './types.js'; export function transformWelcomeScreen(bot: Bot, payload: DiscordWelcomeScreen): WelcomeScreen { const welcomeScreen = { @@ -11,7 +11,7 @@ export function transformWelcomeScreen(bot: Bot, payload: DiscordWelcomeScreen): emojiId: channel.emoji_id ? bot.transformers.snowflake(channel.emoji_id) : undefined, emojiName: channel.emoji_name ?? undefined, })), - } as WelcomeScreen + } as WelcomeScreen; - return bot.transformers.customizers.welcomeScreen(bot, payload, welcomeScreen) + return bot.transformers.customizers.welcomeScreen(bot, payload, welcomeScreen); } diff --git a/packages/bot/src/transformers/widget.ts b/packages/bot/src/transformers/widget.ts index afcdb3377..c5224aade 100644 --- a/packages/bot/src/transformers/widget.ts +++ b/packages/bot/src/transformers/widget.ts @@ -1,6 +1,6 @@ -import type { DiscordGuildWidget } from '@discordeno/types' -import type { Bot } from '../bot.js' -import type { GuildWidget } from './types.js' +import type { DiscordGuildWidget } from '@discordeno/types'; +import type { Bot } from '../bot.js'; +import type { GuildWidget } from './types.js'; export function transformWidget(bot: Bot, payload: DiscordGuildWidget): GuildWidget { const widget = { @@ -12,7 +12,7 @@ export function transformWidget(bot: Bot, payload: DiscordGuildWidget): GuildWid // @ts-expect-error TODO: Deal with partials members: payload.members.map((user) => bot.transformers.user(bot, user)), presenceCount: payload.presence_count, - } as GuildWidget + } as GuildWidget; - return bot.transformers.customizers.widget(bot, payload, widget) + return bot.transformers.customizers.widget(bot, payload, widget); } diff --git a/packages/bot/src/transformers/widgetSettings.ts b/packages/bot/src/transformers/widgetSettings.ts index 8618cbc6c..9945f6d50 100644 --- a/packages/bot/src/transformers/widgetSettings.ts +++ b/packages/bot/src/transformers/widgetSettings.ts @@ -1,12 +1,12 @@ -import type { DiscordGuildWidgetSettings } from '@discordeno/types' -import type { Bot } from '../bot.js' -import type { GuildWidgetSettings } from './types.js' +import type { DiscordGuildWidgetSettings } from '@discordeno/types'; +import type { Bot } from '../bot.js'; +import type { GuildWidgetSettings } from './types.js'; export function transformWidgetSettings(bot: Bot, payload: DiscordGuildWidgetSettings): GuildWidgetSettings { const widget = { enabled: payload.enabled, channelId: payload.channel_id ?? undefined, - } + }; - return bot.transformers.customizers.widgetSettings(bot, payload, widget) + return bot.transformers.customizers.widgetSettings(bot, payload, widget); } diff --git a/packages/bot/tests/e2e/constants.ts b/packages/bot/tests/e2e/constants.ts index 6f0ba13b2..dc96e2a00 100644 --- a/packages/bot/tests/e2e/constants.ts +++ b/packages/bot/tests/e2e/constants.ts @@ -1,9 +1,9 @@ -import dotenv from 'dotenv' +import dotenv from 'dotenv'; -dotenv.config({ path: '../../.env' }) +dotenv.config({ path: '../../.env' }); -if (!process.env.DISCORD_TOKEN) throw new Error('Token was not provided.') -export const token = process.env.DISCORD_TOKEN +if (!process.env.DISCORD_TOKEN) throw new Error('Token was not provided.'); +export const token = process.env.DISCORD_TOKEN; -export const E2E_TEST_GUILD_ID = process.env.E2E_TEST_GUILD_ID -if (!E2E_TEST_GUILD_ID) throw new Error('A COMMUNITY guild id was not provided.') +export const E2E_TEST_GUILD_ID = process.env.E2E_TEST_GUILD_ID; +if (!E2E_TEST_GUILD_ID) throw new Error('A COMMUNITY guild id was not provided.'); diff --git a/packages/bot/tests/e2e/resetguilds.spec.ts b/packages/bot/tests/e2e/resetguilds.spec.ts index 4a55bb152..10336c484 100644 --- a/packages/bot/tests/e2e/resetguilds.spec.ts +++ b/packages/bot/tests/e2e/resetguilds.spec.ts @@ -1,23 +1,23 @@ -import { delay } from '@discordeno/utils' -import { use as chaiUse } from 'chai' -import chaiAsPromised from 'chai-as-promised' -import { describe, it } from 'mocha' -import { createBot } from '../../src/bot.js' -import { token } from './constants.js' +import { delay } from '@discordeno/utils'; +import { use as chaiUse } from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +import { describe, it } from 'mocha'; +import { createBot } from '../../src/bot.js'; +import { token } from './constants.js'; -chaiUse(chaiAsPromised) +chaiUse(chaiAsPromised); describe('[Bot] Can start and stop the bot', () => { it('Start and stop the bot', async () => { const bot = createBot({ token, desiredProperties: {}, - }) + }); - await bot.start() + await bot.start(); - await delay(5000) + await delay(5000); - await bot.shutdown() - }) -}) + await bot.shutdown(); + }); +}); diff --git a/packages/bot/tests/unit/desiredProprieties.spec.ts b/packages/bot/tests/unit/desiredProprieties.spec.ts index e719df24d..5d1efec38 100644 --- a/packages/bot/tests/unit/desiredProprieties.spec.ts +++ b/packages/bot/tests/unit/desiredProprieties.spec.ts @@ -1,24 +1,24 @@ -import { expect } from 'chai' -import { describe, it } from 'mocha' -import { createDesiredPropertiesObject } from '../../src/desiredProperties.js' +import { expect } from 'chai'; +import { describe, it } from 'mocha'; +import { createDesiredPropertiesObject } from '../../src/desiredProperties.js'; describe('desired properties', () => { it('fills defaults', () => { - const desired = createDesiredPropertiesObject({}) + const desired = createDesiredPropertiesObject({}); - expect(desired.channel.id).to.be.equal(false) - }) + expect(desired.channel.id).to.be.equal(false); + }); it('respects config', () => { - const desired = createDesiredPropertiesObject({ channel: { id: true } }) + const desired = createDesiredPropertiesObject({ channel: { id: true } }); - expect(desired.channel.id).to.be.equal(true) - expect(desired.guild.id).to.be.equal(false) - }) + expect(desired.channel.id).to.be.equal(true); + expect(desired.guild.id).to.be.equal(false); + }); it('can change default', () => { - const desired = createDesiredPropertiesObject({}, true) + const desired = createDesiredPropertiesObject({}, true); - expect(desired.channel.id).to.be.equal(true) - }) -}) + expect(desired.channel.id).to.be.equal(true); + }); +}); diff --git a/packages/bot/tests/unit/index.spec.ts b/packages/bot/tests/unit/index.spec.ts index 3ca08a54b..18a17c85c 100644 --- a/packages/bot/tests/unit/index.spec.ts +++ b/packages/bot/tests/unit/index.spec.ts @@ -1,7 +1,7 @@ -import { describe, it } from 'mocha' +import { describe, it } from 'mocha'; describe('index.ts', () => { it('will import without error', async () => { - await import('../../src/index.js') - }) -}) + await import('../../src/index.js'); + }); +}); diff --git a/packages/discordeno/src/index.ts b/packages/discordeno/src/index.ts index 32cd6dc65..81b2eb951 100644 --- a/packages/discordeno/src/index.ts +++ b/packages/discordeno/src/index.ts @@ -1 +1 @@ -export * from '@discordeno/bot' +export * from '@discordeno/bot'; diff --git a/packages/discordeno/tests/index.spec.ts b/packages/discordeno/tests/index.spec.ts index 4cc609818..cf4daa90a 100644 --- a/packages/discordeno/tests/index.spec.ts +++ b/packages/discordeno/tests/index.spec.ts @@ -1,7 +1,7 @@ -import { describe, it } from 'mocha' +import { describe, it } from 'mocha'; describe('index.ts', () => { it('will import without error', async () => { - await import('../src/index.js') - }) -}) + await import('../src/index.js'); + }); +}); diff --git a/packages/gateway/src/Shard.ts b/packages/gateway/src/Shard.ts index e5262b495..9a75efd8f 100644 --- a/packages/gateway/src/Shard.ts +++ b/packages/gateway/src/Shard.ts @@ -1,10 +1,10 @@ -import { Buffer } from 'node:buffer' -import zlib from 'node:zlib' -import type { DiscordGatewayPayload, DiscordHello, DiscordReady, DiscordUpdatePresence } from '@discordeno/types' -import { GatewayCloseEventCodes, GatewayOpcodes } from '@discordeno/types' -import { delay, LeakyBucket, logger } from '@discordeno/utils' -import type { Decompress as FZstdDecompress } from 'fzstd' -import NodeWebSocket from 'ws' +import { Buffer } from 'node:buffer'; +import zlib from 'node:zlib'; +import type { DiscordGatewayPayload, DiscordHello, DiscordReady, DiscordUpdatePresence } from '@discordeno/types'; +import { GatewayCloseEventCodes, GatewayOpcodes } from '@discordeno/types'; +import { delay, LeakyBucket, logger } from '@discordeno/utils'; +import type { Decompress as FZstdDecompress } from 'fzstd'; +import NodeWebSocket from 'ws'; import { type ShardEvents, type ShardGatewayConfig, @@ -13,48 +13,48 @@ import { type ShardSocketRequest, ShardState, TransportCompression, -} from './types.js' +} from './types.js'; -const ZLIB_SYNC_FLUSH = new Uint8Array([0x0, 0x0, 0xff, 0xff]) +const ZLIB_SYNC_FLUSH = new Uint8Array([0x0, 0x0, 0xff, 0xff]); -let fzstd: typeof import('fzstd') +let fzstd: typeof import('fzstd'); /** Since fzstd is an optional dependency, we need to import it lazily. */ async function getFZStd() { - return (fzstd ??= await import('fzstd')) + return (fzstd ??= await import('fzstd')); } export class DiscordenoShard { /** The id of the shard. */ - id: number + id: number; /** The connection config details that this shard will used to connect to discord. */ - connection: ShardGatewayConfig + connection: ShardGatewayConfig; /** This contains all the heartbeat information */ - heart: ShardHeart + heart: ShardHeart; /** The maximum of requests which can be send to discord per rate limit tick. Typically this value should not be changed. */ - maxRequestsPerRateLimitTick: number = 120 + maxRequestsPerRateLimitTick: number = 120; /** The previous payload sequence number. */ - previousSequenceNumber: number | null = null + previousSequenceNumber: number | null = null; /** In which interval (in milliseconds) the gateway resets it's rate limit. */ - rateLimitResetInterval: number = 60000 + rateLimitResetInterval: number = 60000; /** Current session id of the shard if present. */ - sessionId?: string + sessionId?: string; /** This contains the WebSocket connection to Discord, if currently connected. */ - socket?: WebSocket + socket?: WebSocket; /** Current internal state of the this. */ - state = ShardState.Offline + state = ShardState.Offline; /** The url provided by discord to use when resuming a connection for this this. */ - resumeGatewayUrl: string = '' + resumeGatewayUrl: string = ''; /** The shard related event handlers. */ - events: ShardEvents = {} + events: ShardEvents = {}; /** Cache for pending gateway requests which should have been send while the gateway went offline. */ - offlineSendQueue: (() => void)[] = [] + offlineSendQueue: (() => void)[] = []; /** Resolve internal waiting states. Mapped by SelectedEvents => ResolveFunction */ - resolves = new Map<'READY' | 'RESUMED' | 'INVALID_SESSION', (payload: DiscordGatewayPayload) => void>() + resolves = new Map<'READY' | 'RESUMED' | 'INVALID_SESSION', (payload: DiscordGatewayPayload) => void>(); /** Shard bucket. Only access this if you know what you are doing. Bucket for handling shard request rate limits. */ - bucket: LeakyBucket + bucket: LeakyBucket; /** Logger for the bucket. */ - logger: Pick + logger: Pick; /** * Is the shard going offline? * @@ -64,103 +64,103 @@ export class DiscordenoShard { * @private * This is for internal purposes only, and subject to breaking changes. */ - goingOffline = false + goingOffline = false; /** Text decoder used for compressed payloads. */ - textDecoder = new TextDecoder() + textDecoder = new TextDecoder(); /** zlib Inflate or zstd decompress (from node:zlib) instance for transport payloads. */ - inflate?: zlib.Inflate | zlib.ZstdDecompress + inflate?: zlib.Inflate | zlib.ZstdDecompress; /** ZLib inflate buffer. */ - inflateBuffer: Uint8Array | null = null + inflateBuffer: Uint8Array | null = null; /** ZStd Decompress instance for ZStd-stream transport payloads. */ - zstdDecompress?: FZstdDecompress + zstdDecompress?: FZstdDecompress; /** Queue for compressed payloads for Zstd Decompress */ - decompressionPromisesQueue: ((data: DiscordGatewayPayload) => void)[] = [] + decompressionPromisesQueue: ((data: DiscordGatewayPayload) => void)[] = []; /** * A function that will be called once the socket is closed and handleClose() has finished updating internal states. * * @private * This is for internal purposes only, and subject to breaking changes. */ - resolveAfterClose?: (close: CloseEvent) => void + resolveAfterClose?: (close: CloseEvent) => void; constructor(options: ShardCreateOptions) { - this.id = options.id - this.connection = options.connection - this.events = options.events - this.logger = options.logger ?? logger + this.id = options.id; + this.connection = options.connection; + this.events = options.events; + this.logger = options.logger ?? logger; this.heart = { acknowledged: false, interval: 45000, - } + }; - if (options.requestIdentify) this.requestIdentify = options.requestIdentify - if (options.makePresence) this.makePresence = options.makePresence + if (options.requestIdentify) this.requestIdentify = options.requestIdentify; + if (options.makePresence) this.makePresence = options.makePresence; this.bucket = new LeakyBucket({ max: this.calculateSafeRequests(), refillAmount: this.calculateSafeRequests(), refillInterval: 60000, logger: this.logger, - }) + }); } /** The gateway configuration which is used to connect to Discord. */ get gatewayConfig(): ShardGatewayConfig { - return this.connection + return this.connection; } /** The url to connect to. Initially this is the discord gateway url, and then is switched to resume gateway url once a READY is received. */ get connectionUrl(): string { // Use || and not ?? here. ?? will cause a bug. - return this.resumeGatewayUrl || this.gatewayConfig.url + return this.resumeGatewayUrl || this.gatewayConfig.url; } /** Calculate the amount of requests which can safely be made per rate limit interval, before the gateway gets disconnected due to an exceeded rate limit. */ calculateSafeRequests(): number { // * 2 adds extra safety layer for discords OP 1 requests that we need to respond to - const safeRequests = this.maxRequestsPerRateLimitTick - Math.ceil(this.rateLimitResetInterval / this.heart.interval) * 2 + const safeRequests = this.maxRequestsPerRateLimitTick - Math.ceil(this.rateLimitResetInterval / this.heart.interval) * 2; - return safeRequests < 0 ? 0 : safeRequests + return safeRequests < 0 ? 0 : safeRequests; } async checkOffline(highPriority: boolean): Promise { - if (this.isOpen()) return + if (this.isOpen()) return; return await new Promise((resolve) => { // Higher priority requests get added at the beginning of the array. - if (highPriority) this.offlineSendQueue.unshift(resolve) - else this.offlineSendQueue.push(resolve) - }) + if (highPriority) this.offlineSendQueue.unshift(resolve); + else this.offlineSendQueue.push(resolve); + }); } /** Close the socket connection to discord if present. */ async close(code: number, reason: string): Promise { - this.logger.debug(`[Shard] Request for Shard #${this.id} to close the socket with code ${code}.`) + this.logger.debug(`[Shard] Request for Shard #${this.id} to close the socket with code ${code}.`); if (this.socket?.readyState !== NodeWebSocket.OPEN) { - this.logger.debug(`[Shard] Shard #${this.id}'s ready state is ${this.socket?.readyState}, Unable to close.`) - return + this.logger.debug(`[Shard] Shard #${this.id}'s ready state is ${this.socket?.readyState}, Unable to close.`); + return; } - this.goingOffline = code === GatewayCloseEventCodes.NormalClosure || code === GatewayCloseEventCodes.GoingAway + this.goingOffline = code === GatewayCloseEventCodes.NormalClosure || code === GatewayCloseEventCodes.GoingAway; // This has to be created before the actual call to socket.close as for example Bun calls socket.onclose immediately on the .close() call instead of waiting for the connection to end const promise = new Promise((resolve) => { - this.resolveAfterClose = resolve - }) + this.resolveAfterClose = resolve; + }); - this.socket.close(code, reason) + this.socket.close(code, reason); - this.logger.debug(`[Shard] Waiting for Shard #${this.id} to close the socket with code ${code}.`) + this.logger.debug(`[Shard] Waiting for Shard #${this.id} to close the socket with code ${code}.`); // We need to wait for the socket to be fully closed, otherwise there'll be race condition issues if we try to connect again, resulting in unexpected behavior. - await promise + await promise; - this.logger.debug(`[Shard] Shard #${this.id} closed the socket with code ${code}.`) + this.logger.debug(`[Shard] Shard #${this.id} closed the socket with code ${code}.`); // Reset the resolveAfterClose function after it has been resolved. - this.resolveAfterClose = undefined + this.resolveAfterClose = undefined; } /** Connect the shard with the gateway and start heartbeating. This will not identify the shard to the gateway. */ @@ -168,129 +168,129 @@ export class DiscordenoShard { // Only set the shard to `Connecting` state, // if the connection request does not come from an identify or resume action. if (![ShardState.Identifying, ShardState.Resuming].includes(this.state)) { - this.state = ShardState.Connecting + this.state = ShardState.Connecting; } - this.logger.debug(`[Shard] Connecting Shard #${this.id} socket.`) + this.logger.debug(`[Shard] Connecting Shard #${this.id} socket.`); - this.events.connecting?.(this) + this.events.connecting?.(this); - const url = new URL(this.connectionUrl) - url.searchParams.set('v', this.gatewayConfig.version.toString()) - url.searchParams.set('encoding', 'json') + const url = new URL(this.connectionUrl); + url.searchParams.set('v', this.gatewayConfig.version.toString()); + url.searchParams.set('encoding', 'json'); // Set the compress url param and initialize the decompression contexts if (this.gatewayConfig.transportCompression) { - url.searchParams.set('compress', this.gatewayConfig.transportCompression) + url.searchParams.set('compress', this.gatewayConfig.transportCompression); if (this.gatewayConfig.transportCompression === TransportCompression.zlib) { - this.inflateBuffer = null + this.inflateBuffer = null; this.inflate = zlib.createInflate({ finishFlush: zlib.constants.Z_SYNC_FLUSH, chunkSize: 64 * 1024, - }) + }); this.inflate.on('error', (e) => { - this.logger.error('The was an error in decompressing a ZLib compressed payload', e) - }) + this.logger.error('The was an error in decompressing a ZLib compressed payload', e); + }); this.inflate.on('data', (data) => { - if (!(data instanceof Uint8Array)) return + if (!(data instanceof Uint8Array)) return; if (this.inflateBuffer) { - const newBuffer = new Uint8Array(this.inflateBuffer.byteLength + data.byteLength) - newBuffer.set(this.inflateBuffer) - newBuffer.set(data, this.inflateBuffer.byteLength) - this.inflateBuffer = newBuffer + const newBuffer = new Uint8Array(this.inflateBuffer.byteLength + data.byteLength); + newBuffer.set(this.inflateBuffer); + newBuffer.set(data, this.inflateBuffer.byteLength); + this.inflateBuffer = newBuffer; - return + return; } - this.inflateBuffer = data - }) + this.inflateBuffer = data; + }); } if (this.gatewayConfig.transportCompression === TransportCompression.zstd) { if ('createZstdDecompress' in zlib) { - this.logger.debug('[Shard] Using node:zlib zstd decompression.') + this.logger.debug('[Shard] Using node:zlib zstd decompression.'); - this.inflateBuffer = null + this.inflateBuffer = null; this.inflate = zlib.createZstdDecompress({ chunkSize: 64 * 1024, - }) + }); this.inflate.on('error', (e) => { - this.logger.error('The was an error in decompressing a Zstd compressed payload', e) - }) + this.logger.error('The was an error in decompressing a Zstd compressed payload', e); + }); this.inflate.on('data', (data) => { - if (!(data instanceof Uint8Array)) return + if (!(data instanceof Uint8Array)) return; if (this.inflateBuffer) { - const newBuffer = new Uint8Array(this.inflateBuffer.byteLength + data.byteLength) - newBuffer.set(this.inflateBuffer) - newBuffer.set(data, this.inflateBuffer.byteLength) - this.inflateBuffer = newBuffer + const newBuffer = new Uint8Array(this.inflateBuffer.byteLength + data.byteLength); + newBuffer.set(this.inflateBuffer); + newBuffer.set(data, this.inflateBuffer.byteLength); + this.inflateBuffer = newBuffer; - return + return; } - this.inflateBuffer = data - }) + this.inflateBuffer = data; + }); } else { const fzstd = await getFZStd().catch(() => { - this.logger.warn('[Shard] "fzstd" is not installed. Disabled transport compression.') - url.searchParams.delete('compress') + this.logger.warn('[Shard] "fzstd" is not installed. Disabled transport compression.'); + url.searchParams.delete('compress'); - return null - }) + return null; + }); if (fzstd) { - this.logger.debug('[Shard] Using fzstd zstd decompression.') + this.logger.debug('[Shard] Using fzstd zstd decompression.'); this.zstdDecompress = new fzstd.Decompress((data) => { - const decodedData = this.textDecoder.decode(data) - const parsedData = JSON.parse(decodedData) - this.decompressionPromisesQueue.shift()?.(parsedData) - }) + const decodedData = this.textDecoder.decode(data); + const parsedData = JSON.parse(decodedData); + this.decompressionPromisesQueue.shift()?.(parsedData); + }); } } } } if (this.gatewayConfig.compress && this.gatewayConfig.transportCompression) { - this.logger.warn('[Shard] Payload compression has been disabled since transport compression is enabled as well.') - this.gatewayConfig.compress = false + this.logger.warn('[Shard] Payload compression has been disabled since transport compression is enabled as well.'); + this.gatewayConfig.compress = false; } // We check for built-in WebSocket implementations in Bun or Deno, NodeJS v22 has an implementation too but it seems to be less optimized so for now it is better to use the ws npm package - const shouldUseBuiltin = Reflect.has(globalThis, 'WebSocket') && (Reflect.has(globalThis, 'Bun') || Reflect.has(globalThis, 'Deno')) + const shouldUseBuiltin = Reflect.has(globalThis, 'WebSocket') && (Reflect.has(globalThis, 'Bun') || Reflect.has(globalThis, 'Deno')); // @ts-expect-error NodeWebSocket doesn't support "dispatchEvent", and while we don't use it, it is required on the "WebSocket" type - const socket: WebSocket = shouldUseBuiltin ? new WebSocket(url) : new NodeWebSocket(url) - this.socket = socket + const socket: WebSocket = shouldUseBuiltin ? new WebSocket(url) : new NodeWebSocket(url); + this.socket = socket; // By default WebSocket will give us a Blob, this changes it so that it gives us an ArrayBuffer - socket.binaryType = 'arraybuffer' + socket.binaryType = 'arraybuffer'; - socket.onerror = (event) => this.handleError(event) - socket.onclose = (closeEvent) => this.handleClose(closeEvent) - socket.onmessage = (messageEvent) => this.handleMessage(messageEvent) + socket.onerror = (event) => this.handleError(event); + socket.onclose = (closeEvent) => this.handleClose(closeEvent); + socket.onmessage = (messageEvent) => this.handleMessage(messageEvent); return await new Promise((resolve) => { socket.onopen = () => { // Only set the shard to `Unidentified` state if the connection request does not come from an identify or resume action. if (![ShardState.Identifying, ShardState.Resuming].includes(this.state)) { - this.state = ShardState.Unidentified + this.state = ShardState.Unidentified; } - this.logger.debug(`[Shard] Shard #${this.id} socket connected.`) + this.logger.debug(`[Shard] Shard #${this.id} socket connected.`); - this.events.connected?.(this) + this.events.connected?.(this); - resolve(this) - } - }) + resolve(this); + }; + }); } /** @@ -301,25 +301,25 @@ export class DiscordenoShard { // A new identify has been requested even though there is already a connection open. // Therefore we need to close the old connection and heartbeating before creating a new one. if (this.isOpen()) { - this.logger.debug(`[Shard] Identifying open Shard #${this.id}, closing the connection`) - await this.close(ShardSocketCloseCodes.ReIdentifying, 'Re-identifying closure of old connection.') + this.logger.debug(`[Shard] Identifying open Shard #${this.id}, closing the connection`); + await this.close(ShardSocketCloseCodes.ReIdentifying, 'Re-identifying closure of old connection.'); } if (!bypassRequest) { - await this.requestIdentify() + await this.requestIdentify(); } - this.state = ShardState.Identifying - this.events.identifying?.(this) + this.state = ShardState.Identifying; + this.events.identifying?.(this); // It is possible that the shard is in Heartbeating state but not identified, // so check whether there is already a gateway connection existing. // If not we need to create one before we identify. if (!this.isOpen()) { - await this.connect() + await this.connect(); } - this.logger.debug(`[Shard] Sending Identify payload for Shard #${this.id}.`) + this.logger.debug(`[Shard] Sending Identify payload for Shard #${this.id}.`); this.send( { @@ -334,51 +334,51 @@ export class DiscordenoShard { }, }, true, - ) + ); return await new Promise((resolve) => { this.resolves.set('READY', () => { - resolve() - }) + resolve(); + }); // When identifying too fast, Discord sends an invalid session payload. // This can safely be ignored though and the shard starts a new identify action. this.resolves.set('INVALID_SESSION', () => { - this.resolves.delete('READY') - resolve() - }) - }) + this.resolves.delete('READY'); + resolve(); + }); + }); } /** Check whether the connection to Discord is currently open. */ isOpen(): boolean { - return this.socket?.readyState === NodeWebSocket.OPEN + return this.socket?.readyState === NodeWebSocket.OPEN; } /** Attempt to resume the previous shards session with the gateway. */ async resume(): Promise { - this.logger.debug(`[Shard] Resuming Shard #${this.id}`) + this.logger.debug(`[Shard] Resuming Shard #${this.id}`); // It has been requested to resume the Shards session. // It's possible that the shard is still connected with Discord's gateway therefore we need to forcefully close it. if (this.isOpen()) { - this.logger.debug(`[Shard] Resuming open Shard #${this.id}, closing the connection`) - await this.close(ShardSocketCloseCodes.ResumeClosingOldConnection, 'Reconnecting the shard, closing old connection.') + this.logger.debug(`[Shard] Resuming open Shard #${this.id}, closing the connection`); + await this.close(ShardSocketCloseCodes.ResumeClosingOldConnection, 'Reconnecting the shard, closing old connection.'); } // Shard has never identified, so we cannot resume. if (!this.sessionId) { - this.logger.debug(`[Shard] Trying to resume Shard #${this.id} without the session id. Identifying the shard instead.`) + this.logger.debug(`[Shard] Trying to resume Shard #${this.id} without the session id. Identifying the shard instead.`); - await this.identify() - return + await this.identify(); + return; } - this.state = ShardState.Resuming + this.state = ShardState.Resuming; // Before we can resume, we need to create a new connection with Discord's gateway. - await this.connect() + await this.connect(); - this.logger.debug(`[Shard] Resuming Shard #${this.id} connected. Session id: ${this.sessionId} | Sequence: ${this.previousSequenceNumber}`) + this.logger.debug(`[Shard] Resuming Shard #${this.id} connected. Session id: ${this.sessionId} | Sequence: ${this.previousSequenceNumber}`); this.send( { @@ -390,18 +390,18 @@ export class DiscordenoShard { }, }, true, - ) + ); return await new Promise((resolve) => { - this.resolves.set('RESUMED', () => resolve()) + this.resolves.set('RESUMED', () => resolve()); // If it is attempted to resume with an invalid session id, Discord sends an invalid session payload // Not erroring here since it is easy that this happens, also it would be not catchable this.resolves.set('INVALID_SESSION', () => { - this.resolves.delete('RESUMED') - resolve() - }) - }) + this.resolves.delete('RESUMED'); + resolve(); + }); + }); } /** @@ -411,59 +411,59 @@ export class DiscordenoShard { async send(message: ShardSocketRequest, highPriority: boolean = false): Promise { // Before acquiring a token from the bucket, check whether the shard is currently offline or not. // Else bucket and token wait time just get wasted. - await this.checkOffline(highPriority) + await this.checkOffline(highPriority); - await this.bucket.acquire(highPriority) + await this.bucket.acquire(highPriority); // It's possible, that the shard went offline after a token has been acquired from the bucket. - await this.checkOffline(highPriority) + await this.checkOffline(highPriority); - this.socket?.send(JSON.stringify(message)) + this.socket?.send(JSON.stringify(message)); } /** Shutdown the this. Forcefully disconnect the shard from Discord. The shard may not attempt to reconnect with Discord. */ async shutdown(): Promise { - await this.close(ShardSocketCloseCodes.Shutdown, 'Shard shutting down.') - this.state = ShardState.Offline + await this.close(ShardSocketCloseCodes.Shutdown, 'Shard shutting down.'); + this.state = ShardState.Offline; } /** Handle a gateway connection error */ handleError(error: Event): void { - this.logger.error(`[Shard] There was an error connecting Shard #${this.id}.`, error) + this.logger.error(`[Shard] There was an error connecting Shard #${this.id}.`, error); } /** Handle a gateway connection close. */ async handleClose(close: CloseEvent): Promise { - this.socket = undefined - this.stopHeartbeating() + this.socket = undefined; + this.stopHeartbeating(); // Clear the zlib/zstd data - this.inflate = undefined - this.zstdDecompress = undefined - this.inflateBuffer = null - this.decompressionPromisesQueue = [] + this.inflate = undefined; + this.zstdDecompress = undefined; + this.inflateBuffer = null; + this.decompressionPromisesQueue = []; - this.logger.debug(`[Shard] Shard #${this.id} closed with code ${close.code}${close.reason ? `, and reason: ${close.reason}` : ''}.`) + this.logger.debug(`[Shard] Shard #${this.id} closed with code ${close.code}${close.reason ? `, and reason: ${close.reason}` : ''}.`); // Resolve the close promise if it exists - this.resolveAfterClose?.(close) + this.resolveAfterClose?.(close); switch (close.code) { case ShardSocketCloseCodes.TestingFinished: { - this.state = ShardState.Offline - this.events.disconnected?.(this) + this.state = ShardState.Offline; + this.events.disconnected?.(this); - return + return; } // On these codes a manual start will be done. case ShardSocketCloseCodes.Shutdown: case ShardSocketCloseCodes.ReIdentifying: case ShardSocketCloseCodes.Resharded: case ShardSocketCloseCodes.ResumeClosingOldConnection: { - this.state = ShardState.Disconnected - this.events.disconnected?.(this) + this.state = ShardState.Disconnected; + this.events.disconnected?.(this); - return + return; } // When these codes are received something went really wrong. // On those we cannot start a reconnect attempt. @@ -473,33 +473,33 @@ export class DiscordenoShard { case GatewayCloseEventCodes.InvalidApiVersion: case GatewayCloseEventCodes.InvalidIntents: case GatewayCloseEventCodes.DisallowedIntents: { - this.state = ShardState.Offline - this.events.disconnected?.(this) + this.state = ShardState.Offline; + this.events.disconnected?.(this); - throw new Error(close.reason || 'Discord gave no reason! GG! You broke Discord!') + throw new Error(close.reason || 'Discord gave no reason! GG! You broke Discord!'); } // Gateway connection closes which require a new identify. case GatewayCloseEventCodes.NotAuthenticated: case GatewayCloseEventCodes.InvalidSeq: case GatewayCloseEventCodes.SessionTimedOut: { - this.logger.debug(`[Shard] Shard #${this.id} closed requiring re-identify.`) - this.state = ShardState.Identifying - this.events.disconnected?.(this) + this.logger.debug(`[Shard] Shard #${this.id} closed requiring re-identify.`); + this.state = ShardState.Identifying; + this.events.disconnected?.(this); - await this.identify() - return + await this.identify(); + return; } // NOTE: This case must always be right above the cases that runs with default case because of how switch works when you don't break / return, more info below. case GatewayCloseEventCodes.NormalClosure: case GatewayCloseEventCodes.GoingAway: { // If the shard is marked as goingOffline, it stays disconnected. if (this.goingOffline) { - this.state = ShardState.Disconnected - this.events.disconnected?.(this) + this.state = ShardState.Disconnected; + this.events.disconnected?.(this); - this.goingOffline = false + this.goingOffline = false; - return + return; } // Otherwise, we want the shard to go through the default case where it gets resumed, as it might be an unexpected closure from Discord or Cloudflare for example, so we don't use break / return here. @@ -512,16 +512,16 @@ export class DiscordenoShard { case GatewayCloseEventCodes.AlreadyAuthenticated: default: { // We don't want to get into an infinite loop where we resume forever, so if we were already resuming we identify instead - this.state = this.state === ShardState.Resuming ? ShardState.Identifying : ShardState.Resuming - this.events.disconnected?.(this) + this.state = this.state === ShardState.Resuming ? ShardState.Identifying : ShardState.Resuming; + this.events.disconnected?.(this); if (this.state === ShardState.Resuming) { - await this.resume() + await this.resume(); } else { - await this.identify() + await this.identify(); } - return + return; } } } @@ -529,14 +529,14 @@ export class DiscordenoShard { /** Handle an incoming gateway message. */ async handleMessage(message: MessageEvent): Promise { // The ws npm package will use a Buffer, while the global built-in will use ArrayBuffer - const isCompressed = message.data instanceof ArrayBuffer || message.data instanceof Buffer + const isCompressed = message.data instanceof ArrayBuffer || message.data instanceof Buffer; - const data = isCompressed ? await this.decompressPacket(message.data) : (JSON.parse(message.data) as DiscordGatewayPayload) + const data = isCompressed ? await this.decompressPacket(message.data) : (JSON.parse(message.data) as DiscordGatewayPayload); // Check if the decompression was not successful - if (!data) return + if (!data) return; - await this.handleDiscordPacket(data) + await this.handleDiscordPacket(data); } /** @@ -546,91 +546,91 @@ export class DiscordenoShard { */ async decompressPacket(data: ArrayBuffer | Buffer): Promise { // A buffer is a Uint8Array under the hood. An ArrayBuffer is generic, so we need to create the Uint8Array that uses the whole ArrayBuffer - const compressedData: Uint8Array = data instanceof Buffer ? data : new Uint8Array(data) + const compressedData: Uint8Array = data instanceof Buffer ? data : new Uint8Array(data); if (this.gatewayConfig.transportCompression === TransportCompression.zlib) { if (!this.inflate) { - this.logger.fatal('[Shard] zlib-stream transport compression was enabled but no instance of Inflate was found.') - return null + this.logger.fatal('[Shard] zlib-stream transport compression was enabled but no instance of Inflate was found.'); + return null; } // Alias, used to avoid some null checks in the Promise constructor - const inflate = this.inflate + const inflate = this.inflate; const writePromise = new Promise((resolve, reject) => { - inflate.write(compressedData, 'binary', (error) => (error ? reject(error) : resolve())) - }) + inflate.write(compressedData, 'binary', (error) => (error ? reject(error) : resolve())); + }); - if (!endsWithMarker(compressedData, ZLIB_SYNC_FLUSH)) return null + if (!endsWithMarker(compressedData, ZLIB_SYNC_FLUSH)) return null; - await writePromise + await writePromise; if (!this.inflateBuffer) { - this.logger.warn('[Shard] The ZLib inflate buffer was cleared at an unexpected moment.') - return null + this.logger.warn('[Shard] The ZLib inflate buffer was cleared at an unexpected moment.'); + return null; } - const decodedData = this.textDecoder.decode(this.inflateBuffer) - this.inflateBuffer = null + const decodedData = this.textDecoder.decode(this.inflateBuffer); + this.inflateBuffer = null; - return JSON.parse(decodedData) + return JSON.parse(decodedData); } if (this.gatewayConfig.transportCompression === TransportCompression.zstd) { if (this.zstdDecompress) { - this.zstdDecompress.push(compressedData) + this.zstdDecompress.push(compressedData); - const decompressionPromise = new Promise((r) => this.decompressionPromisesQueue.push(r)) - return await decompressionPromise + const decompressionPromise = new Promise((r) => this.decompressionPromisesQueue.push(r)); + return await decompressionPromise; } if (this.inflate) { // Alias, used to avoid some null checks in the Promise constructor - const decompress = this.inflate + const decompress = this.inflate; const writePromise = new Promise((resolve, reject) => { - decompress.write(compressedData, 'binary', (error) => (error ? reject(error) : resolve())) - }) + decompress.write(compressedData, 'binary', (error) => (error ? reject(error) : resolve())); + }); - await writePromise + await writePromise; if (!this.inflateBuffer) { - this.logger.warn('[Shard] The ZLib inflate buffer was cleared at an unexpected moment.') - return null + this.logger.warn('[Shard] The ZLib inflate buffer was cleared at an unexpected moment.'); + return null; } - const decodedData = this.textDecoder.decode(this.inflateBuffer) - this.inflateBuffer = null + const decodedData = this.textDecoder.decode(this.inflateBuffer); + this.inflateBuffer = null; - return JSON.parse(decodedData) + return JSON.parse(decodedData); } - this.logger.fatal('[Shard] zstd-stream transport compression was enabled but no zstd decompressor was found.') - return null + this.logger.fatal('[Shard] zstd-stream transport compression was enabled but no zstd decompressor was found.'); + return null; } if (this.gatewayConfig.compress) { - const decompressed = zlib.inflateSync(compressedData) - const decodedData = this.textDecoder.decode(decompressed) + const decompressed = zlib.inflateSync(compressedData); + const decodedData = this.textDecoder.decode(decompressed); - return JSON.parse(decodedData) + return JSON.parse(decodedData); } - return null + return null; } /** Handles a incoming gateway packet. */ async handleDiscordPacket(packet: DiscordGatewayPayload): Promise { // Edge case start: https://github.com/discordeno/discordeno/issues/2311 - this.heart.lastAck = Date.now() - this.heart.acknowledged = true + this.heart.lastAck = Date.now(); + this.heart.acknowledged = true; // Edge case end! switch (packet.op) { case GatewayOpcodes.Heartbeat: { - if (!this.isOpen()) return + if (!this.isOpen()) return; - this.heart.lastBeat = Date.now() + this.heart.lastBeat = Date.now(); // Discord randomly sends this requiring an immediate heartbeat back. // Using a direct socket.send call here because heartbeat requests are reserved by us. this.socket?.send( @@ -638,18 +638,18 @@ export class DiscordenoShard { op: GatewayOpcodes.Heartbeat, d: this.previousSequenceNumber, }), - ) - this.events.heartbeat?.(this) + ); + this.events.heartbeat?.(this); - break + break; } case GatewayOpcodes.Hello: { - const interval = (packet.d as DiscordHello).heartbeat_interval - this.logger.debug(`[Shard] Shard #${this.id} received Hello`) - this.startHeartbeating(interval) + const interval = (packet.d as DiscordHello).heartbeat_interval; + this.logger.debug(`[Shard] Shard #${this.id} received Hello`); + this.startHeartbeating(interval); if (this.state !== ShardState.Resuming) { - const currentQueue = [...this.bucket.queue] + const currentQueue = [...this.bucket.queue]; // HELLO has been send on a non resume action. // This means that the shard starts a new session, // therefore the rate limit interval has been reset too. @@ -658,97 +658,97 @@ export class DiscordenoShard { refillInterval: 60000, refillAmount: this.calculateSafeRequests(), logger: this.logger, - }) + }); // Queue should not be lost on a re-identify. - this.bucket.queue.unshift(...currentQueue) + this.bucket.queue.unshift(...currentQueue); } - this.events.hello?.(this) + this.events.hello?.(this); - break + break; } case GatewayOpcodes.HeartbeatACK: { // Manually calculating the round trip time for users who need it. if (this.heart.lastBeat) { - this.heart.rtt = this.heart.lastAck - this.heart.lastBeat + this.heart.rtt = this.heart.lastAck - this.heart.lastBeat; } - this.events.heartbeatAck?.(this) + this.events.heartbeatAck?.(this); - break + break; } case GatewayOpcodes.Reconnect: { - this.logger.debug(`[Shard] Received a Reconnect for Shard #${this.id}`) - this.events.requestedReconnect?.(this) + this.logger.debug(`[Shard] Received a Reconnect for Shard #${this.id}`); + this.events.requestedReconnect?.(this); - await this.resume() + await this.resume(); - break + break; } case GatewayOpcodes.InvalidSession: { - const resumable = packet.d as boolean - this.logger.debug(`[Shard] Received Invalid Session for Shard #${this.id} with resumable as ${resumable}`) + const resumable = packet.d as boolean; + this.logger.debug(`[Shard] Received Invalid Session for Shard #${this.id} with resumable as ${resumable}`); - this.events.invalidSession?.(this, resumable) + this.events.invalidSession?.(this, resumable); // We need to wait for a random amount of time between 1 and 5 // Reference: https://discord.com/developers/docs/topics/gateway#resuming - await delay(Math.floor((Math.random() * 4 + 1) * 1000)) + await delay(Math.floor((Math.random() * 4 + 1) * 1000)); - this.resolves.get('INVALID_SESSION')?.(packet) - this.resolves.delete('INVALID_SESSION') + this.resolves.get('INVALID_SESSION')?.(packet); + this.resolves.delete('INVALID_SESSION'); // When resumable is false we need to re-identify if (!resumable) { - await this.identify() + await this.identify(); - break + break; } // The session is invalid but apparently it is resumable - await this.resume() + await this.resume(); - break + break; } } switch (packet.t) { case 'RESUMED': - this.state = ShardState.Connected - this.events.resumed?.(this) + this.state = ShardState.Connected; + this.events.resumed?.(this); - this.logger.debug(`[Shard] Shard #${this.id} received RESUMED`) + this.logger.debug(`[Shard] Shard #${this.id} received RESUMED`); // Continue the requests which have been queued since the shard went offline. - this.offlineSendQueue.forEach((resolve) => resolve()) + this.offlineSendQueue.forEach((resolve) => resolve()); // Setting the length to 0 will delete the elements in it - this.offlineSendQueue.length = 0 + this.offlineSendQueue.length = 0; - this.resolves.get('RESUMED')?.(packet) - this.resolves.delete('RESUMED') - break + this.resolves.get('RESUMED')?.(packet); + this.resolves.delete('RESUMED'); + break; case 'READY': { - const payload = packet.d as DiscordReady + const payload = packet.d as DiscordReady; // Important for future resumes. - this.resumeGatewayUrl = payload.resume_gateway_url - this.sessionId = payload.session_id + this.resumeGatewayUrl = payload.resume_gateway_url; + this.sessionId = payload.session_id; - this.state = ShardState.Connected + this.state = ShardState.Connected; - this.logger.debug(`[Shard] Shard #${this.id} received READY`) - this.events.ready?.(this) + this.logger.debug(`[Shard] Shard #${this.id} received READY`); + this.events.ready?.(this); // Continue the requests which have been queued since the shard went offline. // Important when this is a re-identify - this.offlineSendQueue.forEach((resolve) => resolve()) + this.offlineSendQueue.forEach((resolve) => resolve()); // Setting the length to 0 will delete the elements in it - this.offlineSendQueue.length = 0 + this.offlineSendQueue.length = 0; - this.resolves.get('READY')?.(packet) - this.resolves.delete('READY') - break + this.resolves.get('READY')?.(packet); + this.resolves.delete('READY'); + break; } } @@ -756,10 +756,10 @@ export class DiscordenoShard { // `s` can be either `null` or a `number`. // In order to prevent update misses when `s` is `0` we check against null. if (packet.s !== null) { - this.previousSequenceNumber = packet.s + this.previousSequenceNumber = packet.s; } - this.events.message?.(this, packet) + this.events.message?.(this, packet); } /** @@ -768,7 +768,7 @@ export class DiscordenoShard { * Passing the shard's id there to make it easier for the dev to use this function. */ async makePresence(): Promise { - return + return; } /** @@ -779,32 +779,32 @@ export class DiscordenoShard { /** Start sending heartbeat payloads to Discord in the provided interval. */ startHeartbeating(interval: number): void { - this.logger.debug(`[Shard] Start heartbeating on Shard #${this.id}`) + this.logger.debug(`[Shard] Start heartbeating on Shard #${this.id}`); // If old heartbeast exist like after resume, clear the old ones. - this.stopHeartbeating() + this.stopHeartbeating(); - this.heart.interval = interval + this.heart.interval = interval; // Only set the shard's state to `Unidentified` // if heartbeating has not been started due to an identify or resume action. if ([ShardState.Disconnected, ShardState.Offline].includes(this.state)) { - this.logger.debug(`[Shard] Shard is disconnected or offline but the heartbeat was started #${this.id}`) - this.state = ShardState.Unidentified + this.logger.debug(`[Shard] Shard is disconnected or offline but the heartbeat was started #${this.id}`); + this.state = ShardState.Unidentified; } // The first heartbeat needs to be send with a random delay between `0` and `interval` // Using a `setTimeout(_, jitter)` here to accomplish that. // `Math.random()` can be `0` so we use `0.5` if this happens // Reference: https://discord.com/developers/docs/topics/gateway#heartbeating - const jitter = Math.ceil(this.heart.interval * (Math.random() || 0.5)) + const jitter = Math.ceil(this.heart.interval * (Math.random() || 0.5)); this.heart.timeoutId = setTimeout(() => { - this.logger.debug(`[Shard] Beginning heartbeating process for Shard #${this.id}`) + this.logger.debug(`[Shard] Beginning heartbeating process for Shard #${this.id}`); - if (!this.isOpen()) return + if (!this.isOpen()) return; - this.logger.debug(`[Shard] Heartbeating on Shard #${this.id}. Previous sequence number: ${this.previousSequenceNumber}`) + this.logger.debug(`[Shard] Heartbeating on Shard #${this.id}. Previous sequence number: ${this.previousSequenceNumber}`); // Using a direct socket.send call here because heartbeat requests are reserved by us. this.socket?.send( @@ -812,16 +812,16 @@ export class DiscordenoShard { op: GatewayOpcodes.Heartbeat, d: this.previousSequenceNumber, }), - ) + ); - this.heart.lastBeat = Date.now() - this.heart.acknowledged = false + this.heart.lastBeat = Date.now(); + this.heart.acknowledged = false; // After the random heartbeat jitter we can start a normal interval. this.heart.intervalId = setInterval(async () => { if (!this.isOpen()) { - this.logger.debug(`[Shard] Shard #${this.id} is not open, but attempted heartbeat, ignoring.`) - return + this.logger.debug(`[Shard] Shard #${this.id} is not open, but attempted heartbeat, ignoring.`); + return; } // The Shard did not receive a heartbeat ACK from Discord in time, @@ -829,12 +829,12 @@ export class DiscordenoShard { // The Shard needs to start a re-identify action accordingly. // Reference: https://discord.com/developers/docs/topics/gateway#heartbeating-example-gateway-heartbeat-ack if (!this.heart.acknowledged) { - this.logger.debug(`[Shard] Heartbeat not acknowledged for Shard #${this.id}. Assuming zombied connection.`) - await this.close(ShardSocketCloseCodes.ZombiedConnection, 'Zombied connection, did not receive an heartbeat ACK in time.') - return + this.logger.debug(`[Shard] Heartbeat not acknowledged for Shard #${this.id}. Assuming zombied connection.`); + await this.close(ShardSocketCloseCodes.ZombiedConnection, 'Zombied connection, did not receive an heartbeat ACK in time.'); + return; } - this.logger.debug(`[Shard] Heartbeating on Shard #${this.id}. Previous sequence number: ${this.previousSequenceNumber}`) + this.logger.debug(`[Shard] Heartbeating on Shard #${this.id}. Previous sequence number: ${this.previousSequenceNumber}`); // Using a direct socket.send call here because heartbeat requests are reserved by us. this.socket?.send( @@ -842,50 +842,50 @@ export class DiscordenoShard { op: GatewayOpcodes.Heartbeat, d: this.previousSequenceNumber, }), - ) + ); - this.heart.lastBeat = Date.now() - this.heart.acknowledged = false + this.heart.lastBeat = Date.now(); + this.heart.acknowledged = false; - this.events.heartbeat?.(this) - }, this.heart.interval) - }, jitter) + this.events.heartbeat?.(this); + }, this.heart.interval); + }, jitter); } /** Stop the heartbeating process with discord. */ stopHeartbeating(): void { // Clear the regular heartbeat interval. - clearInterval(this.heart.intervalId) + clearInterval(this.heart.intervalId); // It's possible that the Shard got closed before the first jittered heartbeat. // To go safe we should clear the related timeout too. - clearTimeout(this.heart.timeoutId) + clearTimeout(this.heart.timeoutId); } } /** Check if the buffer ends with the marker */ function endsWithMarker(buffer: Uint8Array, marker: Uint8Array) { - if (buffer.length < marker.length) return false + if (buffer.length < marker.length) return false; for (let i = 0; i < marker.length; i++) { - if (buffer[buffer.length - marker.length + i] !== marker[i]) return false + if (buffer[buffer.length - marker.length + i] !== marker[i]) return false; } - return true + return true; } export interface ShardCreateOptions { /** The shard id */ - id: number + id: number; /** The connection details */ - connection: ShardGatewayConfig + connection: ShardGatewayConfig; /** The event handlers for events on the shard. */ - events: ShardEvents + events: ShardEvents; /** The logger for the shard */ - logger?: Pick + logger?: Pick; /** The handler to request a space to make an identify request. */ - requestIdentify?: () => Promise + requestIdentify?: () => Promise; /** Function to create the bot status to send on Identify requests */ - makePresence?: () => Promise + makePresence?: () => Promise; } -export default DiscordenoShard +export default DiscordenoShard; diff --git a/packages/gateway/src/index.ts b/packages/gateway/src/index.ts index ebce307e6..ef2e82b9f 100644 --- a/packages/gateway/src/index.ts +++ b/packages/gateway/src/index.ts @@ -1,3 +1,3 @@ -export * from './manager.js' -export * from './Shard.js' -export * from './types.js' +export * from './manager.js'; +export * from './Shard.js'; +export * from './types.js'; diff --git a/packages/gateway/src/manager.ts b/packages/gateway/src/manager.ts index bee4d88e4..039f96fa5 100644 --- a/packages/gateway/src/manager.ts +++ b/packages/gateway/src/manager.ts @@ -1,4 +1,4 @@ -import { randomBytes } from 'node:crypto' +import { randomBytes } from 'node:crypto'; import { type AtLeastOne, type BigString, @@ -10,10 +10,10 @@ import { GatewayIntents, GatewayOpcodes, type RequestGuildMembers, -} from '@discordeno/types' -import { Collection, jsonSafeReplacer, LeakyBucket, logger } from '@discordeno/utils' -import Shard from './Shard.js' -import { type ShardEvents, ShardSocketCloseCodes, type ShardSocketRequest, type TransportCompression, type UpdateVoiceState } from './types.js' +} from '@discordeno/types'; +import { Collection, jsonSafeReplacer, LeakyBucket, logger } from '@discordeno/utils'; +import Shard from './Shard.js'; +import { type ShardEvents, ShardSocketCloseCodes, type ShardSocketRequest, type TransportCompression, type UpdateVoiceState } from './types.js'; export function createGatewayManager(options: CreateGatewayManagerOptions): GatewayManager { const connectionOptions = options.connection ?? { @@ -25,7 +25,7 @@ export function createGatewayManager(options: CreateGatewayManagerOptions): Gate total: 1000, resetAfter: 1000 * 60 * 60 * 24, }, - } + }; const gateway: GatewayManager = { events: options.events ?? {}, @@ -66,87 +66,87 @@ export function createGatewayManager(options: CreateGatewayManagerOptions): Gate getSessionInfo: options.resharding?.getSessionInfo, updateGuildsShardId: options.resharding?.updateGuildsShardId, async checkIfReshardingIsNeeded() { - gateway.logger.debug('[Resharding] Checking if resharding is needed.') + gateway.logger.debug('[Resharding] Checking if resharding is needed.'); if (!gateway.resharding.enabled) { - gateway.logger.debug('[Resharding] Resharding is disabled.') + gateway.logger.debug('[Resharding] Resharding is disabled.'); - return { needed: false } + return { needed: false }; } if (!gateway.resharding.getSessionInfo) { - throw new Error("[Resharding] Resharding is enabled but no 'resharding.getSessionInfo()' is not provided.") + throw new Error("[Resharding] Resharding is enabled but no 'resharding.getSessionInfo()' is not provided."); } - gateway.logger.debug('[Resharding] Resharding is enabled.') + gateway.logger.debug('[Resharding] Resharding is enabled.'); - const sessionInfo = await gateway.resharding.getSessionInfo() + const sessionInfo = await gateway.resharding.getSessionInfo(); - gateway.logger.debug(`[Resharding] Session info retrieved: ${JSON.stringify(sessionInfo)}`) + gateway.logger.debug(`[Resharding] Session info retrieved: ${JSON.stringify(sessionInfo)}`); // Don't have enough identify limits to try resharding if (sessionInfo.sessionStartLimit.remaining < sessionInfo.shards) { - gateway.logger.debug('[Resharding] Not enough session start limits left to reshard.') + gateway.logger.debug('[Resharding] Not enough session start limits left to reshard.'); - return { needed: false, info: sessionInfo } + return { needed: false, info: sessionInfo }; } - gateway.logger.debug('[Resharding] Able to reshard, checking whether necessary now.') + gateway.logger.debug('[Resharding] Able to reshard, checking whether necessary now.'); // 2500 is the max amount of guilds a single shard can handle // 1000 is the amount of guilds discord uses to determine how many shards to recommend. // This algo helps check if your bot has grown enough to reshard. // While this is imprecise as discord changes the recommended number of shard every 1000 guilds it is good enough // The alternative is to store the guild count for each shard and require the Guilds intent for `GUILD_CREATE` and `GUILD_DELETE` events - const percentage = (sessionInfo.shards / ((gateway.totalShards * 2500) / 1000)) * 100 + const percentage = (sessionInfo.shards / ((gateway.totalShards * 2500) / 1000)) * 100; // Less than necessary% being used so do nothing if (percentage < gateway.resharding.shardsFullPercentage) { - gateway.logger.debug('[Resharding] Resharding not needed.') + gateway.logger.debug('[Resharding] Resharding not needed.'); - return { needed: false, info: sessionInfo } + return { needed: false, info: sessionInfo }; } - gateway.logger.info('[Resharding] Resharding is needed.') + gateway.logger.info('[Resharding] Resharding is needed.'); - return { needed: true, info: sessionInfo } + return { needed: true, info: sessionInfo }; }, async reshard(info) { - gateway.logger.info(`[Resharding] Starting the reshard process. Previous total shards: ${gateway.totalShards}`) + gateway.logger.info(`[Resharding] Starting the reshard process. Previous total shards: ${gateway.totalShards}`); // Set values on gateway - gateway.totalShards = info.shards + gateway.totalShards = info.shards; // Handles preparing mid sized bots for LBS - gateway.totalShards = gateway.calculateTotalShards() + gateway.totalShards = gateway.calculateTotalShards(); // Set first shard id if provided in info - if (typeof info.firstShardId === 'number') gateway.firstShardId = info.firstShardId + if (typeof info.firstShardId === 'number') gateway.firstShardId = info.firstShardId; // Set last shard id if provided in info - if (typeof info.lastShardId === 'number') gateway.lastShardId = info.lastShardId + if (typeof info.lastShardId === 'number') gateway.lastShardId = info.lastShardId; // If we didn't get any lastShardId, we assume all the shards are to be used - else gateway.lastShardId = gateway.totalShards - 1 - gateway.logger.info(`[Resharding] Starting the reshard process. New total shards: ${gateway.totalShards}`) + else gateway.lastShardId = gateway.totalShards - 1; + gateway.logger.info(`[Resharding] Starting the reshard process. New total shards: ${gateway.totalShards}`); // Resetting buckets - gateway.buckets.clear() + gateway.buckets.clear(); // Refilling buckets with new values - gateway.prepareBuckets() + gateway.prepareBuckets(); // Call all the buckets and tell their workers & shards to identify const promises = Array.from(gateway.buckets.entries()).map(async ([bucketId, bucket]) => { for (const worker of bucket.workers) { for (const shardId of worker.queue) { - await gateway.resharding.tellWorkerToPrepare(worker.id, shardId, bucketId) + await gateway.resharding.tellWorkerToPrepare(worker.id, shardId, bucketId); } } - }) + }); - await Promise.all(promises) + await Promise.all(promises); - gateway.logger.info(`[Resharding] All shards are now online.`) + gateway.logger.info(`[Resharding] All shards are now online.`); - await gateway.resharding.onReshardingSwitch() + await gateway.resharding.onReshardingSwitch(); }, async tellWorkerToPrepare(workerId, shardId, bucketId) { - gateway.logger.debug(`[Resharding] Telling worker to prepare. Worker: ${workerId} | Shard: ${shardId} | Bucket: ${bucketId}.`) + gateway.logger.debug(`[Resharding] Telling worker to prepare. Worker: ${workerId} | Shard: ${shardId} | Bucket: ${bucketId}.`); const shard = new Shard({ id: shardId, connection: { @@ -166,32 +166,32 @@ export function createGatewayManager(options: CreateGatewayManagerOptions): Gate await gateway.resharding.updateGuildsShardId?.( (payload.d as DiscordReady).guilds.map((g) => g.id), shardId, - ) + ); } }, }, logger: gateway.logger, requestIdentify: async () => await gateway.requestIdentify(shardId), makePresence: gateway.makePresence, - }) + }); - gateway.resharding.shards.set(shardId, shard) + gateway.resharding.shards.set(shardId, shard); - await shard.identify() + await shard.identify(); - gateway.logger.debug(`[Resharding] Shard #${shardId} identified.`) + gateway.logger.debug(`[Resharding] Shard #${shardId} identified.`); }, async onReshardingSwitch() { - gateway.logger.debug(`[Resharding] Making the switch from the old shards to the new ones.`) + gateway.logger.debug(`[Resharding] Making the switch from the old shards to the new ones.`); // Move the events from the old shards to the new ones for (const shard of gateway.resharding.shards.values()) { - shard.events = options.events ?? {} + shard.events = options.events ?? {}; } // Old shards stop processing events for (const shard of gateway.shards.values()) { - const oldHandler = shard.events.message + const oldHandler = shard.events.message; // Change with spread operator to not affect new shards, as changing anything on shard.events will directly change options.events, which changes new shards' events shard.events = { @@ -199,29 +199,29 @@ export function createGatewayManager(options: CreateGatewayManagerOptions): Gate message: async function (_, message) { // Member checks need to continue but others can stop if (message.t === 'GUILD_MEMBERS_CHUNK') { - oldHandler?.(shard, message) + oldHandler?.(shard, message); } }, - } + }; } - gateway.logger.info(`[Resharding] Shutting down old shards.`) - await gateway.shutdown(ShardSocketCloseCodes.Resharded, 'Resharded!', false) + gateway.logger.info(`[Resharding] Shutting down old shards.`); + await gateway.shutdown(ShardSocketCloseCodes.Resharded, 'Resharded!', false); - gateway.logger.info(`[Resharding] Completed.`) - gateway.shards = new Map(gateway.resharding.shards) - gateway.resharding.shards.clear() + gateway.logger.info(`[Resharding] Completed.`); + gateway.shards = new Map(gateway.resharding.shards); + gateway.resharding.shards.clear(); }, }, calculateTotalShards() { // Bots under 100k servers do not have access to LBS. if (gateway.totalShards < 100) { - gateway.logger.debug(`[Gateway] Calculating total shards: ${gateway.totalShards}`) - return gateway.totalShards + gateway.logger.debug(`[Gateway] Calculating total shards: ${gateway.totalShards}`); + return gateway.totalShards; } - gateway.logger.debug(`[Gateway] Calculating total shards`, gateway.totalShards, gateway.connection.sessionStartLimit.maxConcurrency) + gateway.logger.debug(`[Gateway] Calculating total shards`, gateway.totalShards, gateway.connection.sessionStartLimit.maxConcurrency); // Calculate a multiple of `maxConcurrency` which can be used to connect to the gateway. return ( Math.ceil( @@ -229,20 +229,20 @@ export function createGatewayManager(options: CreateGatewayManagerOptions): Gate // If `maxConcurrency` is 1, we can safely use 16 to get `totalShards` to be in a multiple of 16 so that we can prepare bots with 100k servers for LBS. (gateway.connection.sessionStartLimit.maxConcurrency === 1 ? 16 : gateway.connection.sessionStartLimit.maxConcurrency), ) * (gateway.connection.sessionStartLimit.maxConcurrency === 1 ? 16 : gateway.connection.sessionStartLimit.maxConcurrency) - ) + ); }, calculateWorkerId(shardId) { const workerId = options.spreadShardsInRoundRobin ? shardId % gateway.totalWorkers - : Math.min(Math.floor(shardId / gateway.shardsPerWorker), gateway.totalWorkers - 1) + : Math.min(Math.floor(shardId / gateway.shardsPerWorker), gateway.totalWorkers - 1); gateway.logger.debug( `[Gateway] Calculating workerId: Shard: ${shardId} -> Worker: ${workerId} -> Per Worker: ${gateway.shardsPerWorker} -> Total: ${gateway.totalWorkers}`, - ) - return workerId + ); + return workerId; }, prepareBuckets() { for (let i = 0; i < gateway.connection.sessionStartLimit.maxConcurrency; ++i) { - gateway.logger.debug(`[Gateway] Preparing buckets for concurrency: ${i}`) + gateway.logger.debug(`[Gateway] Preparing buckets for concurrency: ${i}`); gateway.buckets.set(i, { workers: [], leakyBucket: new LeakyBucket({ @@ -251,95 +251,95 @@ export function createGatewayManager(options: CreateGatewayManagerOptions): Gate refillInterval: gateway.spawnShardDelay, logger: this.logger, }), - }) + }); } // Organize all shards into their own buckets for (let shardId = gateway.firstShardId; shardId <= gateway.lastShardId; ++shardId) { - gateway.logger.debug(`[Gateway] Preparing buckets for shard: ${shardId}`) + gateway.logger.debug(`[Gateway] Preparing buckets for shard: ${shardId}`); if (shardId >= gateway.totalShards) { - throw new Error(`Shard (id: ${shardId}) is bigger or equal to the used amount of used shards which is ${gateway.totalShards}`) + throw new Error(`Shard (id: ${shardId}) is bigger or equal to the used amount of used shards which is ${gateway.totalShards}`); } - const bucketId = shardId % gateway.connection.sessionStartLimit.maxConcurrency - const bucket = gateway.buckets.get(bucketId) + const bucketId = shardId % gateway.connection.sessionStartLimit.maxConcurrency; + const bucket = gateway.buckets.get(bucketId); if (!bucket) { throw new Error( `Shard (id: ${shardId}) got assigned to an illegal bucket id: ${bucketId}, expected a bucket id between 0 and ${ gateway.connection.sessionStartLimit.maxConcurrency - 1 }`, - ) + ); } // Get the worker id for this shard - const workerId = gateway.calculateWorkerId(shardId) - const worker = bucket.workers.find((w) => w.id === workerId) + const workerId = gateway.calculateWorkerId(shardId); + const worker = bucket.workers.find((w) => w.id === workerId); // If this worker already exists, add the shard to its queue if (worker) { - worker.queue.push(shardId) + worker.queue.push(shardId); } else { - bucket.workers.push({ id: workerId, queue: [shardId] }) + bucket.workers.push({ id: workerId, queue: [shardId] }); } } }, async spawnShards() { // Prepare the concurrency buckets - gateway.prepareBuckets() + gateway.prepareBuckets(); const promises = [...gateway.buckets.entries()].map(async ([bucketId, bucket]) => { for (const worker of bucket.workers) { for (const shardId of worker.queue) { - await gateway.tellWorkerToIdentify(worker.id, shardId, bucketId) + await gateway.tellWorkerToIdentify(worker.id, shardId, bucketId); } } - }) + }); // We use Promise.all so we can start all buckets at the same time - await Promise.all(promises) + await Promise.all(promises); // Check and reshard automatically if auto resharding is enabled. if (gateway.resharding.enabled && gateway.resharding.checkInterval !== -1) { // It is better to ensure there is always only one - clearInterval(gateway.resharding.checkIntervalId) + clearInterval(gateway.resharding.checkIntervalId); if (!gateway.resharding.getSessionInfo) { - gateway.resharding.enabled = false - gateway.logger.warn("[Resharding] Resharding is enabled but 'resharding.getSessionInfo()' was not provided. Disabling resharding.") + gateway.resharding.enabled = false; + gateway.logger.warn("[Resharding] Resharding is enabled but 'resharding.getSessionInfo()' was not provided. Disabling resharding."); - return + return; } gateway.resharding.checkIntervalId = setInterval(async () => { - const reshardingInfo = await gateway.resharding.checkIfReshardingIsNeeded() + const reshardingInfo = await gateway.resharding.checkIfReshardingIsNeeded(); - if (reshardingInfo.needed && reshardingInfo.info) await gateway.resharding.reshard(reshardingInfo.info) - }, gateway.resharding.checkInterval) + if (reshardingInfo.needed && reshardingInfo.info) await gateway.resharding.reshard(reshardingInfo.info); + }, gateway.resharding.checkInterval); } }, async shutdown(code, reason, clearReshardingInterval = true) { - if (clearReshardingInterval) clearInterval(gateway.resharding.checkIntervalId) + if (clearReshardingInterval) clearInterval(gateway.resharding.checkIntervalId); - await Promise.all(Array.from(gateway.shards.values()).map((shard) => shard.close(code, reason))) + await Promise.all(Array.from(gateway.shards.values()).map((shard) => shard.close(code, reason))); }, async sendPayload(shardId, payload) { - const shard = gateway.shards.get(shardId) + const shard = gateway.shards.get(shardId); if (!shard) { - throw new Error(`Shard (id: ${shardId} not found`) + throw new Error(`Shard (id: ${shardId} not found`); } - await shard.send(payload) + await shard.send(payload); }, async tellWorkerToIdentify(workerId, shardId, bucketId) { - gateway.logger.debug(`[Gateway] Tell worker #${workerId} to identify shard #${shardId} from bucket ${bucketId}`) - await gateway.identify(shardId) + gateway.logger.debug(`[Gateway] Tell worker #${workerId} to identify shard #${shardId} from bucket ${bucketId}`); + await gateway.identify(shardId); }, async identify(shardId: number) { - let shard = this.shards.get(shardId) - gateway.logger.debug(`[Gateway] Identifying ${shard ? 'existing' : 'new'} shard (${shardId})`) + let shard = this.shards.get(shardId); + gateway.logger.debug(`[Gateway] Identifying ${shard ? 'existing' : 'new'} shard (${shardId})`); if (!shard) { shard = new Shard({ @@ -358,59 +358,59 @@ export function createGatewayManager(options: CreateGatewayManagerOptions): Gate logger: this.logger, requestIdentify: async () => await gateway.requestIdentify(shardId), makePresence: gateway.makePresence, - }) + }); - this.shards.set(shardId, shard) + this.shards.set(shardId, shard); } - await shard.identify() + await shard.identify(); }, async requestIdentify(shardId) { - gateway.logger.debug(`[Gateway] Shard #${shardId} requested an identify.`) + gateway.logger.debug(`[Gateway] Shard #${shardId} requested an identify.`); - const bucket = gateway.buckets.get(shardId % gateway.connection.sessionStartLimit.maxConcurrency) + const bucket = gateway.buckets.get(shardId % gateway.connection.sessionStartLimit.maxConcurrency); if (!bucket) { - throw new Error("Can't request identify for a shard that is not assigned to any bucket.") + throw new Error("Can't request identify for a shard that is not assigned to any bucket."); } - await bucket.leakyBucket.acquire() + await bucket.leakyBucket.acquire(); - gateway.logger.debug(`[Gateway] Approved identify request for Shard #${shardId}.`) + gateway.logger.debug(`[Gateway] Approved identify request for Shard #${shardId}.`); }, async kill(shardId: number) { - const shard = this.shards.get(shardId) + const shard = this.shards.get(shardId); if (!shard) { - gateway.logger.debug(`[Gateway] Shard #${shardId} was requested to be killed, but the shard could not be found.`) - return + gateway.logger.debug(`[Gateway] Shard #${shardId} was requested to be killed, but the shard could not be found.`); + return; } - gateway.logger.debug(`[Gateway] Killing Shard #${shardId}`) - this.shards.delete(shardId) - await shard.shutdown() + gateway.logger.debug(`[Gateway] Killing Shard #${shardId}`); + this.shards.delete(shardId); + await shard.shutdown(); }, // Helpers methods below this calculateShardId(guildId, totalShards) { // If none is provided, use the total shards number from gateway object. - if (!totalShards) totalShards = gateway.totalShards + if (!totalShards) totalShards = gateway.totalShards; // If it is only 1 shard, it will always be shard id 0 if (totalShards === 1) { - gateway.logger.debug(`[Gateway] calculateShardId (1 shard)`) - return 0 + gateway.logger.debug(`[Gateway] calculateShardId (1 shard)`); + return 0; } - gateway.logger.debug(`[Gateway] calculateShardId (guildId: ${guildId}, totalShards: ${totalShards})`) - return Number((BigInt(guildId) >> 22n) % BigInt(totalShards)) + gateway.logger.debug(`[Gateway] calculateShardId (guildId: ${guildId}, totalShards: ${totalShards})`); + return Number((BigInt(guildId) >> 22n) % BigInt(totalShards)); }, async joinVoiceChannel(guildId, channelId, options) { - const shardId = gateway.calculateShardId(guildId) + const shardId = gateway.calculateShardId(guildId); - gateway.logger.debug(`[Gateway] joinVoiceChannel guildId: ${guildId} channelId: ${channelId}`) + gateway.logger.debug(`[Gateway] joinVoiceChannel guildId: ${guildId} channelId: ${channelId}`); await gateway.sendPayload(shardId, { op: GatewayOpcodes.VoiceStateUpdate, @@ -420,21 +420,21 @@ export function createGatewayManager(options: CreateGatewayManagerOptions): Gate self_mute: options?.selfMute ?? false, self_deaf: options?.selfDeaf ?? true, }, - }) + }); }, async editBotStatus(data) { - gateway.logger.debug(`[Gateway] editBotStatus data: ${JSON.stringify(data, jsonSafeReplacer)}`) + gateway.logger.debug(`[Gateway] editBotStatus data: ${JSON.stringify(data, jsonSafeReplacer)}`); await Promise.all( [...gateway.shards.values()].map(async (shard) => { - gateway.editShardStatus(shard.id, data) + gateway.editShardStatus(shard.id, data); }), - ) + ); }, async editShardStatus(shardId, data) { - gateway.logger.debug(`[Gateway] editShardStatus shardId: ${shardId} -> data: ${JSON.stringify(data)}`) + gateway.logger.debug(`[Gateway] editShardStatus shardId: ${shardId} -> data: ${JSON.stringify(data)}`); await gateway.sendPayload(shardId, { op: GatewayOpcodes.PresenceUpdate, @@ -444,32 +444,32 @@ export function createGatewayManager(options: CreateGatewayManagerOptions): Gate activities: data.activities, status: data.status, }, - }) + }); }, async requestMembers(guildId, options) { - const shardId = gateway.calculateShardId(guildId) + const shardId = gateway.calculateShardId(guildId); if (gateway.intents && (!options?.limit || options.limit > 1) && !(gateway.intents & GatewayIntents.GuildMembers)) - throw new Error('Cannot fetch more then 1 member without the GUILD_MEMBERS intent') + throw new Error('Cannot fetch more then 1 member without the GUILD_MEMBERS intent'); - gateway.logger.debug(`[Gateway] requestMembers guildId: ${guildId} -> data: ${JSON.stringify(options)}`) + gateway.logger.debug(`[Gateway] requestMembers guildId: ${guildId} -> data: ${JSON.stringify(options)}`); if (options?.userIds?.length) { - gateway.logger.debug(`[Gateway] requestMembers guildId: ${guildId} -> setting user limit based on userIds length: ${options.userIds.length}`) + gateway.logger.debug(`[Gateway] requestMembers guildId: ${guildId} -> setting user limit based on userIds length: ${options.userIds.length}`); - options.limit = options.userIds.length + options.limit = options.userIds.length; } if (!options?.nonce) { - let nonce = '' + let nonce = ''; while (!nonce || gateway.cache.requestMembers.pending.has(nonce)) { - nonce = randomBytes(16).toString('hex') + nonce = randomBytes(16).toString('hex'); } - options ??= { limit: 0 } - options.nonce = nonce + options ??= { limit: 0 }; + options.nonce = nonce; } const members = !gateway.cache.requestMembers.enabled @@ -477,16 +477,16 @@ export function createGatewayManager(options: CreateGatewayManagerOptions): Gate : new Promise>((resolve, reject) => { // Should never happen. if (!gateway.cache.requestMembers.enabled || !options?.nonce) { - reject(new Error("Can't request the members without the nonce or with the feature disabled.")) - return + reject(new Error("Can't request the members without the nonce or with the feature disabled.")); + return; } gateway.cache.requestMembers.pending.set(options.nonce, { nonce: options.nonce, resolve, members: [], - }) - }) + }); + }); await gateway.sendPayload(shardId, { op: GatewayOpcodes.RequestGuildMembers, @@ -499,15 +499,15 @@ export function createGatewayManager(options: CreateGatewayManagerOptions): Gate user_ids: options?.userIds?.map((id) => id.toString()), nonce: options?.nonce, }, - }) + }); - return await members + return await members; }, async leaveVoiceChannel(guildId) { - const shardId = gateway.calculateShardId(guildId) + const shardId = gateway.calculateShardId(guildId); - gateway.logger.debug(`[Gateway] leaveVoiceChannel guildId: ${guildId} Shard ${shardId}`) + gateway.logger.debug(`[Gateway] leaveVoiceChannel guildId: ${guildId} Shard ${shardId}`); await gateway.sendPayload(shardId, { op: GatewayOpcodes.VoiceStateUpdate, @@ -517,7 +517,7 @@ export function createGatewayManager(options: CreateGatewayManagerOptions): Gate self_mute: false, self_deaf: false, }, - }) + }); }, async requestSoundboardSounds(guildIds) { @@ -526,15 +526,15 @@ export function createGatewayManager(options: CreateGatewayManagerOptions): Gate * For this reason we need to group the ids with the shard the calculateShardId method gives */ - const map = new Map() + const map = new Map(); for (const guildId of guildIds) { - const shardId = gateway.calculateShardId(guildId) + const shardId = gateway.calculateShardId(guildId); - const ids = map.get(shardId) ?? [] - map.set(shardId, ids) + const ids = map.get(shardId) ?? []; + map.set(shardId, ids); - ids.push(guildId) + ids.push(guildId); } await Promise.all( @@ -546,11 +546,11 @@ export function createGatewayManager(options: CreateGatewayManagerOptions): Gate }, }), ), - ) + ); }, - } + }; - return gateway + return gateway; } export interface CreateGatewayManagerOptions { @@ -558,32 +558,32 @@ export interface CreateGatewayManagerOptions { * Id of the first Shard which should get controlled by this manager. * @default 0 */ - firstShardId?: number + firstShardId?: number; /** * Id of the last Shard which should get controlled by this manager. * @default 0 */ - lastShardId?: number + lastShardId?: number; /** * Delay in milliseconds to wait before spawning next shard. OPTIMAL IS ABOVE 5100. YOU DON'T WANT TO HIT THE RATE LIMIT!!! * @default 5300 */ - spawnShardDelay?: number + spawnShardDelay?: number; /** * Total amount of shards your bot uses. Useful for zero-downtime updates or resharding. * @default 1 */ - totalShards?: number + totalShards?: number; /** * The amount of shards to load per worker. * @default 25 */ - shardsPerWorker?: number + shardsPerWorker?: number; /** * The total amount of workers to use for your bot. * @default 4 */ - totalWorkers?: number + totalWorkers?: number; /** * Whether to spread shards across workers in a round-robin manner. * @@ -596,53 +596,53 @@ export interface CreateGatewayManagerOptions { * * @default false */ - spreadShardsInRoundRobin?: boolean + spreadShardsInRoundRobin?: boolean; /** Important data which is used by the manager to connect shards to the gateway. */ - connection?: Camelize + connection?: Camelize; /** Whether incoming payloads are compressed using zlib. * * @default false */ - compress?: boolean + compress?: boolean; /** What transport compression should be used */ - transportCompression?: TransportCompression | null + transportCompression?: TransportCompression | null; /** The calculated intent value of the events which the shard should receive. * * @default 0 */ - intents?: number + intents?: number; /** Identify properties to use */ properties?: { /** Operating system the shard runs on. * * @default "darwin" | "linux" | "windows" */ - os: string + os: string; /** The "browser" where this shard is running on. * * @default "Discordeno" */ - browser: string + browser: string; /** The device on which the shard is running. * * @default "Discordeno" */ - device: string - } + device: string; + }; /** Bot token which is used to connect to Discord */ - token: string + token: string; /** The URL of the gateway which should be connected to. * * @default "wss://gateway.discord.gg" */ - url?: string + url?: string; /** The gateway version which should be used. * * @default 10 */ - version?: number + version?: number; /** The events handlers */ - events?: ShardEvents + events?: ShardEvents; /** This managers cache related settings. */ cache?: { requestMembers?: { @@ -650,28 +650,28 @@ export interface CreateGatewayManagerOptions { * Whether or not request member requests should be cached. * @default false */ - enabled?: boolean - } - } + enabled?: boolean; + }; + }; /** * The logger that the gateway manager will use. * @default logger // The logger exported by `@discordeno/utils` */ - logger?: Pick + logger?: Pick; /** * Make the presence for when the bot connects to the gateway * * @remarks * This function will be called each time a Shard is going to identify */ - makePresence?: () => Promise + makePresence?: () => Promise; /** Options related to resharding. */ resharding?: { /** * Whether or not automated resharding should be enabled. * @default true */ - enabled: boolean + enabled: boolean; /** * The % of how full a shard is when resharding should be triggered. * @@ -681,17 +681,17 @@ export interface CreateGatewayManagerOptions { * * @default 80 as in 80% */ - shardsFullPercentage: number + shardsFullPercentage: number; /** * The interval in milliseconds, of how often to check whether resharding is needed and reshard automatically. Set to -1 to disable auto resharding. * @default 28800000 (8 hours) */ - checkInterval: number + checkInterval: number; /** Handler to get shard count and other session info. */ - getSessionInfo?: () => Promise> + getSessionInfo?: () => Promise>; /** Handler to edit the shard id on any cached guilds. */ - updateGuildsShardId?: (guildIds: string[], shardId: number) => Promise - } + updateGuildsShardId?: (guildIds: string[], shardId: number) => Promise; + }; } export interface GatewayManager extends Required { @@ -699,23 +699,23 @@ export interface GatewayManager extends Required { buckets: Map< number, { - workers: Array<{ id: number; queue: number[] }> + workers: Array<{ id: number; queue: number[] }>; /** The bucket to queue the identifies. */ - leakyBucket: LeakyBucket + leakyBucket: LeakyBucket; } - > + >; /** The shards that are created. */ - shards: Map + shards: Map; /** The logger for the gateway manager. */ - logger: Pick + logger: Pick; /** Everything related to resharding. */ resharding: CreateGatewayManagerOptions['resharding'] & { /** The interval id of the check interval. This is used to clear the interval when the manager is shutdown. */ - checkIntervalId?: NodeJS.Timeout | undefined + checkIntervalId?: NodeJS.Timeout | undefined; /** Holds the shards that resharding has created. Once resharding is done, this replaces the gateway.shards */ - shards: Map + shards: Map; /** Handler to check if resharding is necessary. */ - checkIfReshardingIsNeeded: () => Promise<{ needed: boolean; info?: Camelize }> + checkIfReshardingIsNeeded: () => Promise<{ needed: boolean; info?: Camelize }>; /** * Handler to begin resharding. * @@ -723,7 +723,7 @@ export interface GatewayManager extends Required { * This function will resolve once the resharding is done. * So when all the calls to {@link tellWorkerToPrepare} and {@link onReshardingSwitch} are done. */ - reshard: (info: Camelize & { firstShardId?: number; lastShardId?: number }) => Promise + reshard: (info: Camelize & { firstShardId?: number; lastShardId?: number }) => Promise; /** * Handler to communicate to a worker that it needs to spawn a new shard and identify it for the resharding. * @@ -731,25 +731,25 @@ export interface GatewayManager extends Required { * This handler works in the same way as the {@link tellWorkerToIdentify} handler. * So you should wait for the worker to have identified the shard before resolving the promise */ - tellWorkerToPrepare: (workerId: number, shardId: number, bucketId: number) => Promise + tellWorkerToPrepare: (workerId: number, shardId: number, bucketId: number) => Promise; /** * Handle called when all the workers have finished preparing for the resharding. * * This should make the new resharded shards become the active ones and shutdown the old ones */ - onReshardingSwitch: () => Promise - } + onReshardingSwitch: () => Promise; + }; /** Determine max number of shards to use based upon the max concurrency. */ - calculateTotalShards: () => number + calculateTotalShards: () => number; /** Determine the id of the worker which is handling a shard. */ - calculateWorkerId: (shardId: number) => number + calculateWorkerId: (shardId: number) => number; /** Prepares all the buckets that are available for identifying the shards. */ - prepareBuckets: () => void + prepareBuckets: () => void; /** Start identifying all the shards. */ - spawnShards: () => Promise + spawnShards: () => Promise; /** Shutdown all shards. */ - shutdown: (code: number, reason: string, clearReshardingInterval?: boolean) => Promise - sendPayload: (shardId: number, payload: ShardSocketRequest) => Promise + shutdown: (code: number, reason: string, clearReshardingInterval?: boolean) => Promise; + sendPayload: (shardId: number, payload: ShardSocketRequest) => Promise; /** * Allows users to hook in and change to communicate to different workers across different servers or anything they like. * For example using redis pubsub to talk to other servers. @@ -757,15 +757,15 @@ export interface GatewayManager extends Required { * @remarks * This should wait for the worker to have identified the shard before resolving the returned promise */ - tellWorkerToIdentify: (workerId: number, shardId: number, bucketId: number) => Promise + tellWorkerToIdentify: (workerId: number, shardId: number, bucketId: number) => Promise; /** Tell the manager to identify a Shard. If this Shard is not already managed this will also add the Shard to the manager. */ - identify: (shardId: number) => Promise + identify: (shardId: number) => Promise; /** Kill a shard. Close a shards connection to Discord's gateway (if any) and remove it from the manager. */ - kill: (shardId: number) => Promise + kill: (shardId: number) => Promise; /** This function makes sure that the bucket is allowed to make the next identify request. */ - requestIdentify: (shardId: number) => Promise + requestIdentify: (shardId: number) => Promise; /** Calculates the number of shards based on the guild id and total shards. */ - calculateShardId: (guildId: BigString, totalShards?: number) => number + calculateShardId: (guildId: BigString, totalShards?: number) => number; /** * Connects the bot user to a voice or stage channel. * @@ -781,14 +781,18 @@ export interface GatewayManager extends Required { * * @see {@link https://discord.com/developers/docs/topics/gateway#update-voice-state} */ - joinVoiceChannel: (guildId: BigString, channelId: BigString, options?: AtLeastOne>) => Promise + joinVoiceChannel: ( + guildId: BigString, + channelId: BigString, + options?: AtLeastOne>, + ) => Promise; /** * Edits the bot status in all shards that this gateway manages. * * @param data The status data to set the bots status to. * @returns nothing */ - editBotStatus: (data: DiscordUpdatePresence) => Promise + editBotStatus: (data: DiscordUpdatePresence) => Promise; /** * Edits the bot's status on one shard. * @@ -796,7 +800,7 @@ export interface GatewayManager extends Required { * @param data The status data to set the bots status to. * @returns nothing */ - editShardStatus: (shardId: number, data: DiscordUpdatePresence) => Promise + editShardStatus: (shardId: number, data: DiscordUpdatePresence) => Promise; /** * Fetches the list of members for a guild over the gateway. If `gateway.cache.requestMembers.enabled` is not set, this function will return an empty array and you'll have to handle the `GUILD_MEMBERS_CHUNK` events yourself. * @@ -820,7 +824,7 @@ export interface GatewayManager extends Required { * * @see {@link https://discord.com/developers/docs/topics/gateway#request-guild-members} */ - requestMembers: (guildId: BigString, options?: Omit) => Promise> + requestMembers: (guildId: BigString, options?: Omit) => Promise>; /** * Leaves the voice channel the bot user is currently in. * @@ -833,7 +837,7 @@ export interface GatewayManager extends Required { * * @see {@link https://discord.com/developers/docs/topics/gateway#update-voice-state} */ - leaveVoiceChannel: (guildId: BigString) => Promise + leaveVoiceChannel: (guildId: BigString) => Promise; /** * Used to request soundboard sounds for a list of guilds. * @@ -853,7 +857,7 @@ export interface GatewayManager extends Required { * * @see {@link https://discord.com/developers/docs/topics/gateway-events#request-soundboard-sounds} */ - requestSoundboardSounds: (guildIds: BigString[]) => Promise + requestSoundboardSounds: (guildIds: BigString[]) => Promise; /** This managers cache related settings. */ cache: { requestMembers: { @@ -861,18 +865,18 @@ export interface GatewayManager extends Required { * Whether or not request member requests should be cached. * @default false */ - enabled: boolean + enabled: boolean; /** The pending requests. */ - pending: Collection - } - } + pending: Collection; + }; + }; } export interface RequestMemberRequest { /** The unique nonce for this request. */ - nonce: string + nonce: string; /** The resolver handler to run when all members arrive. */ - resolve: (value: Camelize | PromiseLike>) => void + resolve: (value: Camelize | PromiseLike>) => void; /** The members that have already arrived for this request. */ - members: DiscordMemberWithUser[] + members: DiscordMemberWithUser[]; } diff --git a/packages/gateway/src/types.ts b/packages/gateway/src/types.ts index 702603368..9999ea0fe 100644 --- a/packages/gateway/src/types.ts +++ b/packages/gateway/src/types.ts @@ -1,5 +1,5 @@ -import type { DiscordGatewayPayload, GatewayOpcodes } from '@discordeno/types' -import type Shard from './Shard.js' +import type { DiscordGatewayPayload, GatewayOpcodes } from '@discordeno/types'; +import type Shard from './Shard.js'; export enum ShardState { /** Shard is fully connected to the gateway and receiving events from Discord. */ @@ -52,7 +52,7 @@ export interface ShardGatewayConfig { * * @see https://discord.com/developers/docs/topics/gateway#payload-compression */ - compress: boolean + compress: boolean; /** * What Transport Compression should be use * @@ -60,96 +60,96 @@ export interface ShardGatewayConfig { * * @see https://discord.com/developers/docs/topics/gateway#transport-compression */ - transportCompression: TransportCompression | null + transportCompression: TransportCompression | null; /** The calculated intent value of the events which the shard should receive. * * @default 0 */ - intents: number + intents: number; /** Identify properties to use */ properties: { /** Operating system the shard runs on. * * @default "darwin" | "linux" | "windows" */ - os: string + os: string; /** The "browser" where this shard is running on. * * @default "Discordeno" */ - browser: string + browser: string; /** The device on which the shard is running. * * @default "Discordeno" */ - device: string - } + device: string; + }; /** Bot token which is used to connect to Discord */ - token: string + token: string; /** The URL of the gateway which should be connected to. * * @default "wss://gateway.discord.gg" */ - url: string + url: string; /** The gateway version which should be used. * * @default 10 */ - version: number + version: number; /** * The total number of shards to connect to across the entire bot. * @default 1 */ - totalShards: number + totalShards: number; } export interface ShardHeart { /** Whether or not the heartbeat was acknowledged by Discord in time. */ - acknowledged: boolean + acknowledged: boolean; /** Interval between heartbeats requested by Discord. */ - interval: number + interval: number; /** Id of the interval, which is used for sending the heartbeats. */ - intervalId?: NodeJS.Timeout + intervalId?: NodeJS.Timeout; /** Unix (in milliseconds) timestamp when the last heartbeat ACK was received from Discord. */ - lastAck?: number + lastAck?: number; /** Unix timestamp (in milliseconds) when the last heartbeat was sent. */ - lastBeat?: number + lastBeat?: number; /** Round trip time (in milliseconds) from Shard to Discord and back. * Calculated using the heartbeat system. * Note: this value is undefined until the first heartbeat to Discord has happened. */ - rtt?: number + rtt?: number; /** Id of the timeout which is used for sending the first heartbeat to Discord since it's "special". */ - timeoutId?: NodeJS.Timeout + timeoutId?: NodeJS.Timeout; } export interface ShardEvents { /** A heartbeat has been send. */ - heartbeat?: (shard: Shard) => unknown + heartbeat?: (shard: Shard) => unknown; /** A heartbeat ACK was received. */ - heartbeatAck?: (shard: Shard) => unknown + heartbeatAck?: (shard: Shard) => unknown; /** Shard has received a Hello payload. */ - hello?: (shard: Shard) => unknown + hello?: (shard: Shard) => unknown; /** The Shards session has been invalidated. */ - invalidSession?: (shard: Shard, resumable: boolean) => unknown + invalidSession?: (shard: Shard, resumable: boolean) => unknown; /** The shard has started a resume action. */ - resuming?: (shard: Shard) => unknown + resuming?: (shard: Shard) => unknown; /** The shard has successfully resumed an old session. */ - resumed?: (shard: Shard) => unknown + resumed?: (shard: Shard) => unknown; /** Discord has requested the Shard to reconnect. */ - requestedReconnect?: (shard: Shard) => unknown + requestedReconnect?: (shard: Shard) => unknown; /** The shard started to connect to Discord's gateway. */ - connecting?: (shard: Shard) => unknown + connecting?: (shard: Shard) => unknown; /** The shard is connected with Discord's gateway. */ - connected?: (shard: Shard) => unknown + connected?: (shard: Shard) => unknown; /** The shard has been disconnected from Discord's gateway. */ - disconnected?: (shard: Shard) => unknown + disconnected?: (shard: Shard) => unknown; /** The shard has started to identify itself to Discord. */ - identifying?: (shard: Shard) => unknown + identifying?: (shard: Shard) => unknown; /** The shard has successfully been identified itself with Discord. */ - ready?: (shard: Shard) => unknown + ready?: (shard: Shard) => unknown; /** The shard has received a message from Discord. */ - message?: (shard: Shard, payload: DiscordGatewayPayload) => unknown + message?: (shard: Shard, payload: DiscordGatewayPayload) => unknown; } export enum ShardSocketCloseCodes { @@ -172,19 +172,19 @@ export enum ShardSocketCloseCodes { export interface ShardSocketRequest { /** The OP-Code for the payload to send. */ - op: GatewayOpcodes + op: GatewayOpcodes; /** Payload data. */ - d: unknown + d: unknown; } /** https://discord.com/developers/docs/topics/gateway#update-voice-state */ export interface UpdateVoiceState { /** id of the guild */ - guildId: string + guildId: string; /** id of the voice channel client wants to join (null if disconnecting) */ - channelId: string | null + channelId: string | null; /** Is the client muted */ - selfMute: boolean + selfMute: boolean; /** Is the client deafened */ - selfDeaf: boolean + selfDeaf: boolean; } diff --git a/packages/gateway/tests/integration/connection.spec.ts b/packages/gateway/tests/integration/connection.spec.ts index 91418f6fd..b5ada1471 100644 --- a/packages/gateway/tests/integration/connection.spec.ts +++ b/packages/gateway/tests/integration/connection.spec.ts @@ -1,58 +1,58 @@ -import { GatewayOpcodes, Intents } from '@discordeno/types' -import { createGatewayManager, type GatewayManager } from '../../src/manager.js' -import { ShardSocketCloseCodes } from '../../src/types.js' -import { creatWSServer, heartbeatInterval } from './websocket.js' +import { GatewayOpcodes, Intents } from '@discordeno/types'; +import { createGatewayManager, type GatewayManager } from '../../src/manager.js'; +import { ShardSocketCloseCodes } from '../../src/types.js'; +import { creatWSServer, heartbeatInterval } from './websocket.js'; describe('Gateway Integration', () => { it('Can connect to server', async () => { - const { promise: connected, resolve: resolveConnected } = promiseWithResolvers() + const { promise: connected, resolve: resolveConnected } = promiseWithResolvers(); const { port, close } = creatWSServer({ onOpen: resolveConnected, - }) + }); - const gateway = createGatewayManagerWithPort(port) - await gateway.spawnShards() - await connected + const gateway = createGatewayManagerWithPort(port); + await gateway.spawnShards(); + await connected; - await gateway.shutdown(ShardSocketCloseCodes.TestingFinished, 'Testing finished') + await gateway.shutdown(ShardSocketCloseCodes.TestingFinished, 'Testing finished'); // To avoid needing to wait 1m to get the bucket refil timer to fire we cancel it - clearTimeout(gateway.shards.get(0)?.bucket.timeoutId) + clearTimeout(gateway.shards.get(0)?.bucket.timeoutId); - close() - }) + close(); + }); it('Can heartbeat', async () => { - const { promise: connected, resolve: resolveConnected } = promiseWithResolvers() - const { promise: heartbeated, resolve: resolveHeartbeat, reject: rejectHeartbeat } = promiseWithResolvers() + const { promise: connected, resolve: resolveConnected } = promiseWithResolvers(); + const { promise: heartbeated, resolve: resolveHeartbeat, reject: rejectHeartbeat } = promiseWithResolvers(); const { port, close } = creatWSServer({ onOpen: resolveConnected, onMessage: (message) => { if (message.op === GatewayOpcodes.Heartbeat) { - resolveHeartbeat() + resolveHeartbeat(); } }, - }) + }); - const gateway = createGatewayManagerWithPort(port) - await gateway.spawnShards() - await connected + const gateway = createGatewayManagerWithPort(port); + await gateway.spawnShards(); + await connected; - const timeout = setTimeout(() => rejectHeartbeat(new Error('Not heartbeat in time')), heartbeatInterval) - await heartbeated + const timeout = setTimeout(() => rejectHeartbeat(new Error('Not heartbeat in time')), heartbeatInterval); + await heartbeated; - clearTimeout(timeout) + clearTimeout(timeout); - await gateway.shutdown(ShardSocketCloseCodes.TestingFinished, 'Testing finished') + await gateway.shutdown(ShardSocketCloseCodes.TestingFinished, 'Testing finished'); // To avoid needing to wait 1m to get the bucket refil timer to fire we cancel it - clearTimeout(gateway.shards.get(0)?.bucket.timeoutId) + clearTimeout(gateway.shards.get(0)?.bucket.timeoutId); - close() - }) -}) + close(); + }); +}); function createGatewayManagerWithPort(port: number): GatewayManager { return createGatewayManager({ @@ -74,22 +74,22 @@ function createGatewayManagerWithPort(port: number): GatewayManager { checkInterval: 0, shardsFullPercentage: 0, }, - }) + }); } // Polyfill for https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/withResolvers function promiseWithResolvers() { - let resolve!: (value: T | PromiseLike) => void - let reject!: (reason?: any) => void + let resolve!: (value: T | PromiseLike) => void; + let reject!: (reason?: any) => void; const promise = new Promise((_resolve, _reject) => { - resolve = _resolve - reject = _reject - }) + resolve = _resolve; + reject = _reject; + }); return { promise, resolve, reject, - } + }; } diff --git a/packages/gateway/tests/integration/websocket.ts b/packages/gateway/tests/integration/websocket.ts index b7dbceaad..db993f1d2 100644 --- a/packages/gateway/tests/integration/websocket.ts +++ b/packages/gateway/tests/integration/websocket.ts @@ -1,5 +1,5 @@ -import { type DiscordGatewayPayload, GatewayOpcodes } from '@discordeno/types' -import { type WebSocket, WebSocketServer } from 'ws' +import { type DiscordGatewayPayload, GatewayOpcodes } from '@discordeno/types'; +import { type WebSocket, WebSocketServer } from 'ws'; /** * This value needs to be AT LEAST `1017` @@ -7,15 +7,15 @@ import { type WebSocket, WebSocketServer } from 'ws' * The reason for this is because the calculation in Shard.calculateSafeRequests will return 0 not allowing any sort of message to the websocket server. * Discord uses a way higher number for this value, but during this test we lower it since it would be annoying and useless make the test last 40+ seconds to test the heartbeat, but to make this work it needs to be at least 1017 so that calculateSafeRequests return 2 allowing for the shard to send messages. */ -export const heartbeatInterval = 1017 +export const heartbeatInterval = 1017; export function creatWSServer(options: CreateWsServerOptions) { // Port 0 according to the node:http docs is for requesting the OS a random unused port - const server = new WebSocketServer({ port: 0 }) + const server = new WebSocketServer({ port: 0 }); - const address = server.address() + const address = server.address(); if (typeof address !== 'object' || !address) { - throw new TypeError('The address of the WebSocketServer should be an non-null object') + throw new TypeError('The address of the WebSocketServer should be an non-null object'); } server.on('connection', (socket) => { @@ -25,22 +25,22 @@ export function creatWSServer(options: CreateWsServerOptions) { d: { heartbeat_interval: heartbeatInterval, }, - }) + }); - options.onOpen?.() + options.onOpen?.(); socket.on('message', (data) => { - const msg = JSON.parse(data.toString('utf-8')) - options.onMessage?.(msg) + const msg = JSON.parse(data.toString('utf-8')); + options.onMessage?.(msg); switch (msg.op) { case GatewayOpcodes.Heartbeat: { send(socket, { op: GatewayOpcodes.HeartbeatACK, s: null, - }) + }); - break + break; } case GatewayOpcodes.Identify: { @@ -67,25 +67,25 @@ export function creatWSServer(options: CreateWsServerOptions) { guilds: [], application: { id: '0', flags: 0 }, }, - }) + }); - break + break; } } - }) - }) + }); + }); return { port: address.port, close: () => server.close(), - } + }; } export interface CreateWsServerOptions { - onOpen?: () => any - onMessage?: (message: DiscordGatewayPayload) => any + onOpen?: () => any; + onMessage?: (message: DiscordGatewayPayload) => any; } function send(ws: WebSocket, payload: object) { - ws.send(JSON.stringify(payload)) + ws.send(JSON.stringify(payload)); } diff --git a/packages/gateway/tests/unit/index.spec.ts b/packages/gateway/tests/unit/index.spec.ts index 3ca08a54b..18a17c85c 100644 --- a/packages/gateway/tests/unit/index.spec.ts +++ b/packages/gateway/tests/unit/index.spec.ts @@ -1,7 +1,7 @@ -import { describe, it } from 'mocha' +import { describe, it } from 'mocha'; describe('index.ts', () => { it('will import without error', async () => { - await import('../../src/index.js') - }) -}) + await import('../../src/index.js'); + }); +}); diff --git a/packages/rest/src/index.ts b/packages/rest/src/index.ts index 81d1a9b62..c166ba15c 100644 --- a/packages/rest/src/index.ts +++ b/packages/rest/src/index.ts @@ -1,6 +1,6 @@ -export * from './invalidBucket.js' -export * from './manager.js' -export * from './queue.js' -export * from './routes.js' -export * from './types.js' -export * from './typings/routes.js' +export * from './invalidBucket.js'; +export * from './manager.js'; +export * from './queue.js'; +export * from './routes.js'; +export * from './types.js'; +export * from './typings/routes.js'; diff --git a/packages/rest/src/invalidBucket.ts b/packages/rest/src/invalidBucket.ts index 8bb6a6fe8..fa5f27a01 100644 --- a/packages/rest/src/invalidBucket.ts +++ b/packages/rest/src/invalidBucket.ts @@ -1,4 +1,4 @@ -import { delay, logger } from '@discordeno/utils' +import { delay, logger } from '@discordeno/utils'; /** * A invalid request bucket is used in a similar manner as a leaky bucket but a invalid request bucket can be refilled as needed. @@ -23,132 +23,132 @@ export function createInvalidRequestBucket(options: InvalidRequestBucketOptions) requestsAllowed: function () { if (bucket.resetAt !== undefined && Date.now() >= bucket.resetAt) { - bucket.invalidRequests = 0 - bucket.resetAt = Date.now() + bucket.interval + bucket.invalidRequests = 0; + bucket.resetAt = Date.now() + bucket.interval; } - return bucket.max - bucket.invalidRequests - bucket.activeRequests - bucket.safety + return bucket.max - bucket.invalidRequests - bucket.activeRequests - bucket.safety; }, isRequestAllowed: function () { - return bucket.requestsAllowed() > 0 + return bucket.requestsAllowed() > 0; }, waitUntilRequestAvailable: async function () { return await new Promise(async (resolve) => { // If whatever amount of requests is left is more than the safety margin, allow the request if (bucket.isRequestAllowed()) { - bucket.activeRequests += 1 - resolve() + bucket.activeRequests += 1; + resolve(); } else { - bucket.waiting.push(resolve) - await bucket.processWaiting() + bucket.waiting.push(resolve); + await bucket.processWaiting(); } - }) + }); }, processWaiting: async function () { // If already processing, that loop will handle all waiting requests. - if (bucket.processing) return + if (bucket.processing) return; // Mark as processing so other loops don't start - bucket.processing = true + bucket.processing = true; while (bucket.waiting.length > 0) { bucket.logger.info( `[InvalidBucket] processing waiting queue while loop ran with ${bucket.waiting.length} pending requests to be made. ${JSON.stringify( bucket, )}`, - ) + ); if (!bucket.isRequestAllowed() && bucket.resetAt !== undefined) { bucket.logger.warn( `[InvalidBucket] processing waiting queue is now paused until more requests are available. ${ bucket.waiting.length } pending requests. ${JSON.stringify(bucket)}`, - ) - await delay(bucket.resetAt - Date.now()) + ); + await delay(bucket.resetAt - Date.now()); } - bucket.activeRequests += 1 + bucket.activeRequests += 1; // Resolve the next item in the queue - bucket.waiting.shift()?.() + bucket.waiting.shift()?.(); } // Mark as false so next pending request can be triggered by new loop. - bucket.processing = false + bucket.processing = false; }, handleCompletedRequest: function (code, sharedScope) { // Since request is complete, we can remove one from requested. - bucket.activeRequests -= 1 + bucket.activeRequests -= 1; // Since it is as a valid request, we don't need to do anything - if (!bucket.errorStatuses.includes(code)) return + if (!bucket.errorStatuses.includes(code)) return; // Shared scope is not considered invalid - if (code === 429 && sharedScope) return + if (code === 429 && sharedScope) return; // INVALID REQUEST WAS MADE if (bucket.resetAt === undefined) { - bucket.resetAt = Date.now() + bucket.interval + bucket.resetAt = Date.now() + bucket.interval; } - bucket.invalidRequests += 1 - bucket.logger.warn(`[InvalidBucket] an invalid request was made. Increasing invalidRequests count to ${bucket.invalidRequests}`) + bucket.invalidRequests += 1; + bucket.logger.warn(`[InvalidBucket] an invalid request was made. Increasing invalidRequests count to ${bucket.invalidRequests}`); }, - } + }; - return bucket + return bucket; } export interface InvalidRequestBucketOptions { /** current invalid amount */ - current?: number + current?: number; /** max invalid requests allowed until ban. Defaults to 10,000 */ - max?: number + max?: number; /** The time that discord allows to make the max number of invalid requests. Defaults to 10 minutes */ - interval?: number + interval?: number; /** When the timeout for the bucket has started at. */ - resetAt?: number + resetAt?: number; /** how safe to be from max. Defaults to 1 */ - safety?: number + safety?: number; /** The request statuses that count as an invalid request. */ - errorStatuses?: number[] + errorStatuses?: number[]; /** The amount of requests that were requested from this bucket. */ - requested?: number + requested?: number; /** The logger that will be used for the bucket */ - logger?: Pick + logger?: Pick; } export interface InvalidRequestBucket { /** current invalid amount */ - invalidRequests: number + invalidRequests: number; /** max invalid requests allowed until ban. Defaults to 10,000 */ - max: number + max: number; /** The time that discord allows to make the max number of invalid requests. Defaults to 10 minutes */ - interval: number + interval: number; /** When the timeout for this bucket has started at. */ - resetAt: number | undefined + resetAt: number | undefined; /** how safe to be from max. Defaults to 1 */ - safety: number + safety: number; /** The request statuses that count as an invalid request. */ - errorStatuses: number[] + errorStatuses: number[]; /** The amount of requests that were requested from this bucket. */ - activeRequests: number + activeRequests: number; /** The requests that are currently pending. */ - waiting: Array<(value: void | PromiseLike) => void> + waiting: Array<(value: void | PromiseLike) => void>; /** Whether or not the waiting queue is already processing. */ - processing: boolean + processing: boolean; /** The logger that will be used for the bucket */ - logger: Pick + logger: Pick; /** Gives the number of requests that are currently allowed. */ - requestsAllowed: () => number + requestsAllowed: () => number; /** Checks if a request is allowed at this time. */ - isRequestAllowed: () => boolean + isRequestAllowed: () => boolean; /** Waits until a request is available */ - waitUntilRequestAvailable: () => Promise + waitUntilRequestAvailable: () => Promise; /** Begins processing the waiting queue of requests. */ - processWaiting: () => Promise + processWaiting: () => Promise; /** Handler for whenever a request is validated. This should update the requested values or trigger any other necessary stuff. */ - handleCompletedRequest: (code: number, sharedScope: boolean) => void + handleCompletedRequest: (code: number, sharedScope: boolean) => void; } diff --git a/packages/rest/src/manager.ts b/packages/rest/src/manager.ts index 026b008ba..de3c42e99 100644 --- a/packages/rest/src/manager.ts +++ b/packages/rest/src/manager.ts @@ -1,5 +1,5 @@ -import { Buffer } from 'node:buffer' -import { type InspectOptions, inspect } from 'node:util' +import { Buffer } from 'node:buffer'; +import { type InspectOptions, inspect } from 'node:util'; import type { BigString, Camelize, @@ -57,7 +57,7 @@ import type { DiscordWebhook, DiscordWelcomeScreen, ModifyGuildTemplate, -} from '@discordeno/types' +} from '@discordeno/types'; import { calculateBits, camelize, @@ -70,27 +70,27 @@ import { processReactionString, snowflakeToTimestamp, urlToBase64, -} from '@discordeno/utils' -import { createInvalidRequestBucket } from './invalidBucket.js' -import { Queue } from './queue.js' -import { createRoutes } from './routes.js' -import type { CreateRequestBodyOptions, CreateRestManagerOptions, MakeRequestOptions, RestManager, SendRequestOptions } from './types.js' +} from '@discordeno/utils'; +import { createInvalidRequestBucket } from './invalidBucket.js'; +import { Queue } from './queue.js'; +import { createRoutes } from './routes.js'; +import type { CreateRequestBodyOptions, CreateRestManagerOptions, MakeRequestOptions, RestManager, SendRequestOptions } from './types.js'; -export const DISCORD_API_VERSION = 10 -export const DISCORD_API_URL = 'https://discord.com/api' +export const DISCORD_API_VERSION = 10; +export const DISCORD_API_URL = 'https://discord.com/api'; -export const AUDIT_LOG_REASON_HEADER = 'x-audit-log-reason' -export const RATE_LIMIT_REMAINING_HEADER = 'x-ratelimit-remaining' -export const RATE_LIMIT_RESET_AFTER_HEADER = 'x-ratelimit-reset-after' -export const RATE_LIMIT_GLOBAL_HEADER = 'x-ratelimit-global' -export const RATE_LIMIT_BUCKET_HEADER = 'x-ratelimit-bucket' -export const RATE_LIMIT_LIMIT_HEADER = 'x-ratelimit-limit' -export const RATE_LIMIT_SCOPE_HEADER = 'x-ratelimit-scope' +export const AUDIT_LOG_REASON_HEADER = 'x-audit-log-reason'; +export const RATE_LIMIT_REMAINING_HEADER = 'x-ratelimit-remaining'; +export const RATE_LIMIT_RESET_AFTER_HEADER = 'x-ratelimit-reset-after'; +export const RATE_LIMIT_GLOBAL_HEADER = 'x-ratelimit-global'; +export const RATE_LIMIT_BUCKET_HEADER = 'x-ratelimit-bucket'; +export const RATE_LIMIT_LIMIT_HEADER = 'x-ratelimit-limit'; +export const RATE_LIMIT_SCOPE_HEADER = 'x-ratelimit-scope'; export function createRestManager(options: CreateRestManagerOptions): RestManager { - const applicationId = options.applicationId ? BigInt(options.applicationId) : getBotIdFromToken(options.token) + const applicationId = options.applicationId ? BigInt(options.applicationId) : getBotIdFromToken(options.token); - const baseUrl = options.proxy?.baseUrl ?? DISCORD_API_URL + const baseUrl = options.proxy?.baseUrl ?? DISCORD_API_URL; // Discord error can get nested a lot, so we use a custom inspect to change the depth to Infinity const baseErrorPrototype = { [inspect.custom](_depth: number, options: InspectOptions, _inspect: typeof inspect) { @@ -99,9 +99,9 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage depth: Infinity, // Since we call inspect on ourself, we need to disable the calls to the inspect.custom symbol or else it will cause an infinite loop. customInspect: false, - }) + }); }, - } + }; const rest: RestManager = { applicationId, @@ -132,24 +132,24 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage createBaseHeaders() { return { 'user-agent': `DiscordBot (https://github.com/discordeno/discordeno, v${DISCORDENO_VERSION})`, - } + }; }, checkRateLimits(url, identifier) { - const ratelimited = rest.rateLimitedPaths.get(`${identifier}${url}`) + const ratelimited = rest.rateLimitedPaths.get(`${identifier}${url}`); - const global = rest.rateLimitedPaths.get('global') - const now = Date.now() + const global = rest.rateLimitedPaths.get('global'); + const now = Date.now(); if (ratelimited && now < ratelimited.resetTimestamp) { - return ratelimited.resetTimestamp - now + return ratelimited.resetTimestamp - now; } if (global && now < global.resetTimestamp) { - return global.resetTimestamp - now + return global.resetTimestamp - now; } - return false + return false; }, async updateTokenQueues(oldToken, newToken) { @@ -157,15 +157,15 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage if (!rest.updateBearerTokenEndpoint) { throw new Error( "The 'proxy.updateBearerTokenEndpoint' option needs to be set when using a rest proxy and needed to call 'updateTokenQueues'", - ) + ); } const headers = { 'content-type': 'application/json', - } as Record + } as Record; if (rest.authorization !== undefined) { - headers[rest.authorizationHeader] = rest.authorization + headers[rest.authorizationHeader] = rest.authorization; } await fetch(`${rest.baseUrl}/${rest.updateBearerTokenEndpoint}`, { @@ -175,65 +175,65 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage newToken, }), headers, - }) + }); - return + return; } - const newIdentifier = `Bearer ${newToken}` + const newIdentifier = `Bearer ${newToken}`; // Update all the queues for (const [key, queue] of rest.queues.entries()) { - if (!key.startsWith(`Bearer ${oldToken}`)) continue + if (!key.startsWith(`Bearer ${oldToken}`)) continue; - rest.queues.delete(key) - queue.identifier = newIdentifier + rest.queues.delete(key); + queue.identifier = newIdentifier; - const newKey = `${newIdentifier}${queue.url}` - const newQueue = rest.queues.get(newKey) + const newKey = `${newIdentifier}${queue.url}`; + const newQueue = rest.queues.get(newKey); // Merge the queues if (newQueue) { - newQueue.waiting.unshift(...queue.waiting) - newQueue.pending.unshift(...queue.pending) + newQueue.waiting.unshift(...queue.waiting); + newQueue.pending.unshift(...queue.pending); - queue.waiting = [] - queue.pending = [] + queue.waiting = []; + queue.pending = []; - queue.cleanup() + queue.cleanup(); } else { - rest.queues.set(newKey, queue) + rest.queues.set(newKey, queue); } } for (const [key, ratelimitPath] of rest.rateLimitedPaths.entries()) { - if (!key.startsWith(`Bearer ${oldToken}`)) continue + if (!key.startsWith(`Bearer ${oldToken}`)) continue; - rest.rateLimitedPaths.set(`${newIdentifier}${ratelimitPath.url}`, ratelimitPath) + rest.rateLimitedPaths.set(`${newIdentifier}${ratelimitPath.url}`, ratelimitPath); if (ratelimitPath.bucketId) { - rest.rateLimitedPaths.set(`${newIdentifier}${ratelimitPath.bucketId}`, ratelimitPath) + rest.rateLimitedPaths.set(`${newIdentifier}${ratelimitPath.bucketId}`, ratelimitPath); } } }, changeToDiscordFormat(obj: any): any { - if (obj === null) return null + if (obj === null) return null; if (typeof obj === 'object') { if (Array.isArray(obj)) { - return obj.map((item) => rest.changeToDiscordFormat(item)) + return obj.map((item) => rest.changeToDiscordFormat(item)); } - const newObj: any = {} + const newObj: any = {}; for (const key of Object.keys(obj)) { - const value = obj[key] + const value = obj[key]; // If the key is already in snake_case we can assume it is already in the discord format. if (key.includes('_')) { - newObj[key] = value - continue + newObj[key] = value; + continue; } // Some falsy values should be allowed like null or 0 @@ -242,90 +242,90 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage case 'permissions': case 'allow': case 'deny': - newObj[key] = typeof value === 'string' ? value : calculateBits(value) - continue + newObj[key] = typeof value === 'string' ? value : calculateBits(value); + continue; case 'defaultMemberPermissions': - newObj.default_member_permissions = typeof value === 'string' ? value : calculateBits(value) - continue + newObj.default_member_permissions = typeof value === 'string' ? value : calculateBits(value); + continue; case 'nameLocalizations': - newObj.name_localizations = value - continue + newObj.name_localizations = value; + continue; case 'descriptionLocalizations': - newObj.description_localizations = value - continue + newObj.description_localizations = value; + continue; } } - newObj[camelToSnakeCase(key)] = rest.changeToDiscordFormat(value) + newObj[camelToSnakeCase(key)] = rest.changeToDiscordFormat(value); } - return newObj + return newObj; } - if (typeof obj === 'bigint') return obj.toString() + if (typeof obj === 'bigint') return obj.toString(); - return obj + return obj; }, createRequestBody(method, options) { - const headers = this.createBaseHeaders() + const headers = this.createBaseHeaders(); - if (options?.unauthorized !== true) headers.authorization = `Bot ${rest.token}` + if (options?.unauthorized !== true) headers.authorization = `Bot ${rest.token}`; // IF A REASON IS PROVIDED ENCODE IT IN HEADERS if (options?.reason !== undefined) { - headers[AUDIT_LOG_REASON_HEADER] = encodeURIComponent(options?.reason) + headers[AUDIT_LOG_REASON_HEADER] = encodeURIComponent(options?.reason); } - let body: string | FormData | undefined + let body: string | FormData | undefined; // Have to check for attachments first, since body then has to be send in a different way. if (options?.files !== undefined) { - const form = new FormData() + const form = new FormData(); for (let i = 0; i < options.files.length; ++i) { - form.append(`files[${i}]`, options.files[i].blob, options.files[i].name) + form.append(`files[${i}]`, options.files[i].blob, options.files[i].name); } // Have to use changeToDiscordFormat or else JSON.stringify may throw an error for the presence of BigInt(s) in the json - form.append('payload_json', JSON.stringify(rest.changeToDiscordFormat({ ...options.body, files: undefined }))) + form.append('payload_json', JSON.stringify(rest.changeToDiscordFormat({ ...options.body, files: undefined }))); // No need to set the `content-type` header since `fetch` does that automatically for us when we use a `FormData` object. - body = form + body = form; } else if (options?.body && options.headers && options.headers['content-type'] === 'application/x-www-form-urlencoded') { // OAuth2 body handling - const formBody: string[] = [] + const formBody: string[] = []; - const discordBody = rest.changeToDiscordFormat(options.body) + const discordBody = rest.changeToDiscordFormat(options.body); for (const prop in discordBody) { - formBody.push(`${encodeURIComponent(prop)}=${encodeURIComponent(discordBody[prop])}`) + formBody.push(`${encodeURIComponent(prop)}=${encodeURIComponent(discordBody[prop])}`); } - body = formBody.join('&') + body = formBody.join('&'); } else if (options?.body !== undefined) { if (options.body instanceof FormData) { - body = options.body + body = options.body; // No need to set the `content-type` header since `fetch` does that automatically for us when we use a `FormData` object. } else { - body = JSON.stringify(rest.changeToDiscordFormat(options.body)) - headers['content-type'] = `application/json` + body = JSON.stringify(rest.changeToDiscordFormat(options.body)); + headers['content-type'] = `application/json`; } } // SOMETIMES SPECIAL HEADERS (E.G. CUSTOM AUTHORIZATION) NEED TO BE USED if (options?.headers) { - Object.assign(headers, options.headers) + Object.assign(headers, options.headers); } return { body, headers, method, - } + }; }, processRateLimitedPaths() { - const now = Date.now() + const now = Date.now(); for (const [key, value] of rest.rateLimitedPaths.entries()) { // rest.debug( @@ -334,59 +334,59 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage // }` // ) // If the time has not reached cancel - if (value.resetTimestamp > now) continue + if (value.resetTimestamp > now) continue; // Rate limit is over, delete the rate limiter - rest.rateLimitedPaths.delete(key) + rest.rateLimitedPaths.delete(key); // If it was global, also mark the global value as false - if (key === 'global') rest.globallyRateLimited = false + if (key === 'global') rest.globallyRateLimited = false; } // ALL PATHS ARE CLEARED CAN CANCEL OUT! if (rest.rateLimitedPaths.size === 0) { - rest.processingRateLimitedPaths = false + rest.processingRateLimitedPaths = false; } else { - rest.processingRateLimitedPaths = true + rest.processingRateLimitedPaths = true; // RECHECK IN 1 SECOND setTimeout(() => { // rest.debug('[REST - processRateLimitedPaths] Running setTimeout.') - rest.processRateLimitedPaths() - }, 1000) + rest.processRateLimitedPaths(); + }, 1000); } }, /** Processes the rate limit headers and determines if it needs to be rate limited and returns the bucket id if available */ processHeaders(url, headers, identifier) { - let rateLimited = false + let rateLimited = false; // GET ALL NECESSARY HEADERS - const remaining = headers.get(RATE_LIMIT_REMAINING_HEADER) - const retryAfter = headers.get(RATE_LIMIT_RESET_AFTER_HEADER) - const reset = Date.now() + Number(retryAfter) * 1000 - const global = headers.get(RATE_LIMIT_GLOBAL_HEADER) + const remaining = headers.get(RATE_LIMIT_REMAINING_HEADER); + const retryAfter = headers.get(RATE_LIMIT_RESET_AFTER_HEADER); + const reset = Date.now() + Number(retryAfter) * 1000; + const global = headers.get(RATE_LIMIT_GLOBAL_HEADER); // undefined override null needed for typings - const bucketId = headers.get(RATE_LIMIT_BUCKET_HEADER) ?? undefined - const limit = headers.get(RATE_LIMIT_LIMIT_HEADER) + const bucketId = headers.get(RATE_LIMIT_BUCKET_HEADER) ?? undefined; + const limit = headers.get(RATE_LIMIT_LIMIT_HEADER); // If we didn't received the identifier, fallback to the bot token - identifier ??= `Bot ${rest.token}` + identifier ??= `Bot ${rest.token}`; rest.queues.get(`${identifier}${url}`)?.handleCompletedRequest({ remaining: remaining ? Number(remaining) : undefined, interval: retryAfter ? Number(retryAfter) * 1000 : undefined, max: limit ? Number(limit) : undefined, - }) + }); // IF THERE IS NO REMAINING RATE LIMIT, MARK IT AS RATE LIMITED if (remaining === '0') { - rateLimited = true + rateLimited = true; // SAVE THE URL AS LIMITED, IMPORTANT FOR NEW REQUESTS BY USER WITHOUT BUCKET rest.rateLimitedPaths.set(`${identifier}${url}`, { url, resetTimestamp: reset, bucketId, - }) + }); // SAVE THE BUCKET AS LIMITED SINCE DIFFERENT URLS MAY SHARE A BUCKET if (bucketId) { @@ -394,135 +394,135 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage url, resetTimestamp: reset, bucketId, - }) + }); } } // IF THERE IS NO REMAINING GLOBAL LIMIT, MARK IT RATE LIMITED GLOBALLY if (global) { - const retryAfter = Number(headers.get('retry-after')) * 1000 - const globalReset = Date.now() + retryAfter + const retryAfter = Number(headers.get('retry-after')) * 1000; + const globalReset = Date.now() + retryAfter; // rest.debug( // `[REST = Globally Rate Limited] URL: ${url} | Global Rest: ${globalReset}` // ) - rest.globallyRateLimited = true - rateLimited = true + rest.globallyRateLimited = true; + rateLimited = true; setTimeout(() => { - rest.globallyRateLimited = false - }, retryAfter) + rest.globallyRateLimited = false; + }, retryAfter); rest.rateLimitedPaths.set('global', { url: 'global', resetTimestamp: globalReset, bucketId, - }) + }); if (bucketId) { rest.rateLimitedPaths.set(identifier, { url: 'global', resetTimestamp: globalReset, bucketId, - }) + }); } } if (rateLimited && !rest.processingRateLimitedPaths) { - rest.processRateLimitedPaths() + rest.processRateLimitedPaths(); } - return rateLimited ? bucketId : undefined + return rateLimited ? bucketId : undefined; }, async sendRequest(options) { - const url = `${rest.baseUrl}/v${rest.version}${options.route}` - const payload = rest.createRequestBody(options.method, options.requestBodyOptions) + const url = `${rest.baseUrl}/v${rest.version}${options.route}`; + const payload = rest.createRequestBody(options.method, options.requestBodyOptions); - const loggingHeaders = { ...payload.headers } + const loggingHeaders = { ...payload.headers }; if (payload.headers.authorization) { - const authorizationScheme = payload.headers.authorization?.split(' ')[0] - loggingHeaders.authorization = `${authorizationScheme} tokenhere` + const authorizationScheme = payload.headers.authorization?.split(' ')[0]; + loggingHeaders.authorization = `${authorizationScheme} tokenhere`; } - const request = new Request(url, payload) + const request = new Request(url, payload); rest.events.request(request, { body: options.requestBodyOptions?.body, - }) + }); - rest.logger.debug(`sending request to ${url}`, 'with payload:', { ...payload, headers: loggingHeaders }) + rest.logger.debug(`sending request to ${url}`, 'with payload:', { ...payload, headers: loggingHeaders }); const response = await fetch(request).catch(async (error) => { - rest.logger.error(error) - rest.events.requestError(request, error, { body: options.requestBodyOptions?.body }) + rest.logger.error(error); + rest.events.requestError(request, error, { body: options.requestBodyOptions?.body }); // Mark request as completed - rest.invalidBucket.handleCompletedRequest(999, false) + rest.invalidBucket.handleCompletedRequest(999, false); options.reject({ ok: false, status: 999, error: 'Possible network or request shape issue occurred. If this is rare, its a network glitch. If it occurs a lot something is wrong.', - }) - throw error - }) - rest.logger.debug(`request fetched from ${url} with status ${response.status} & ${response.statusText}`) + }); + throw error; + }); + rest.logger.debug(`request fetched from ${url} with status ${response.status} & ${response.statusText}`); // Sometimes the Content-Type may be "application/json; charset=utf-8", for this reason, we need to check the start of the header - const body = await (response.headers.get('Content-Type')?.startsWith('application/json') ? response.json() : response.text()).catch(() => null) + const body = await (response.headers.get('Content-Type')?.startsWith('application/json') ? response.json() : response.text()).catch(() => null); rest.events.response(request, response, { requestBody: options.requestBodyOptions?.body, responseBody: body, - }) + }); // Mark request as completed - rest.invalidBucket.handleCompletedRequest(response.status, response.headers.get(RATE_LIMIT_SCOPE_HEADER) === 'shared') + rest.invalidBucket.handleCompletedRequest(response.status, response.headers.get(RATE_LIMIT_SCOPE_HEADER) === 'shared'); // Set the bucket id if it was available on the headers - const bucketId = rest.processHeaders(rest.simplifyUrl(options.route, options.method), response.headers, payload.headers.authorization) + const bucketId = rest.processHeaders(rest.simplifyUrl(options.route, options.method), response.headers, payload.headers.authorization); - if (bucketId) options.bucketId = bucketId + if (bucketId) options.bucketId = bucketId; if (response.status < HttpResponseCode.Success || response.status >= HttpResponseCode.Error) { - rest.logger.debug(`Request to ${url} failed.`) + rest.logger.debug(`Request to ${url} failed.`); if (response.status !== HttpResponseCode.TooManyRequests) { - options.reject({ ok: false, status: response.status, statusText: response.statusText, body }) - return + options.reject({ ok: false, status: response.status, statusText: response.statusText, body }); + return; } - rest.logger.debug(`Request to ${url} was ratelimited.`) + rest.logger.debug(`Request to ${url} was ratelimited.`); // Too many attempts, get rid of request from queue. if (options.retryCount >= rest.maxRetryCount) { - rest.logger.debug(`Request to ${url} exceeded the maximum allowed retries.`, 'with payload:', payload) + rest.logger.debug(`Request to ${url} exceeded the maximum allowed retries.`, 'with payload:', payload); // rest.debug(`[REST - RetriesMaxed] ${JSON.stringify(options)}`) options.reject({ ok: false, status: response.status, statusText: response.statusText, error: 'The request was rate limited and it maxed out the retries limit.', - }) + }); - return + return; } - options.retryCount += 1 + options.retryCount += 1; - const resetAfter = response.headers.get(RATE_LIMIT_RESET_AFTER_HEADER) - if (resetAfter) await delay(Number(resetAfter) * 1000) + const resetAfter = response.headers.get(RATE_LIMIT_RESET_AFTER_HEADER); + if (resetAfter) await delay(Number(resetAfter) * 1000); - return await options.retryRequest?.(options) + return await options.retryRequest?.(options); } // Discord sometimes sends a response with no content - options.resolve({ ok: true, status: response.status, body: response.status === HttpResponseCode.NoContent ? undefined : body }) + options.resolve({ ok: true, status: response.status, body: response.status === HttpResponseCode.NoContent ? undefined : body }); }, simplifyUrl(url, method) { - const routeInformationKey: string[] = [method] + const routeInformationKey: string[] = [method]; - const queryParamIndex = url.indexOf('?') - const route = queryParamIndex !== -1 ? url.slice(0, queryParamIndex) : url + const queryParamIndex = url.indexOf('?'); + const route = queryParamIndex !== -1 ? url.slice(0, queryParamIndex) : url; // Since the urls start with / the first part will always be empty - const splittedRoute = route.split('/') + const splittedRoute = route.split('/'); // 1) Strip the minor params // The only majors are channels, guilds, webhooks and webhooks with their token @@ -530,25 +530,25 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage const strippedRoute = splittedRoute .map((part, index, array) => { // While parseInt will truncate the snowflake id, it will still tell us if it is a number - const isNumber = Number.isFinite(parseInt(part, 10)) + const isNumber = Number.isFinite(parseInt(part, 10)); if (!isNumber) { // Reactions emoji need to be stripped as it is a minor parameter - if (index >= 1 && array[index - 1] === 'reactions') return 'x' + if (index >= 1 && array[index - 1] === 'reactions') return 'x'; // If we are on a webhook or if it is part of the route, keep it as it is a major parameter - return part + return part; } // Check if we are on a channel id, a guild id or a webhook id - const isMajor = index >= 1 && (array[index - 1] === 'channels' || array[index - 1] === 'guilds' || array[index - 1] === 'webhooks') + const isMajor = index >= 1 && (array[index - 1] === 'channels' || array[index - 1] === 'guilds' || array[index - 1] === 'webhooks'); - if (isMajor) return part + if (isMajor) return part; - return 'x' + return 'x'; }) - .join('/') + .join('/'); - routeInformationKey.push(strippedRoute) + routeInformationKey.push(strippedRoute); // 2) Account for exceptions // - https://github.com/discord/discord-api-docs/issues/1092 @@ -556,91 +556,91 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage // The 2 exceptions are for message delete, so we need to check if we are in that route if (method === 'DELETE' && splittedRoute.length === 5 && splittedRoute[1] === 'channels' && strippedRoute.endsWith('/messages/x')) { - const messageId = splittedRoute[4] - const timestamp = snowflakeToTimestamp(messageId) - const now = Date.now() + const messageId = splittedRoute[4]; + const timestamp = snowflakeToTimestamp(messageId); + const now = Date.now(); // https://github.com/discord/discord-api-docs/issues/1092 if (now - timestamp < 10_000) { - routeInformationKey.push('message-delete-10s') + routeInformationKey.push('message-delete-10s'); } // https://github.com/discord/discord-api-docs/issues/1295 // 2 weeks = 2 * 7 * 24 * 60 * 60 * 1000 = 1209600000 if (now - timestamp > 1209600000) { - routeInformationKey.push('message-delete-2w') + routeInformationKey.push('message-delete-2w'); } } - return routeInformationKey.join(':') + return routeInformationKey.join(':'); }, async processRequest(request: SendRequestOptions) { - const url = rest.simplifyUrl(request.route, request.method) + const url = rest.simplifyUrl(request.route, request.method); if (request.runThroughQueue === false) { - await rest.sendRequest(request) + await rest.sendRequest(request); - return + return; } // If we the request has a token, use it // Else fallback to prefix with the bot token - const queueIdentifier = request.requestBodyOptions?.headers?.authorization ?? `Bot ${rest.token}` + const queueIdentifier = request.requestBodyOptions?.headers?.authorization ?? `Bot ${rest.token}`; - const queue = rest.queues.get(`${queueIdentifier}${url}`) + const queue = rest.queues.get(`${queueIdentifier}${url}`); if (queue !== undefined) { - queue.makeRequest(request) + queue.makeRequest(request); } else { // CREATES A NEW QUEUE - const bucketQueue = new Queue(rest, { url, deleteQueueDelay: rest.deleteQueueDelay, identifier: queueIdentifier }) + const bucketQueue = new Queue(rest, { url, deleteQueueDelay: rest.deleteQueueDelay, identifier: queueIdentifier }); // Save queue - rest.queues.set(`${queueIdentifier}${url}`, bucketQueue) + rest.queues.set(`${queueIdentifier}${url}`, bucketQueue); // Add request to queue - bucketQueue.makeRequest(request) + bucketQueue.makeRequest(request); } }, async makeRequest(method, route, options) { // This error needs to be created here because of how stack traces get calculated - const error = new Error() + const error = new Error(); if (rest.isProxied) { if (rest.authorization) { - options ??= {} - options.headers ??= {} - options.headers[rest.authorizationHeader] = rest.authorization + options ??= {}; + options.headers ??= {}; + options.headers[rest.authorizationHeader] = rest.authorization; } - const request = new Request(`${rest.baseUrl}/v${rest.version}${route}`, rest.createRequestBody(method, options)) + const request = new Request(`${rest.baseUrl}/v${rest.version}${route}`, rest.createRequestBody(method, options)); rest.events.request(request, { body: options?.body, - }) + }); - const result = await fetch(request) + const result = await fetch(request); // Sometimes the Content-Type may be "application/json; charset=utf-8", for this reason, we need to check the start of the header - const body = await (result.headers.get('Content-Type')?.startsWith('application/json') ? result.json() : result.text()).catch(() => null) + const body = await (result.headers.get('Content-Type')?.startsWith('application/json') ? result.json() : result.text()).catch(() => null); rest.events.response(request, result, { requestBody: options?.body, responseBody: body, - }) + }); if (!result.ok) { error.cause = Object.assign(Object.create(baseErrorPrototype), { ok: false, status: result.status, body, - }) + }); - throw error + throw error; } - return result.status !== 204 ? (typeof body === 'string' ? JSON.parse(body) : body) : undefined + return result.status !== 204 ? (typeof body === 'string' ? JSON.parse(body) : body) : undefined; } return await new Promise(async (resolve, reject) => { @@ -650,189 +650,189 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage requestBodyOptions: options, retryCount: 0, retryRequest: async (payload: SendRequestOptions) => { - await rest.processRequest(payload) + await rest.processRequest(payload); }, resolve: (data) => { - resolve(data.status !== 204 ? (typeof data.body === 'string' ? JSON.parse(data.body) : data.body) : undefined) + resolve(data.status !== 204 ? (typeof data.body === 'string' ? JSON.parse(data.body) : data.body) : undefined); }, reject: (reason) => { - let errorText: string + let errorText: string; switch (reason.status) { case 400: - errorText = "The options was improperly formatted, or the server couldn't understand it." - break + errorText = "The options was improperly formatted, or the server couldn't understand it."; + break; case 401: - errorText = 'The Authorization header was missing or invalid.' - break + errorText = 'The Authorization header was missing or invalid.'; + break; case 403: - errorText = 'The Authorization token you passed did not have permission to the resource.' - break + errorText = 'The Authorization token you passed did not have permission to the resource.'; + break; case 404: - errorText = "The resource at the location specified doesn't exist." - break + errorText = "The resource at the location specified doesn't exist."; + break; case 405: - errorText = 'The HTTP method used is not valid for the location specified.' - break + errorText = 'The HTTP method used is not valid for the location specified.'; + break; case 429: - errorText = "You're being ratelimited." - break + errorText = "You're being ratelimited."; + break; case 502: - errorText = 'There was not a gateway available to process your options. Wait a bit and retry.' - break + errorText = 'There was not a gateway available to process your options. Wait a bit and retry.'; + break; default: - errorText = reason.statusText ?? 'Unknown error' + errorText = reason.statusText ?? 'Unknown error'; } - error.message = `[${reason.status}] ${errorText}` + error.message = `[${reason.status}] ${errorText}`; // If discord sent us JSON, it is probably going to be an error message from which we can get and add some information about the error to the error message, the full body will be in the error.cause // https://discord.com/developers/docs/reference#error-messages if (typeof reason.body === 'object' && hasProperty(reason.body, 'code') && hasProperty(reason.body, 'message')) { - error.message += `\nDiscord error: [${reason.body.code}] ${reason.body.message}` + error.message += `\nDiscord error: [${reason.body.code}] ${reason.body.message}`; } - error.cause = Object.assign(Object.create(baseErrorPrototype), reason) - reject(error) + error.cause = Object.assign(Object.create(baseErrorPrototype), reason); + reject(error); }, runThroughQueue: options?.runThroughQueue, - } + }; - await rest.processRequest(payload) - }) + await rest.processRequest(payload); + }); }, async get>(url: string, options?: Omit) { - return camelize(await rest.makeRequest('GET', url, options)) as Camelize + return camelize(await rest.makeRequest('GET', url, options)) as Camelize; }, async post>(url: string, options?: Omit) { - return camelize(await rest.makeRequest('POST', url, options)) as Camelize + return camelize(await rest.makeRequest('POST', url, options)) as Camelize; }, async delete(url: string, options?: Omit) { - camelize(await rest.makeRequest('DELETE', url, options)) + camelize(await rest.makeRequest('DELETE', url, options)); }, async patch>(url: string, options?: Omit) { - return camelize(await rest.makeRequest('PATCH', url, options)) as Camelize + return camelize(await rest.makeRequest('PATCH', url, options)) as Camelize; }, async put(url: string, options?: Omit) { - return camelize(await rest.makeRequest('PUT', url, options)) as Camelize + return camelize(await rest.makeRequest('PUT', url, options)) as Camelize; }, async addReaction(channelId, messageId, reaction) { - reaction = processReactionString(reaction) + reaction = processReactionString(reaction); - await rest.put(rest.routes.channels.reactions.bot(channelId, messageId, reaction)) + await rest.put(rest.routes.channels.reactions.bot(channelId, messageId, reaction)); }, async addReactions(channelId, messageId, reactions, ordered = false) { if (!ordered) { await Promise.all( reactions.map(async (reaction) => { - await rest.addReaction(channelId, messageId, reaction) + await rest.addReaction(channelId, messageId, reaction); }), - ) - return + ); + return; } for (const reaction of reactions) { - await rest.addReaction(channelId, messageId, reaction) + await rest.addReaction(channelId, messageId, reaction); } }, async addRole(guildId, userId, roleId, reason) { - await rest.put(rest.routes.guilds.roles.member(guildId, userId, roleId), { reason }) + await rest.put(rest.routes.guilds.roles.member(guildId, userId, roleId), { reason }); }, async addThreadMember(channelId, userId) { - await rest.put(rest.routes.channels.threads.user(channelId, userId)) + await rest.put(rest.routes.channels.threads.user(channelId, userId)); }, async addDmRecipient(channelId, userId, body) { - await rest.put(rest.routes.channels.dmRecipient(channelId, userId), { body }) + await rest.put(rest.routes.channels.dmRecipient(channelId, userId), { body }); }, async createAutomodRule(guildId, body, reason) { - return await rest.post(rest.routes.guilds.automod.rules(guildId), { body, reason }) + return await rest.post(rest.routes.guilds.automod.rules(guildId), { body, reason }); }, async createChannel(guildId, body, reason) { - return await rest.post(rest.routes.guilds.channels(guildId), { body, reason }) + return await rest.post(rest.routes.guilds.channels(guildId), { body, reason }); }, async createEmoji(guildId, body, reason) { - return await rest.post(rest.routes.guilds.emojis(guildId), { body, reason }) + return await rest.post(rest.routes.guilds.emojis(guildId), { body, reason }); }, async createApplicationEmoji(body) { - return await rest.post(rest.routes.applicationEmojis(rest.applicationId), { body }) + return await rest.post(rest.routes.applicationEmojis(rest.applicationId), { body }); }, async createGlobalApplicationCommand(body, options) { - const restOptions: MakeRequestOptions = { body } + const restOptions: MakeRequestOptions = { body }; if (options?.bearerToken) { - restOptions.unauthorized = true + restOptions.unauthorized = true; restOptions.headers = { authorization: `Bearer ${options.bearerToken}`, - } + }; } - return await rest.post(rest.routes.interactions.commands.commands(rest.applicationId), restOptions) + return await rest.post(rest.routes.interactions.commands.commands(rest.applicationId), restOptions); }, async createGuildApplicationCommand(body, guildId, options) { - const restOptions: MakeRequestOptions = { body } + const restOptions: MakeRequestOptions = { body }; if (options?.bearerToken) { - restOptions.unauthorized = true + restOptions.unauthorized = true; restOptions.headers = { authorization: `Bearer ${options.bearerToken}`, - } + }; } - return await rest.post(rest.routes.interactions.commands.guilds.all(rest.applicationId, guildId), restOptions) + return await rest.post(rest.routes.interactions.commands.guilds.all(rest.applicationId, guildId), restOptions); }, async createGuildSticker(guildId, options, reason) { - const form = new FormData() - form.append('file', options.file.blob, options.file.name) - form.append('name', options.name) - form.append('description', options.description) - form.append('tags', options.tags) + const form = new FormData(); + form.append('file', options.file.blob, options.file.name); + form.append('name', options.name); + form.append('description', options.description); + form.append('tags', options.tags); - return await rest.post(rest.routes.guilds.stickers(guildId), { body: form, reason }) + return await rest.post(rest.routes.guilds.stickers(guildId), { body: form, reason }); }, async createGuildTemplate(guildId, body) { - return await rest.post(rest.routes.guilds.templates.all(guildId), { body }) + return await rest.post(rest.routes.guilds.templates.all(guildId), { body }); }, async createForumThread(channelId, body, reason) { - return await rest.post(rest.routes.channels.forum(channelId), { body, files: body.files, reason }) + return await rest.post(rest.routes.channels.forum(channelId), { body, files: body.files, reason }); }, async createInvite(channelId, body = {}, reason) { - return await rest.post(rest.routes.channels.invites(channelId), { body, reason }) + return await rest.post(rest.routes.channels.invites(channelId), { body, reason }); }, async getGuildRoleMemberCounts(guildId) { - return await rest.get>(rest.routes.guilds.roles.memberCounts(guildId)) + return await rest.get>(rest.routes.guilds.roles.memberCounts(guildId)); }, async createRole(guildId, body, reason) { - return await rest.post(rest.routes.guilds.roles.all(guildId), { body, reason }) + return await rest.post(rest.routes.guilds.roles.all(guildId), { body, reason }); }, async createScheduledEvent(guildId, body, reason) { - return await rest.post(rest.routes.guilds.events.events(guildId), { body, reason }) + return await rest.post(rest.routes.guilds.events.events(guildId), { body, reason }); }, async createStageInstance(body, reason) { - return await rest.post(rest.routes.channels.stages(), { body, reason }) + return await rest.post(rest.routes.channels.stages(), { body, reason }); }, async createWebhook(channelId, options, reason) { @@ -842,61 +842,61 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage avatar: options.avatar ? await urlToBase64(options.avatar) : undefined, }, reason, - }) + }); }, async deleteAutomodRule(guildId, ruleId, reason) { - await rest.delete(rest.routes.guilds.automod.rule(guildId, ruleId), { reason }) + await rest.delete(rest.routes.guilds.automod.rule(guildId, ruleId), { reason }); }, async deleteChannel(channelId, reason) { await rest.delete(rest.routes.channels.channel(channelId), { reason, - }) + }); }, async deleteChannelPermissionOverride(channelId, overwriteId, reason) { - await rest.delete(rest.routes.channels.overwrite(channelId, overwriteId), { reason }) + await rest.delete(rest.routes.channels.overwrite(channelId, overwriteId), { reason }); }, async deleteEmoji(guildId, id, reason) { - await rest.delete(rest.routes.guilds.emoji(guildId, id), { reason }) + await rest.delete(rest.routes.guilds.emoji(guildId, id), { reason }); }, async deleteApplicationEmoji(id) { - await rest.delete(rest.routes.applicationEmoji(rest.applicationId, id)) + await rest.delete(rest.routes.applicationEmoji(rest.applicationId, id)); }, async deleteFollowupMessage(token, messageId) { - await rest.delete(rest.routes.interactions.responses.message(rest.applicationId, token, messageId), { unauthorized: true }) + await rest.delete(rest.routes.interactions.responses.message(rest.applicationId, token, messageId), { unauthorized: true }); }, async deleteGlobalApplicationCommand(commandId) { - await rest.delete(rest.routes.interactions.commands.command(rest.applicationId, commandId)) + await rest.delete(rest.routes.interactions.commands.command(rest.applicationId, commandId)); }, async deleteGuildApplicationCommand(commandId, guildId) { - await rest.delete(rest.routes.interactions.commands.guilds.one(rest.applicationId, guildId, commandId)) + await rest.delete(rest.routes.interactions.commands.guilds.one(rest.applicationId, guildId, commandId)); }, async deleteGuildSticker(guildId, stickerId, reason) { - await rest.delete(rest.routes.guilds.sticker(guildId, stickerId), { reason }) + await rest.delete(rest.routes.guilds.sticker(guildId, stickerId), { reason }); }, async deleteGuildTemplate(guildId, templateCode) { - await rest.delete(rest.routes.guilds.templates.guild(guildId, templateCode)) + await rest.delete(rest.routes.guilds.templates.guild(guildId, templateCode)); }, async deleteIntegration(guildId, integrationId, reason) { - await rest.delete(rest.routes.guilds.integration(guildId, integrationId), { reason }) + await rest.delete(rest.routes.guilds.integration(guildId, integrationId), { reason }); }, async deleteInvite(inviteCode, reason) { - await rest.delete(rest.routes.guilds.invite(inviteCode), { reason }) + await rest.delete(rest.routes.guilds.invite(inviteCode), { reason }); }, async deleteMessage(channelId, messageId, reason) { - await rest.delete(rest.routes.channels.message(channelId, messageId), { reason }) + await rest.delete(rest.routes.channels.message(channelId, messageId), { reason }); }, async deleteMessages(channelId, messageIds, reason) { @@ -905,59 +905,59 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage messages: messageIds.slice(0, 100).map((id) => id.toString()), }, reason, - }) + }); }, async deleteOriginalInteractionResponse(token) { - await rest.delete(rest.routes.interactions.responses.original(rest.applicationId, token), { unauthorized: true }) + await rest.delete(rest.routes.interactions.responses.original(rest.applicationId, token), { unauthorized: true }); }, async deleteOwnReaction(channelId, messageId, reaction) { - reaction = processReactionString(reaction) + reaction = processReactionString(reaction); - await rest.delete(rest.routes.channels.reactions.bot(channelId, messageId, reaction)) + await rest.delete(rest.routes.channels.reactions.bot(channelId, messageId, reaction)); }, async deleteReactionsAll(channelId, messageId) { - await rest.delete(rest.routes.channels.reactions.all(channelId, messageId)) + await rest.delete(rest.routes.channels.reactions.all(channelId, messageId)); }, async deleteReactionsEmoji(channelId, messageId, reaction) { - reaction = processReactionString(reaction) + reaction = processReactionString(reaction); - await rest.delete(rest.routes.channels.reactions.emoji(channelId, messageId, reaction)) + await rest.delete(rest.routes.channels.reactions.emoji(channelId, messageId, reaction)); }, async deleteRole(guildId, roleId, reason) { - await rest.delete(rest.routes.guilds.roles.one(guildId, roleId), { reason }) + await rest.delete(rest.routes.guilds.roles.one(guildId, roleId), { reason }); }, async deleteScheduledEvent(guildId, eventId) { - await rest.delete(rest.routes.guilds.events.event(guildId, eventId)) + await rest.delete(rest.routes.guilds.events.event(guildId, eventId)); }, async deleteStageInstance(channelId, reason) { - await rest.delete(rest.routes.channels.stage(channelId), { reason }) + await rest.delete(rest.routes.channels.stage(channelId), { reason }); }, async deleteUserReaction(channelId, messageId, userId, reaction) { - reaction = processReactionString(reaction) + reaction = processReactionString(reaction); - await rest.delete(rest.routes.channels.reactions.user(channelId, messageId, reaction, userId)) + await rest.delete(rest.routes.channels.reactions.user(channelId, messageId, reaction, userId)); }, async deleteWebhook(webhookId, reason) { - await rest.delete(rest.routes.webhooks.id(webhookId), { reason }) + await rest.delete(rest.routes.webhooks.id(webhookId), { reason }); }, async deleteWebhookMessage(webhookId, token, messageId, options) { - await rest.delete(rest.routes.webhooks.message(webhookId, token, messageId, options), { unauthorized: true }) + await rest.delete(rest.routes.webhooks.message(webhookId, token, messageId, options), { unauthorized: true }); }, async deleteWebhookWithToken(webhookId, token) { await rest.delete(rest.routes.webhooks.webhook(webhookId, token), { unauthorized: true, - }) + }); }, async editApplicationCommandPermissions(guildId, commandId, bearerToken, permissions) { @@ -969,16 +969,16 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage }, headers: { authorization: `Bearer ${bearerToken}` }, }, - ) + ); }, async editAutomodRule(guildId, ruleId, body, reason) { - return await rest.patch(rest.routes.guilds.automod.rule(guildId, ruleId), { body, reason }) + return await rest.patch(rest.routes.guilds.automod.rule(guildId, ruleId), { body, reason }); }, async editBotProfile(options) { - const avatar = options?.botAvatarURL ? await urlToBase64(options?.botAvatarURL) : options?.botAvatarURL - const banner = options?.botBannerURL ? await urlToBase64(options?.botBannerURL) : options?.botBannerURL + const avatar = options?.botAvatarURL ? await urlToBase64(options?.botAvatarURL) : options?.botAvatarURL; + const banner = options?.botBannerURL ? await urlToBase64(options?.botBannerURL) : options?.botBannerURL; return await rest.patch(rest.routes.currentUser(), { body: { @@ -986,27 +986,27 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage avatar, banner, }, - }) + }); }, async editChannel(channelId, body, reason) { - return await rest.patch(rest.routes.channels.channel(channelId), { body, reason }) + return await rest.patch(rest.routes.channels.channel(channelId), { body, reason }); }, async editChannelPermissionOverrides(channelId, body, reason) { - await rest.put(rest.routes.channels.overwrite(channelId, body.id), { body, reason }) + await rest.put(rest.routes.channels.overwrite(channelId, body.id), { body, reason }); }, async editChannelPositions(guildId, body) { - await rest.patch(rest.routes.guilds.channels(guildId), { body }) + await rest.patch(rest.routes.guilds.channels(guildId), { body }); }, async editEmoji(guildId, id, body, reason) { - return await rest.patch(rest.routes.guilds.emoji(guildId, id), { body, reason }) + return await rest.patch(rest.routes.guilds.emoji(guildId, id), { body, reason }); }, async editApplicationEmoji(id, body) { - return await rest.patch(rest.routes.applicationEmoji(rest.applicationId, id), { body }) + return await rest.patch(rest.routes.applicationEmoji(rest.applicationId, id), { body }); }, async editFollowupMessage(token, messageId, body) { @@ -1014,33 +1014,33 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage body, files: body.files, unauthorized: true, - }) + }); }, async editGlobalApplicationCommand(commandId, body) { - return await rest.patch(rest.routes.interactions.commands.command(rest.applicationId, commandId), { body }) + return await rest.patch(rest.routes.interactions.commands.command(rest.applicationId, commandId), { body }); }, async editGuild(guildId, body, reason) { - return await rest.patch(rest.routes.guilds.guild(guildId), { body, reason }) + return await rest.patch(rest.routes.guilds.guild(guildId), { body, reason }); }, async editGuildApplicationCommand(commandId, guildId, body) { return await rest.patch(rest.routes.interactions.commands.guilds.one(rest.applicationId, guildId, commandId), { body, - }) + }); }, async editGuildSticker(guildId, stickerId, body, reason) { - return await rest.patch(rest.routes.guilds.sticker(guildId, stickerId), { body, reason }) + return await rest.patch(rest.routes.guilds.sticker(guildId, stickerId), { body, reason }); }, async editGuildTemplate(guildId, templateCode: string, body: ModifyGuildTemplate): Promise> { - return await rest.patch(rest.routes.guilds.templates.guild(guildId, templateCode), { body }) + return await rest.patch(rest.routes.guilds.templates.guild(guildId, templateCode), { body }); }, async editMessage(channelId, messageId, body) { - return await rest.patch(rest.routes.channels.message(channelId, messageId), { body, files: body.files }) + return await rest.patch(rest.routes.channels.message(channelId, messageId), { body, files: body.files }); }, async editOriginalInteractionResponse(token, body) { @@ -1048,7 +1048,7 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage body, files: body.files, unauthorized: true, - }) + }); }, async editOwnVoiceState(guildId, options) { @@ -1059,31 +1059,31 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage ? new Date(options.requestToSpeakTimestamp).toISOString() : options.requestToSpeakTimestamp, }, - }) + }); }, async editScheduledEvent(guildId, eventId, body, reason) { - return await rest.patch(rest.routes.guilds.events.event(guildId, eventId), { body, reason }) + return await rest.patch(rest.routes.guilds.events.event(guildId, eventId), { body, reason }); }, async editRole(guildId, roleId, body, reason) { - return await rest.patch(rest.routes.guilds.roles.one(guildId, roleId), { body, reason }) + return await rest.patch(rest.routes.guilds.roles.one(guildId, roleId), { body, reason }); }, async editRolePositions(guildId, body, reason) { - return await rest.patch(rest.routes.guilds.roles.all(guildId), { body, reason }) + return await rest.patch(rest.routes.guilds.roles.all(guildId), { body, reason }); }, async editStageInstance(channelId, topic, reason?: string) { - return await rest.patch(rest.routes.channels.stage(channelId), { body: { topic }, reason }) + return await rest.patch(rest.routes.channels.stage(channelId), { body: { topic }, reason }); }, async editUserVoiceState(guildId, options) { - await rest.patch(rest.routes.guilds.voice(guildId, options.userId), { body: options }) + await rest.patch(rest.routes.guilds.voice(guildId, options.userId), { body: options }); }, async editWebhook(webhookId, body, reason) { - return await rest.patch(rest.routes.webhooks.id(webhookId), { body, reason }) + return await rest.patch(rest.routes.webhooks.id(webhookId), { body, reason }); }, async editWebhookMessage(webhookId, token, messageId, options) { @@ -1091,29 +1091,29 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage body: options, files: options.files, unauthorized: true, - }) + }); }, async editWebhookWithToken(webhookId, token, body) { return await rest.patch(rest.routes.webhooks.webhook(webhookId, token), { body, unauthorized: true, - }) + }); }, async editWelcomeScreen(guildId, body, reason) { - return await rest.patch(rest.routes.guilds.welcome(guildId), { body, reason }) + return await rest.patch(rest.routes.guilds.welcome(guildId), { body, reason }); }, async editWidgetSettings(guildId, body, reason) { - return await rest.patch(rest.routes.guilds.widget(guildId), { body, reason }) + return await rest.patch(rest.routes.guilds.widget(guildId), { body, reason }); }, async executeWebhook(webhookId, token, options) { return await rest.post(rest.routes.webhooks.webhook(webhookId, token, options), { body: options, unauthorized: true, - }) + }); }, async followAnnouncement(sourceChannelId, targetChannelId, reason) { @@ -1122,53 +1122,53 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage webhookChannelId: targetChannelId, }, reason, - }) + }); }, async getActiveThreads(guildId) { - return await rest.get(rest.routes.channels.threads.active(guildId)) + return await rest.get(rest.routes.channels.threads.active(guildId)); }, async getApplicationCommandPermission(guildId, commandId, options) { - const restOptions: Omit = {} + const restOptions: Omit = {}; if (options?.accessToken) { - restOptions.unauthorized = true + restOptions.unauthorized = true; restOptions.headers = { authorization: `Bearer ${options.accessToken}`, - } + }; } return await rest.get( rest.routes.interactions.commands.permission(options?.applicationId ?? rest.applicationId, guildId, commandId), restOptions, - ) + ); }, async getApplicationCommandPermissions(guildId, options) { - const restOptions: Omit = {} + const restOptions: Omit = {}; if (options?.accessToken) { - restOptions.unauthorized = true + restOptions.unauthorized = true; restOptions.headers = { authorization: `Bearer ${options.accessToken}`, - } + }; } return await rest.get( rest.routes.interactions.commands.permissions(options?.applicationId ?? rest.applicationId, guildId), restOptions, - ) + ); }, async getApplicationInfo() { - return await rest.get(rest.routes.oauth2.application()) + return await rest.get(rest.routes.oauth2.application()); }, async editApplicationInfo(body) { return await rest.patch(rest.routes.application(), { body, - }) + }); }, async getCurrentAuthenticationInfo(token) { @@ -1177,11 +1177,11 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage authorization: `Bearer ${token}`, }, unauthorized: true, - }) + }); }, async exchangeToken(clientId, clientSecret, body) { - const basicCredentials = Buffer.from(`${clientId}:${clientSecret}`) + const basicCredentials = Buffer.from(`${clientId}:${clientSecret}`); const restOptions: MakeRequestOptions = { body, @@ -1191,17 +1191,17 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage }, runThroughQueue: false, unauthorized: true, - } + }; if (body.grantType === 'client_credentials') { - restOptions.body.scope = body.scope.join(' ') + restOptions.body.scope = body.scope.join(' '); } - return await rest.post(rest.routes.oauth2.tokenExchange(), restOptions) + return await rest.post(rest.routes.oauth2.tokenExchange(), restOptions); }, async revokeToken(clientId, clientSecret, body) { - const basicCredentials = Buffer.from(`${clientId}:${clientSecret}`) + const basicCredentials = Buffer.from(`${clientId}:${clientSecret}`); await rest.post(rest.routes.oauth2.tokenRevoke(), { body, @@ -1210,95 +1210,95 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage authorization: `Basic ${basicCredentials.toString('base64')}`, }, unauthorized: true, - }) + }); }, async getAuditLog(guildId, options) { - return await rest.get(rest.routes.guilds.auditlogs(guildId, options)) + return await rest.get(rest.routes.guilds.auditlogs(guildId, options)); }, async getAutomodRule(guildId, ruleId) { - return await rest.get(rest.routes.guilds.automod.rule(guildId, ruleId)) + return await rest.get(rest.routes.guilds.automod.rule(guildId, ruleId)); }, async getAutomodRules(guildId) { - return await rest.get(rest.routes.guilds.automod.rules(guildId)) + return await rest.get(rest.routes.guilds.automod.rules(guildId)); }, async getAvailableVoiceRegions() { - return await rest.get(rest.routes.regions()) + return await rest.get(rest.routes.regions()); }, async getBan(guildId, userId) { - return await rest.get(rest.routes.guilds.members.ban(guildId, userId)) + return await rest.get(rest.routes.guilds.members.ban(guildId, userId)); }, async getBans(guildId, options) { - return await rest.get(rest.routes.guilds.members.bans(guildId, options)) + return await rest.get(rest.routes.guilds.members.bans(guildId, options)); }, async getChannel(id) { - return await rest.get(rest.routes.channels.channel(id)) + return await rest.get(rest.routes.channels.channel(id)); }, async getChannelInvites(channelId) { - return await rest.get(rest.routes.channels.invites(channelId)) + return await rest.get(rest.routes.channels.invites(channelId)); }, async getChannels(guildId) { - return await rest.get(rest.routes.guilds.channels(guildId)) + return await rest.get(rest.routes.guilds.channels(guildId)); }, async getChannelWebhooks(channelId) { - return await rest.get(rest.routes.channels.webhooks(channelId)) + return await rest.get(rest.routes.channels.webhooks(channelId)); }, async getDmChannel(userId) { return await rest.post(rest.routes.channels.dm(), { body: { recipientId: userId }, - }) + }); }, async getGroupDmChannel(body) { return await rest.post(rest.routes.channels.dm(), { body, - }) + }); }, async getEmoji(guildId, emojiId) { - return await rest.get(rest.routes.guilds.emoji(guildId, emojiId)) + return await rest.get(rest.routes.guilds.emoji(guildId, emojiId)); }, async getApplicationEmoji(emojiId) { - return await rest.get(rest.routes.applicationEmoji(rest.applicationId, emojiId)) + return await rest.get(rest.routes.applicationEmoji(rest.applicationId, emojiId)); }, async getEmojis(guildId) { - return await rest.get(rest.routes.guilds.emojis(guildId)) + return await rest.get(rest.routes.guilds.emojis(guildId)); }, async getApplicationEmojis() { - return await rest.get<{ items: DiscordEmoji[] }>(rest.routes.applicationEmojis(rest.applicationId)) + return await rest.get<{ items: DiscordEmoji[] }>(rest.routes.applicationEmojis(rest.applicationId)); }, async getFollowupMessage(token, messageId) { - return await rest.get(rest.routes.interactions.responses.message(rest.applicationId, token, messageId), { unauthorized: true }) + return await rest.get(rest.routes.interactions.responses.message(rest.applicationId, token, messageId), { unauthorized: true }); }, async getGatewayBot() { - return await rest.get(rest.routes.gatewayBot()) + return await rest.get(rest.routes.gatewayBot()); }, async getGlobalApplicationCommand(commandId) { - return await rest.get(rest.routes.interactions.commands.command(rest.applicationId, commandId)) + return await rest.get(rest.routes.interactions.commands.command(rest.applicationId, commandId)); }, async getGlobalApplicationCommands(options) { - return await rest.get(rest.routes.interactions.commands.commands(rest.applicationId, options?.withLocalizations)) + return await rest.get(rest.routes.interactions.commands.commands(rest.applicationId, options?.withLocalizations)); }, async getGuild(guildId, options = { counts: true }) { - return await rest.get(rest.routes.guilds.guild(guildId, options.counts)) + return await rest.get(rest.routes.guilds.guild(guildId, options.counts)); }, async getGuilds(token, options) { @@ -1309,155 +1309,155 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage }, unauthorized: true, } - : undefined + : undefined; - return await rest.get[]>(rest.routes.guilds.userGuilds(options), makeRequestOptions) + return await rest.get[]>(rest.routes.guilds.userGuilds(options), makeRequestOptions); }, async getGuildApplicationCommand(commandId, guildId) { - return await rest.get(rest.routes.interactions.commands.guilds.one(rest.applicationId, guildId, commandId)) + return await rest.get(rest.routes.interactions.commands.guilds.one(rest.applicationId, guildId, commandId)); }, async getGuildApplicationCommands(guildId, options) { return await rest.get( rest.routes.interactions.commands.guilds.all(rest.applicationId, guildId, options?.withLocalizations), - ) + ); }, async getGuildPreview(guildId) { - return await rest.get(rest.routes.guilds.preview(guildId)) + return await rest.get(rest.routes.guilds.preview(guildId)); }, async getGuildTemplate(templateCode) { - return await rest.get(rest.routes.guilds.templates.code(templateCode)) + return await rest.get(rest.routes.guilds.templates.code(templateCode)); }, async getGuildTemplates(guildId) { - return await rest.get(rest.routes.guilds.templates.all(guildId)) + return await rest.get(rest.routes.guilds.templates.all(guildId)); }, async getGuildWebhooks(guildId) { - return await rest.get(rest.routes.guilds.webhooks(guildId)) + return await rest.get(rest.routes.guilds.webhooks(guildId)); }, async getIntegrations(guildId) { - return await rest.get(rest.routes.guilds.integrations(guildId)) + return await rest.get(rest.routes.guilds.integrations(guildId)); }, async getInvite(inviteCode, options) { - return await rest.get(rest.routes.guilds.invite(inviteCode, options)) + return await rest.get(rest.routes.guilds.invite(inviteCode, options)); }, async getInvites(guildId) { - return await rest.get(rest.routes.guilds.invites(guildId)) + return await rest.get(rest.routes.guilds.invites(guildId)); }, async getMessage(channelId, messageId) { - return await rest.get(rest.routes.channels.message(channelId, messageId)) + return await rest.get(rest.routes.channels.message(channelId, messageId)); }, async getMessages(channelId, options) { - return await rest.get(rest.routes.channels.messages(channelId, options)) + return await rest.get(rest.routes.channels.messages(channelId, options)); }, async getStickerPack(stickerPackId) { - return await rest.get(rest.routes.stickerPack(stickerPackId)) + return await rest.get(rest.routes.stickerPack(stickerPackId)); }, async getStickerPacks() { - return await rest.get(rest.routes.stickerPacks()) + return await rest.get(rest.routes.stickerPacks()); }, async getOriginalInteractionResponse(token) { - return await rest.get(rest.routes.interactions.responses.original(rest.applicationId, token), { unauthorized: true }) + return await rest.get(rest.routes.interactions.responses.original(rest.applicationId, token), { unauthorized: true }); }, async getChannelPins(channelId, options) { - return await rest.get(rest.routes.channels.messagePins(channelId, options)) + return await rest.get(rest.routes.channels.messagePins(channelId, options)); }, async getPinnedMessages(channelId) { - return await rest.get(rest.routes.channels.pins(channelId)) + return await rest.get(rest.routes.channels.pins(channelId)); }, async getPrivateArchivedThreads(channelId, options) { - return await rest.get(rest.routes.channels.threads.private(channelId, options)) + return await rest.get(rest.routes.channels.threads.private(channelId, options)); }, async getPrivateJoinedArchivedThreads(channelId, options) { - return await rest.get(rest.routes.channels.threads.joined(channelId, options)) + return await rest.get(rest.routes.channels.threads.joined(channelId, options)); }, async getPruneCount(guildId, options) { - return await rest.get(rest.routes.guilds.prune(guildId, options)) + return await rest.get(rest.routes.guilds.prune(guildId, options)); }, async getPublicArchivedThreads(channelId, options) { - return await rest.get(rest.routes.channels.threads.public(channelId, options)) + return await rest.get(rest.routes.channels.threads.public(channelId, options)); }, async getRoles(guildId) { - return await rest.get(rest.routes.guilds.roles.all(guildId)) + return await rest.get(rest.routes.guilds.roles.all(guildId)); }, async getRole(guildId, roleId) { - return await rest.get(rest.routes.guilds.roles.one(guildId, roleId)) + return await rest.get(rest.routes.guilds.roles.one(guildId, roleId)); }, async getScheduledEvent(guildId, eventId, options) { - return await rest.get(rest.routes.guilds.events.event(guildId, eventId, options?.withUserCount)) + return await rest.get(rest.routes.guilds.events.event(guildId, eventId, options?.withUserCount)); }, async getScheduledEvents(guildId, options) { - return await rest.get(rest.routes.guilds.events.events(guildId, options?.withUserCount)) + return await rest.get(rest.routes.guilds.events.events(guildId, options?.withUserCount)); }, async getScheduledEventUsers(guildId, eventId, options) { - return await rest.get>(rest.routes.guilds.events.users(guildId, eventId, options)) + return await rest.get>(rest.routes.guilds.events.users(guildId, eventId, options)); }, async getSessionInfo() { - return await rest.getGatewayBot() + return await rest.getGatewayBot(); }, async getStageInstance(channelId) { - return await rest.get(rest.routes.channels.stage(channelId)) + return await rest.get(rest.routes.channels.stage(channelId)); }, async getOwnVoiceState(guildId) { - return await rest.get(rest.routes.guilds.voice(guildId)) + return await rest.get(rest.routes.guilds.voice(guildId)); }, async getUserVoiceState(guildId, userId) { - return await rest.get(rest.routes.guilds.voice(guildId, userId)) + return await rest.get(rest.routes.guilds.voice(guildId, userId)); }, async getSticker(stickerId: BigString) { - return await rest.get(rest.routes.sticker(stickerId)) + return await rest.get(rest.routes.sticker(stickerId)); }, async getGuildSticker(guildId, stickerId) { - return await rest.get(rest.routes.guilds.sticker(guildId, stickerId)) + return await rest.get(rest.routes.guilds.sticker(guildId, stickerId)); }, async getGuildStickers(guildId) { - return await rest.get(rest.routes.guilds.stickers(guildId)) + return await rest.get(rest.routes.guilds.stickers(guildId)); }, async getThreadMember(channelId, userId, options) { - return await rest.get(rest.routes.channels.threads.getUser(channelId, userId, options)) + return await rest.get(rest.routes.channels.threads.getUser(channelId, userId, options)); }, async getThreadMembers(channelId, options) { - return await rest.get(rest.routes.channels.threads.members(channelId, options)) + return await rest.get(rest.routes.channels.threads.members(channelId, options)); }, async getReactions(channelId, messageId, reaction, options) { - return await rest.get(rest.routes.channels.reactions.message(channelId, messageId, reaction, options)) + return await rest.get(rest.routes.channels.reactions.message(channelId, messageId, reaction, options)); }, async getUser(id) { - return await rest.get(rest.routes.user(id)) + return await rest.get(rest.routes.user(id)); }, async getCurrentUser(token) { @@ -1466,7 +1466,7 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage authorization: `Bearer ${token}`, }, unauthorized: true, - }) + }); }, async getUserConnections(token) { @@ -1475,7 +1475,7 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage authorization: `Bearer ${token}`, }, unauthorized: true, - }) + }); }, async getUserApplicationRoleConnection(token, applicationId) { @@ -1484,71 +1484,71 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage authorization: `Bearer ${token}`, }, unauthorized: true, - }) + }); }, async getVanityUrl(guildId) { - return await rest.get(rest.routes.guilds.vanity(guildId)) + return await rest.get(rest.routes.guilds.vanity(guildId)); }, async getVoiceRegions(guildId) { - return await rest.get(rest.routes.guilds.regions(guildId)) + return await rest.get(rest.routes.guilds.regions(guildId)); }, async getWebhook(webhookId) { - return await rest.get(rest.routes.webhooks.id(webhookId)) + return await rest.get(rest.routes.webhooks.id(webhookId)); }, async getWebhookMessage(webhookId, token, messageId, options) { return await rest.get(rest.routes.webhooks.message(webhookId, token, messageId, options), { unauthorized: true, - }) + }); }, async getWebhookWithToken(webhookId, token) { return await rest.get(rest.routes.webhooks.webhook(webhookId, token), { unauthorized: true, - }) + }); }, async getWelcomeScreen(guildId) { - return await rest.get(rest.routes.guilds.welcome(guildId)) + return await rest.get(rest.routes.guilds.welcome(guildId)); }, async getWidget(guildId) { - return await rest.get(rest.routes.guilds.widgetJson(guildId)) + return await rest.get(rest.routes.guilds.widgetJson(guildId)); }, async getWidgetSettings(guildId) { - return await rest.get(rest.routes.guilds.widget(guildId)) + return await rest.get(rest.routes.guilds.widget(guildId)); }, async joinThread(channelId) { - await rest.put(rest.routes.channels.threads.me(channelId)) + await rest.put(rest.routes.channels.threads.me(channelId)); }, async leaveGuild(guildId) { - await rest.delete(rest.routes.guilds.leave(guildId)) + await rest.delete(rest.routes.guilds.leave(guildId)); }, async leaveThread(channelId) { - await rest.delete(rest.routes.channels.threads.me(channelId)) + await rest.delete(rest.routes.channels.threads.me(channelId)); }, async publishMessage(channelId, messageId) { - return await rest.post(rest.routes.channels.crosspost(channelId, messageId)) + return await rest.post(rest.routes.channels.crosspost(channelId, messageId)); }, async removeRole(guildId, userId, roleId, reason) { - await rest.delete(rest.routes.guilds.roles.member(guildId, userId, roleId), { reason }) + await rest.delete(rest.routes.guilds.roles.member(guildId, userId, roleId), { reason }); }, async removeThreadMember(channelId, userId) { - await rest.delete(rest.routes.channels.threads.user(channelId, userId)) + await rest.delete(rest.routes.channels.threads.user(channelId, userId)); }, async removeDmRecipient(channelId, userId) { - await rest.delete(rest.routes.channels.dmRecipient(channelId, userId)) + await rest.delete(rest.routes.channels.dmRecipient(channelId, userId)); }, async sendFollowupMessage(token, options) { @@ -1556,7 +1556,7 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage body: options, files: options.files, unauthorized: true, - }) + }); }, async sendInteractionResponse(interactionId, token, options, params) { @@ -1565,51 +1565,51 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage files: options.data?.files, runThroughQueue: false, unauthorized: true, - }) + }); }, async sendMessage(channelId, body) { - return await rest.post(rest.routes.channels.messages(channelId), { body, files: body.files }) + return await rest.post(rest.routes.channels.messages(channelId), { body, files: body.files }); }, async startThreadWithMessage(channelId, messageId, body, reason) { - return await rest.post(rest.routes.channels.threads.message(channelId, messageId), { body, reason }) + return await rest.post(rest.routes.channels.threads.message(channelId, messageId), { body, reason }); }, async startThreadWithoutMessage(channelId, body, reason) { - return await rest.post(rest.routes.channels.threads.all(channelId), { body, reason }) + return await rest.post(rest.routes.channels.threads.all(channelId), { body, reason }); }, async getPollAnswerVoters(channelId, messageId, answerId, options) { - return await rest.get(rest.routes.channels.polls.votes(channelId, messageId, answerId, options)) + return await rest.get(rest.routes.channels.polls.votes(channelId, messageId, answerId, options)); }, async endPoll(channelId, messageId) { - return await rest.post(rest.routes.channels.polls.expire(channelId, messageId)) + return await rest.post(rest.routes.channels.polls.expire(channelId, messageId)); }, async syncGuildTemplate(guildId) { - return await rest.put(rest.routes.guilds.templates.all(guildId)) + return await rest.put(rest.routes.guilds.templates.all(guildId)); }, async banMember(guildId, userId, body, reason) { - await rest.put(rest.routes.guilds.members.ban(guildId, userId), { body, reason }) + await rest.put(rest.routes.guilds.members.ban(guildId, userId), { body, reason }); }, async bulkBanMembers(guildId, options, reason) { - return await rest.post(rest.routes.guilds.members.bulkBan(guildId), { body: options, reason }) + return await rest.post(rest.routes.guilds.members.bulkBan(guildId), { body: options, reason }); }, async editBotMember(guildId, body, reason) { - return await rest.patch(rest.routes.guilds.members.bot(guildId), { body, reason }) + return await rest.patch(rest.routes.guilds.members.bot(guildId), { body, reason }); }, async editMember(guildId, userId, body, reason) { - return await rest.patch(rest.routes.guilds.members.member(guildId, userId), { body, reason }) + return await rest.patch(rest.routes.guilds.members.member(guildId, userId), { body, reason }); }, async getMember(guildId, userId) { - return await rest.get(rest.routes.guilds.members.member(guildId, userId)) + return await rest.get(rest.routes.guilds.members.member(guildId, userId)); }, async getCurrentMember(guildId, token) { @@ -1618,86 +1618,86 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage authorization: `Bearer ${token}`, }, unauthorized: true, - }) + }); }, async getMembers(guildId, options) { - return await rest.get(rest.routes.guilds.members.members(guildId, options)) + return await rest.get(rest.routes.guilds.members.members(guildId, options)); }, async getApplicationActivityInstance(applicationId, instanceId) { - return await rest.get(rest.routes.applicationActivityInstance(applicationId, instanceId)) + return await rest.get(rest.routes.applicationActivityInstance(applicationId, instanceId)); }, async kickMember(guildId, userId, reason) { await rest.delete(rest.routes.guilds.members.member(guildId, userId), { reason, - }) + }); }, async pinMessage(channelId, messageId, reason) { - await rest.put(rest.routes.channels.messagePin(channelId, messageId), { reason }) + await rest.put(rest.routes.channels.messagePin(channelId, messageId), { reason }); }, async pruneMembers(guildId, body, reason) { - return await rest.post<{ pruned: number | null }>(rest.routes.guilds.members.prune(guildId), { body, reason }) + return await rest.post<{ pruned: number | null }>(rest.routes.guilds.members.prune(guildId), { body, reason }); }, async searchMembers(guildId, query, options) { - return await rest.get(rest.routes.guilds.members.search(guildId, query, options)) + return await rest.get(rest.routes.guilds.members.search(guildId, query, options)); }, async getGuildOnboarding(guildId) { - return await rest.get(rest.routes.guilds.onboarding(guildId)) + return await rest.get(rest.routes.guilds.onboarding(guildId)); }, async editGuildOnboarding(guildId, options, reason) { return await rest.put(rest.routes.guilds.onboarding(guildId), { body: options, reason, - }) + }); }, async modifyGuildIncidentActions(guildId, options) { - return await rest.put(rest.routes.guilds.incidentActions(guildId), { body: options }) + return await rest.put(rest.routes.guilds.incidentActions(guildId), { body: options }); }, async unbanMember(guildId, userId, reason) { - await rest.delete(rest.routes.guilds.members.ban(guildId, userId), { reason }) + await rest.delete(rest.routes.guilds.members.ban(guildId, userId), { reason }); }, async unpinMessage(channelId, messageId, reason) { - await rest.delete(rest.routes.channels.messagePin(channelId, messageId), { reason }) + await rest.delete(rest.routes.channels.messagePin(channelId, messageId), { reason }); }, async triggerTypingIndicator(channelId) { - await rest.post(rest.routes.channels.typing(channelId)) + await rest.post(rest.routes.channels.typing(channelId)); }, async upsertGlobalApplicationCommands(body, options) { - const restOptions: MakeRequestOptions = { body } + const restOptions: MakeRequestOptions = { body }; if (options?.bearerToken) { - restOptions.unauthorized = true + restOptions.unauthorized = true; restOptions.headers = { authorization: `Bearer ${options.bearerToken}`, - } + }; } - return await rest.put(rest.routes.interactions.commands.commands(rest.applicationId), restOptions) + return await rest.put(rest.routes.interactions.commands.commands(rest.applicationId), restOptions); }, async upsertGuildApplicationCommands(guildId, body, options) { - const restOptions: MakeRequestOptions = { body } + const restOptions: MakeRequestOptions = { body }; if (options?.bearerToken) { - restOptions.unauthorized = true + restOptions.unauthorized = true; restOptions.headers = { authorization: `Bearer ${options.bearerToken}`, - } + }; } - return await rest.put(rest.routes.interactions.commands.guilds.all(rest.applicationId, guildId), restOptions) + return await rest.put(rest.routes.interactions.commands.guilds.all(rest.applicationId, guildId), restOptions); }, async editUserApplicationRoleConnection(token, applicationId, body) { @@ -1707,125 +1707,125 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage authorization: `Bearer ${token}`, }, unauthorized: true, - }) + }); }, async addGuildMember(guildId, userId, body) { return await rest.put(rest.routes.guilds.members.member(guildId, userId), { body, - }) + }); }, async createTestEntitlement(applicationId, body) { return await rest.post(rest.routes.monetization.entitlements(applicationId), { body, - }) + }); }, async listEntitlements(applicationId, options) { - return await rest.get(rest.routes.monetization.entitlements(applicationId, options)) + return await rest.get(rest.routes.monetization.entitlements(applicationId, options)); }, async getEntitlement(applicationId, entitlementId) { - return await rest.get(rest.routes.monetization.entitlement(applicationId, entitlementId)) + return await rest.get(rest.routes.monetization.entitlement(applicationId, entitlementId)); }, async deleteTestEntitlement(applicationId, entitlementId) { - await rest.delete(rest.routes.monetization.entitlement(applicationId, entitlementId)) + await rest.delete(rest.routes.monetization.entitlement(applicationId, entitlementId)); }, async consumeEntitlement(applicationId, entitlementId) { - await rest.post(rest.routes.monetization.consumeEntitlement(applicationId, entitlementId)) + await rest.post(rest.routes.monetization.consumeEntitlement(applicationId, entitlementId)); }, async listSkus(applicationId) { - return await rest.get(rest.routes.monetization.skus(applicationId)) + return await rest.get(rest.routes.monetization.skus(applicationId)); }, async listSubscriptions(skuId, options) { - return await rest.get(rest.routes.monetization.subscriptions(skuId, options)) + return await rest.get(rest.routes.monetization.subscriptions(skuId, options)); }, async getSubscription(skuId, subscriptionId) { - return await rest.get(rest.routes.monetization.subscription(skuId, subscriptionId)) + return await rest.get(rest.routes.monetization.subscription(skuId, subscriptionId)); }, async sendSoundboardSound(channelId, options) { await rest.post(rest.routes.soundboard.sendSound(channelId), { body: options, - }) + }); }, async listDefaultSoundboardSounds() { - return await rest.get(rest.routes.soundboard.listDefault()) + return await rest.get(rest.routes.soundboard.listDefault()); }, async listGuildSoundboardSounds(guildId) { - return await rest.get<{ items: DiscordSoundboardSound[] }>(rest.routes.soundboard.guildSounds(guildId)) + return await rest.get<{ items: DiscordSoundboardSound[] }>(rest.routes.soundboard.guildSounds(guildId)); }, async getGuildSoundboardSound(guildId, soundId) { - return await rest.get(rest.routes.soundboard.guildSound(guildId, soundId)) + return await rest.get(rest.routes.soundboard.guildSound(guildId, soundId)); }, async createGuildSoundboardSound(guildId, options, reason) { return await rest.post(rest.routes.soundboard.guildSounds(guildId), { body: options, reason, - }) + }); }, async modifyGuildSoundboardSound(guildId, soundId, options, reason) { return await rest.post(rest.routes.soundboard.guildSound(guildId, soundId), { body: options, reason, - }) + }); }, async deleteGuildSoundboardSound(guildId, soundId, reason) { return await rest.delete(rest.routes.soundboard.guildSound(guildId, soundId), { reason, - }) + }); }, async listApplicationRoleConnectionsMetadataRecords(applicationId) { - return await rest.get(rest.routes.applicationRoleConnectionMetadata(applicationId)) + return await rest.get(rest.routes.applicationRoleConnectionMetadata(applicationId)); }, async updateApplicationRoleConnectionsMetadataRecords(applicationId, options) { return await rest.put(rest.routes.applicationRoleConnectionMetadata(applicationId), { body: options, - }) + }); }, async createLobby(options) { return await rest.post(rest.routes.lobby.create(), { body: options, - }) + }); }, async getLobby(lobbyId) { - return await rest.get(rest.routes.lobby.lobby(lobbyId)) + return await rest.get(rest.routes.lobby.lobby(lobbyId)); }, async modifyLobby(lobbyId, options) { return await rest.patch(rest.routes.lobby.lobby(lobbyId), { body: options, - }) + }); }, async deleteLobby(lobbyId) { - return await rest.delete(rest.routes.lobby.lobby(lobbyId)) + return await rest.delete(rest.routes.lobby.lobby(lobbyId)); }, async addMemberToLobby(lobbyId, userId, options) { return await rest.put(rest.routes.lobby.member(lobbyId, userId), { body: options, - }) + }); }, async removeMemberFromLobby(lobbyId, userId) { - return await rest.delete(rest.routes.lobby.member(lobbyId, userId)) + return await rest.delete(rest.routes.lobby.member(lobbyId, userId)); }, async leaveLobby(lobbyId, bearerToken) { @@ -1834,7 +1834,7 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage authorization: `Bearer ${bearerToken}`, }, unauthorized: true, - }) + }); }, async linkChannelToLobby(lobbyId, bearerToken, options) { @@ -1844,7 +1844,7 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage authorization: `Bearer ${bearerToken}`, }, unauthorized: true, - }) + }); }, async unlinkChannelToLobby(lobbyId, bearerToken) { @@ -1853,37 +1853,37 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage authorization: `Bearer ${bearerToken}`, }, unauthorized: true, - }) + }); }, preferSnakeCase(enabled: boolean) { - const camelizer = enabled ? (x: any) => x : camelize + const camelizer = enabled ? (x: any) => x : camelize; rest.get = async (url, options) => { - return camelizer(await rest.makeRequest('GET', url, options)) - } + return camelizer(await rest.makeRequest('GET', url, options)); + }; rest.post = async (url: string, options?: Omit) => { - return camelizer(await rest.makeRequest('POST', url, options)) - } + return camelizer(await rest.makeRequest('POST', url, options)); + }; rest.delete = async (url: string, options?: Omit) => { - camelizer(await rest.makeRequest('DELETE', url, options)) - } + camelizer(await rest.makeRequest('DELETE', url, options)); + }; rest.patch = async (url: string, options?: Omit) => { - return camelizer(await rest.makeRequest('PATCH', url, options)) - } + return camelizer(await rest.makeRequest('PATCH', url, options)); + }; rest.put = async (url: string, options?: Omit) => { - return camelizer(await rest.makeRequest('PUT', url, options)) - } + return camelizer(await rest.makeRequest('PUT', url, options)); + }; - return rest + return rest; }, - } + }; - return rest + return rest; } enum HttpResponseCode { diff --git a/packages/rest/src/queue.ts b/packages/rest/src/queue.ts index 9239526ad..89b0863c6 100644 --- a/packages/rest/src/queue.ts +++ b/packages/rest/src/queue.ts @@ -1,58 +1,58 @@ -import { delay } from '@discordeno/utils' -import type { RestManager, SendRequestOptions } from './types.js' +import { delay } from '@discordeno/utils'; +import type { RestManager, SendRequestOptions } from './types.js'; export class Queue { /** The rest manager */ - rest: RestManager + rest: RestManager; /** Amount of requests that have are remaining. Defaults to 1. */ - remaining: number = 1 + remaining: number = 1; /** Max requests for this this. Defaults to 1. */ - max: number = 1 + max: number = 1; /** The time that discord allows to make the max number of requests. Defaults to 0 */ - interval: number = 0 + interval: number = 0; /** timer to reset to 0 */ - timeoutId: NodeJS.Timeout | undefined + timeoutId: NodeJS.Timeout | undefined; /** The requests that are currently pending. */ - waiting: Array<(value: void | PromiseLike) => void> = [] + waiting: Array<(value: void | PromiseLike) => void> = []; /** The requests that are currently pending. */ - pending: SendRequestOptions[] = [] + pending: SendRequestOptions[] = []; /** Whether or not the waiting queue is already processing. */ - processing: boolean = false + processing: boolean = false; /** Whether or not the pending queue is already processing. */ - processingPending: boolean = false + processingPending: boolean = false; /** Whether the first request is pending. */ - firstRequest: boolean = false + firstRequest: boolean = false; /** The url that all the requests in this queue are sent to. */ - url: string + url: string; /** When requests started being made to determine when the interval will reset it. */ - frozenAt: number = 0 + frozenAt: number = 0; /** The time in milliseconds to wait before deleting this queue if it is empty. Defaults to 60000(one minute). */ - deleteQueueDelay: number = 60000 + deleteQueueDelay: number = 60000; /** The timeout for the deletion of this queue */ - deleteQueueTimeout?: NodeJS.Timeout + deleteQueueTimeout?: NodeJS.Timeout; /** * The identifier for this request, may be the request authorization or fallback to the bot auth * * @remarks * This is used to get the identify this queue from the queue mapping of the rest manager */ - identifier: string + identifier: string; constructor(rest: RestManager, options: QueueOptions) { - this.rest = rest - this.url = options.url - this.identifier = options.identifier + this.rest = rest; + this.url = options.url; + this.identifier = options.identifier; - if (options.interval) this.interval = options.interval - if (options.max) this.max = options.max - if (options.remaining) this.remaining = options.remaining - if (options.timeoutId) this.timeoutId = options.timeoutId - if (options.deleteQueueDelay) this.deleteQueueDelay = options.deleteQueueDelay + if (options.interval) this.interval = options.interval; + if (options.max) this.max = options.max; + if (options.remaining) this.remaining = options.remaining; + if (options.timeoutId) this.timeoutId = options.timeoutId; + if (options.deleteQueueDelay) this.deleteQueueDelay = options.deleteQueueDelay; } /** Check if there is any remaining requests that are allowed. */ isRequestAllowed(): boolean { - return this.remaining > 0 + return this.remaining > 0; } /** Pauses the execution until a request is allowed to be made. */ @@ -61,178 +61,178 @@ export class Queue { // If whatever amount of requests is left is more than the safety margin, allow the request if (this.isRequestAllowed()) { // this.remaining++; - resolve() + resolve(); } else { - this.waiting.push(resolve) - await this.processWaiting() + this.waiting.push(resolve); + await this.processWaiting(); } - }) + }); } /** Process the queue of requests waiting to be handled. */ async processWaiting(): Promise { // If already processing, that loop will handle all waiting requests. - if (this.processing) return + if (this.processing) return; // Mark as processing so other loops don't start - this.processing = true + this.processing = true; while (this.waiting.length > 0) { - this.rest.logger.debug(`[Queue] ${this.queueType} ${this.url} process waiting while loop ran.`) + this.rest.logger.debug(`[Queue] ${this.queueType} ${this.url} process waiting while loop ran.`); if (this.isRequestAllowed()) { // Resolve the next item in the queue - this.waiting.shift()?.() + this.waiting.shift()?.(); } else { - await delay(1000) + await delay(1000); } } // Mark as false so next pending request can be triggered by new loop. - this.processing = false + this.processing = false; } /** Process the queue of all requests pending to be sent. */ async processPending(): Promise { // If already processing, that loop will handle all pending requests. - if (this.processingPending || !this.pending.length) return + if (this.processingPending || !this.pending.length) return; // Mark as processing so other loops don't start - this.processingPending = true + this.processingPending = true; while (this.pending.length > 0) { - this.rest.logger.debug(`Queue ${this.queueType} ${this.url} process pending while loop ran with ${this.pending.length}.`) + this.rest.logger.debug(`Queue ${this.queueType} ${this.url} process pending while loop ran with ${this.pending.length}.`); if (!this.firstRequest && !this.isRequestAllowed()) { - const now = Date.now() - const future = this.frozenAt + this.interval - await delay(future > now ? future - now : 1000) - continue + const now = Date.now(); + const future = this.frozenAt + this.interval; + await delay(future > now ? future - now : 1000); + continue; } - const request = this.pending[0] + const request = this.pending[0]; if (request) { - const basicURL = this.rest.simplifyUrl(request.route, request.method) + const basicURL = this.rest.simplifyUrl(request.route, request.method); // If this url is still rate limited, try again - const urlResetIn = this.rest.checkRateLimits(basicURL, this.identifier) - if (urlResetIn) await delay(urlResetIn) + const urlResetIn = this.rest.checkRateLimits(basicURL, this.identifier); + if (urlResetIn) await delay(urlResetIn); // IF A BUCKET EXISTS, CHECK THE BUCKET'S RATE LIMITS - const bucketResetIn = request.bucketId ? this.rest.checkRateLimits(request.bucketId, this.identifier) : false - if (bucketResetIn) await delay(bucketResetIn) + const bucketResetIn = request.bucketId ? this.rest.checkRateLimits(request.bucketId, this.identifier) : false; + if (bucketResetIn) await delay(bucketResetIn); - this.firstRequest = false - this.remaining-- + this.firstRequest = false; + this.remaining--; if (this.remaining === 0 && this.interval !== 0) { this.timeoutId ??= setTimeout(() => { - this.remaining = this.max - this.timeoutId = undefined - }, this.interval) + this.remaining = this.max; + this.timeoutId = undefined; + }, this.interval); } // Remove from queue, we are executing it. - this.pending.shift() + this.pending.shift(); // Check if this request is able to be made globally - await this.rest.invalidBucket.waitUntilRequestAvailable() + await this.rest.invalidBucket.waitUntilRequestAvailable(); await this.rest .sendRequest(request) // Should be handled in sendRequest, this catch just prevents bots from dying - .catch(() => null) + .catch(() => null); } } - this.rest.logger.debug(`Queue ${this.queueType} ${this.url} process pending while loop exited with ${this.pending.length}.`) + this.rest.logger.debug(`Queue ${this.queueType} ${this.url} process pending while loop exited with ${this.pending.length}.`); // Mark as false so next pending request can be triggered by new loop. - this.processingPending = false - this.cleanup() + this.processingPending = false; + this.cleanup(); } handleCompletedRequest(headers: { max?: number; interval?: number; remaining?: number }): void { if (headers.max === 0) { - this.remaining++ - return + this.remaining++; + return; } - if (!this.frozenAt) this.frozenAt = Date.now() - if (headers.interval !== undefined) this.interval = headers.interval - if (headers.remaining !== undefined) this.remaining = headers.remaining + if (!this.frozenAt) this.frozenAt = Date.now(); + if (headers.interval !== undefined) this.interval = headers.interval; + if (headers.remaining !== undefined) this.remaining = headers.remaining; if (this.remaining <= 1) { this.timeoutId ??= setTimeout(() => { - this.remaining = this.max - this.timeoutId = undefined - }, headers.interval) + this.remaining = this.max; + this.timeoutId = undefined; + }, headers.interval); } } /** Checks if a request is available and adds it to the queue. Also triggers queue processing if not already processing. */ async makeRequest(options: SendRequestOptions): Promise { - await this.waitUntilRequestAvailable() - this.pending.push(options) - this.processPending() + await this.waitUntilRequestAvailable(); + this.pending.push(options); + this.processPending(); } /** Cleans up the queue by checking if there is nothing left and removing it. */ cleanup(): void { if (!this.isQueueClearable()) { - this.processPending() - return + this.processPending(); + return; } - this.rest.logger.debug(`[Queue] ${this.queueType} ${this.url}. Delaying delete for ${this.deleteQueueDelay}ms`) + this.rest.logger.debug(`[Queue] ${this.queueType} ${this.url}. Delaying delete for ${this.deleteQueueDelay}ms`); // Delete in a minute giving a bit of time to allow new requests that may reuse this queue - clearTimeout(this.deleteQueueTimeout) + clearTimeout(this.deleteQueueTimeout); this.deleteQueueTimeout = setTimeout(() => { if (!this.isQueueClearable()) { - this.rest.logger.debug(`[Queue] ${this.queueType} ${this.url}. is not clearable. Restarting processing of queue.`) - this.processPending() - return + this.rest.logger.debug(`[Queue] ${this.queueType} ${this.url}. is not clearable. Restarting processing of queue.`); + this.processPending(); + return; } - this.rest.logger.debug(`[Queue] ${this.queueType} ${this.url}. Deleting`) + this.rest.logger.debug(`[Queue] ${this.queueType} ${this.url}. Deleting`); - if (this.timeoutId) clearTimeout(this.timeoutId) + if (this.timeoutId) clearTimeout(this.timeoutId); // No requests have been requested for this queue so we nuke this queue - this.rest.queues.delete(`${this.identifier}${this.url}`) + this.rest.queues.delete(`${this.identifier}${this.url}`); this.rest.logger.debug( `[Queue] ${this.queueType} ${this.url}. Deleted! Remaining: (${this.rest.queues.size})`, [...this.rest.queues.values()].map((queue) => `${queue.queueType}${queue.url}`), - ) - }, this.deleteQueueDelay) + ); + }, this.deleteQueueDelay); } /** Simply checks if the queue is able to be cleared or it has requests pending. */ isQueueClearable(): boolean { - if (this.firstRequest) return false - if (this.waiting.length > 0) return false - if (this.pending.length > 0) return false - if (this.processing) return false - if (this.processingPending) return false + if (this.firstRequest) return false; + if (this.waiting.length > 0) return false; + if (this.pending.length > 0) return false; + if (this.processing) return false; + if (this.processingPending) return false; - return true + return true; } get queueType(): string { - return this.identifier.slice(0, this.identifier.indexOf(' ')) + return this.identifier.slice(0, this.identifier.indexOf(' ')); } } export interface QueueOptions { /** How many requests are remaining. Defaults to 1 */ - remaining?: number + remaining?: number; /** Max number of requests allowed in this this. Defaults to 1. */ - max?: number + max?: number; /** The time in milliseconds that discord allows to make the max number of invalid requests. Defaults to 0 */ - interval?: number + interval?: number; /** timer to reset to 0 */ - timeoutId?: NodeJS.Timeout + timeoutId?: NodeJS.Timeout; /** The url this queue will be handling. */ - url: string + url: string; /** The time in milliseconds to wait before deleting this queue if it is empty. Defaults to 60000(one minute). */ - deleteQueueDelay?: number + deleteQueueDelay?: number; /** The base key that identifies this queue in the rest manager */ - identifier: string + identifier: string; } diff --git a/packages/rest/src/routes.ts b/packages/rest/src/routes.ts index 963b1ff96..78cee44ff 100644 --- a/packages/rest/src/routes.ts +++ b/packages/rest/src/routes.ts @@ -1,6 +1,6 @@ -import type { GetMessagesOptions, GetScheduledEventUsers } from '@discordeno/types' -import { isGetMessagesAfter, isGetMessagesAround, isGetMessagesBefore, isGetMessagesLimit } from '@discordeno/utils' -import type { RestRoutes } from './typings/routes.js' +import type { GetMessagesOptions, GetScheduledEventUsers } from '@discordeno/types'; +import { isGetMessagesAfter, isGetMessagesAround, isGetMessagesBefore, isGetMessagesLimit } from '@discordeno/utils'; +import type { RestRoutes } from './typings/routes.js'; /** * Creates the available discord API routes @@ -9,257 +9,257 @@ import type { RestRoutes } from './typings/routes.js' * @returns The available discord API routes */ export function createRoutes(disableURIEncode: boolean = false): RestRoutes { - const encode: typeof encodeComponent = disableURIEncode ? (x) => x.toString() : encodeComponent + const encode: typeof encodeComponent = disableURIEncode ? (x) => x.toString() : encodeComponent; return { webhooks: { id: (webhookId) => { - return `/webhooks/${encode(webhookId)}` + return `/webhooks/${encode(webhookId)}`; }, message: (webhookId, token, messageId, options) => { - let url = `/webhooks/${encode(webhookId)}/${encode(token)}/messages/${encode(messageId)}?` + let url = `/webhooks/${encode(webhookId)}/${encode(token)}/messages/${encode(messageId)}?`; if (options) { - if (options.threadId) url += `thread_id=${encode(options.threadId)}` - if (options.withComponents) url += `&with_components=${encode(options.withComponents)}` + if (options.threadId) url += `thread_id=${encode(options.threadId)}`; + if (options.withComponents) url += `&with_components=${encode(options.withComponents)}`; } - return url + return url; }, webhook: (webhookId, token, options) => { - let url = `/webhooks/${encode(webhookId)}/${encode(token)}?` + let url = `/webhooks/${encode(webhookId)}/${encode(token)}?`; if (options) { - if (options?.wait !== undefined) url += `wait=${encode(options.wait)}` - if (options.threadId) url += `&thread_id=${encode(options.threadId)}` - if (options.withComponents) url += `&with_components=${encode(options.withComponents)}` + if (options?.wait !== undefined) url += `wait=${encode(options.wait)}`; + if (options.threadId) url += `&thread_id=${encode(options.threadId)}`; + if (options.withComponents) url += `&with_components=${encode(options.withComponents)}`; } - return url + return url; }, }, // Channel Endpoints channels: { bulk: (channelId) => { - return `/channels/${encode(channelId)}/messages/bulk-delete` + return `/channels/${encode(channelId)}/messages/bulk-delete`; }, dm: () => { - return '/users/@me/channels' + return '/users/@me/channels'; }, dmRecipient: (channelId, userId) => { - return `/channels/${encode(channelId)}/recipients/${encode(userId)}` + return `/channels/${encode(channelId)}/recipients/${encode(userId)}`; }, pin: (channelId, messageId) => { - return `/channels/${encode(channelId)}/pins/${encode(messageId)}` + return `/channels/${encode(channelId)}/pins/${encode(messageId)}`; }, pins: (channelId) => { - return `/channels/${encode(channelId)}/pins` + return `/channels/${encode(channelId)}/pins`; }, messagePins: (channelId, options) => { - let url = `/channels/${encode(channelId)}/messages/pins?` + let url = `/channels/${encode(channelId)}/messages/pins?`; if (options) { - if (options.before) url += `before=${encode(options.before)}` - if (options.limit) url += `&limit=${encode(options.limit)}` + if (options.before) url += `before=${encode(options.before)}`; + if (options.limit) url += `&limit=${encode(options.limit)}`; } - return url + return url; }, messagePin: (channelId, messageId) => { - return `/channels/${encode(channelId)}/messages/pins/${encode(messageId)}` + return `/channels/${encode(channelId)}/messages/pins/${encode(messageId)}`; }, reactions: { bot: (channelId, messageId, emoji) => { - return `/channels/${encode(channelId)}/messages/${encode(messageId)}/reactions/${encodeURIComponent(emoji)}/@me` + return `/channels/${encode(channelId)}/messages/${encode(messageId)}/reactions/${encodeURIComponent(emoji)}/@me`; }, user: (channelId, messageId, emoji, userId) => { - return `/channels/${encode(channelId)}/messages/${encode(messageId)}/reactions/${encodeURIComponent(emoji)}/${encode(userId)}` + return `/channels/${encode(channelId)}/messages/${encode(messageId)}/reactions/${encodeURIComponent(emoji)}/${encode(userId)}`; }, all: (channelId, messageId) => { - return `/channels/${encode(channelId)}/messages/${encode(messageId)}/reactions` + return `/channels/${encode(channelId)}/messages/${encode(messageId)}/reactions`; }, emoji: (channelId, messageId, emoji, options) => { - let url = `/channels/${encode(channelId)}/messages/${encode(messageId)}/reactions/${encodeURIComponent(emoji)}?` + let url = `/channels/${encode(channelId)}/messages/${encode(messageId)}/reactions/${encodeURIComponent(emoji)}?`; if (options) { - if (options.type) url += `type=${encode(options.type)}` - if (options.after) url += `&after=${encode(options.after)}` - if (options.limit) url += `&limit=${encode(options.limit)}` + if (options.type) url += `type=${encode(options.type)}`; + if (options.after) url += `&after=${encode(options.after)}`; + if (options.limit) url += `&limit=${encode(options.limit)}`; } - return url + return url; }, message: (channelId, messageId, emoji, options) => { - let url = `/channels/${encode(channelId)}/messages/${encode(messageId)}/reactions/${encodeURIComponent(emoji)}?` + let url = `/channels/${encode(channelId)}/messages/${encode(messageId)}/reactions/${encodeURIComponent(emoji)}?`; if (options) { - if (options.after) url += `after=${encode(options.after)}` - if (options.limit) url += `&limit=${encode(options.limit)}` + if (options.after) url += `after=${encode(options.after)}`; + if (options.limit) url += `&limit=${encode(options.limit)}`; } - return url + return url; }, }, webhooks: (channelId) => { - return `/channels/${encode(channelId)}/webhooks` + return `/channels/${encode(channelId)}/webhooks`; }, channel: (channelId) => { - return `/channels/${encode(channelId)}` + return `/channels/${encode(channelId)}`; }, follow: (channelId) => { - return `/channels/${encode(channelId)}/followers` + return `/channels/${encode(channelId)}/followers`; }, forum: (channelId) => { - return `/channels/${encode(channelId)}/threads` + return `/channels/${encode(channelId)}/threads`; }, invites: (channelId) => { - return `/channels/${encode(channelId)}/invites` + return `/channels/${encode(channelId)}/invites`; }, message: (channelId, messageId) => { - return `/channels/${encode(channelId)}/messages/${encode(messageId)}` + return `/channels/${encode(channelId)}/messages/${encode(messageId)}`; }, messages: (channelId, options?: GetMessagesOptions) => { - let url = `/channels/${encode(channelId)}/messages?` + let url = `/channels/${encode(channelId)}/messages?`; if (options) { if (isGetMessagesAfter(options) && options.after) { - url += `after=${encode(options.after)}` + url += `after=${encode(options.after)}`; } if (isGetMessagesBefore(options) && options.before) { - url += `&before=${encode(options.before)}` + url += `&before=${encode(options.before)}`; } if (isGetMessagesAround(options) && options.around) { - url += `&around=${encode(options.around)}` + url += `&around=${encode(options.around)}`; } if (isGetMessagesLimit(options) && options.limit) { - url += `&limit=${encode(options.limit)}` + url += `&limit=${encode(options.limit)}`; } } - return url + return url; }, overwrite: (channelId, overwriteId) => { - return `/channels/${encode(channelId)}/permissions/${encode(overwriteId)}` + return `/channels/${encode(channelId)}/permissions/${encode(overwriteId)}`; }, crosspost: (channelId, messageId) => { - return `/channels/${encode(channelId)}/messages/${encode(messageId)}/crosspost` + return `/channels/${encode(channelId)}/messages/${encode(messageId)}/crosspost`; }, stages: () => { - return '/stage-instances' + return '/stage-instances'; }, stage: (channelId) => { - return `/stage-instances/${encode(channelId)}` + return `/stage-instances/${encode(channelId)}`; }, // Thread Endpoints threads: { message: (channelId, messageId) => { - return `/channels/${encode(channelId)}/messages/${encode(messageId)}/threads` + return `/channels/${encode(channelId)}/messages/${encode(messageId)}/threads`; }, all: (channelId) => { - return `/channels/${encode(channelId)}/threads` + return `/channels/${encode(channelId)}/threads`; }, active: (guildId) => { - return `/guilds/${encode(guildId)}/threads/active` + return `/guilds/${encode(guildId)}/threads/active`; }, members: (channelId, options) => { - let url = `/channels/${encode(channelId)}/thread-members?` + let url = `/channels/${encode(channelId)}/thread-members?`; if (options) { - if (options.withMember) url += `with_member=${encode(options.withMember)}` - if (options.limit) url += `&limit=${encode(options.limit)}` - if (options.after) url += `&after=${encode(options.after)}` + if (options.withMember) url += `with_member=${encode(options.withMember)}`; + if (options.limit) url += `&limit=${encode(options.limit)}`; + if (options.after) url += `&after=${encode(options.after)}`; } - return url + return url; }, me: (channelId) => { - return `/channels/${encode(channelId)}/thread-members/@me` + return `/channels/${encode(channelId)}/thread-members/@me`; }, getUser(channelId, userId, options) { - let url = `/channels/${encode(channelId)}/thread-members/${encode(userId)}?` + let url = `/channels/${encode(channelId)}/thread-members/${encode(userId)}?`; if (options) { - if (options.withMember) url += `with_member=${encode(options.withMember)}` + if (options.withMember) url += `with_member=${encode(options.withMember)}`; } - return url + return url; }, user: (channelId, userId) => { - return `/channels/${encode(channelId)}/thread-members/${encode(userId)}` + return `/channels/${encode(channelId)}/thread-members/${encode(userId)}`; }, archived: (channelId) => { - return `/channels/${encode(channelId)}/threads/archived` + return `/channels/${encode(channelId)}/threads/archived`; }, public: (channelId, options) => { - let url = `/channels/${encode(channelId)}/threads/archived/public?` + let url = `/channels/${encode(channelId)}/threads/archived/public?`; if (options) { if (options.before) { - const iso = new Date(options.before).toISOString() - url += `before=${encode(iso)}` + const iso = new Date(options.before).toISOString(); + url += `before=${encode(iso)}`; } - if (options.limit) url += `&limit=${encode(options.limit)}` + if (options.limit) url += `&limit=${encode(options.limit)}`; } - return url + return url; }, private: (channelId, options) => { - let url = `/channels/${encode(channelId)}/threads/archived/private?` + let url = `/channels/${encode(channelId)}/threads/archived/private?`; if (options) { if (options.before) { - const iso = new Date(options.before).toISOString() - url += `before=${encode(iso)}` + const iso = new Date(options.before).toISOString(); + url += `before=${encode(iso)}`; } - if (options.limit) url += `&limit=${encode(options.limit)}` + if (options.limit) url += `&limit=${encode(options.limit)}`; } - return url + return url; }, joined: (channelId, options) => { - let url = `/channels/${encode(channelId)}/users/@me/threads/archived/private?` + let url = `/channels/${encode(channelId)}/users/@me/threads/archived/private?`; if (options) { if (options.before) { - const iso = new Date(options.before).toISOString() - url += `before=${encode(iso)}` + const iso = new Date(options.before).toISOString(); + url += `before=${encode(iso)}`; } - if (options.limit) url += `&limit=${encode(options.limit)}` + if (options.limit) url += `&limit=${encode(options.limit)}`; } - return url + return url; }, }, typing: (channelId) => { - return `/channels/${encode(channelId)}/typing` + return `/channels/${encode(channelId)}/typing`; }, polls: { votes: (channelId, messageId, answerId, options) => { - let url = `/channels/${encode(channelId)}/polls/${encode(messageId)}/answers/${encode(answerId)}?` + let url = `/channels/${encode(channelId)}/polls/${encode(messageId)}/answers/${encode(answerId)}?`; if (options) { - if (options.after) url += `after=${encode(options.after)}` - if (options.limit) url += `&limit=${encode(options.limit)}` + if (options.after) url += `after=${encode(options.after)}`; + if (options.limit) url += `&limit=${encode(options.limit)}`; } - return url + return url; }, expire: (channelId, messageId) => { - return `/channels/${encode(channelId)}/polls/${encode(messageId)}/expire` + return `/channels/${encode(channelId)}/polls/${encode(messageId)}/expire`; }, }, }, @@ -267,262 +267,262 @@ export function createRoutes(disableURIEncode: boolean = false): RestRoutes { // Guild Endpoints guilds: { all: () => { - return '/guilds' + return '/guilds'; }, userGuilds: (options) => { - let url = '/users/@me/guilds?' + let url = '/users/@me/guilds?'; if (options) { - if (options.after) url += `after=${encode(options.after)}` - if (options.before) url += `&before=${encode(options.before)}` - if (options.limit) url += `&limit=${encode(options.limit)}` - if (options.withCounts) url += `&with_counts=${encode(options.withCounts)}` + if (options.after) url += `after=${encode(options.after)}`; + if (options.before) url += `&before=${encode(options.before)}`; + if (options.limit) url += `&limit=${encode(options.limit)}`; + if (options.withCounts) url += `&with_counts=${encode(options.withCounts)}`; } - return url + return url; }, auditlogs: (guildId, options) => { - let url = `/guilds/${encode(guildId)}/audit-logs?` + let url = `/guilds/${encode(guildId)}/audit-logs?`; if (options) { - if (options.actionType) url += `action_type=${encode(options.actionType)}` - if (options.before) url += `&before=${encode(options.before)}` - if (options.after) url += `&after=${encode(options.after)}` - if (options.limit) url += `&limit=${encode(options.limit)}` - if (options.userId) url += `&user_id=${encode(options.userId)}` + if (options.actionType) url += `action_type=${encode(options.actionType)}`; + if (options.before) url += `&before=${encode(options.before)}`; + if (options.after) url += `&after=${encode(options.after)}`; + if (options.limit) url += `&limit=${encode(options.limit)}`; + if (options.userId) url += `&user_id=${encode(options.userId)}`; } - return url + return url; }, automod: { rule: (guildId, ruleId) => { - return `/guilds/${encode(guildId)}/auto-moderation/rules/${encode(ruleId)}` + return `/guilds/${encode(guildId)}/auto-moderation/rules/${encode(ruleId)}`; }, rules: (guildId) => { - return `/guilds/${encode(guildId)}/auto-moderation/rules` + return `/guilds/${encode(guildId)}/auto-moderation/rules`; }, }, channels: (guildId) => { - return `/guilds/${encode(guildId)}/channels` + return `/guilds/${encode(guildId)}/channels`; }, emoji: (guildId, emojiId) => { - return `/guilds/${encode(guildId)}/emojis/${encode(emojiId)}` + return `/guilds/${encode(guildId)}/emojis/${encode(emojiId)}`; }, emojis: (guildId) => { - return `/guilds/${encode(guildId)}/emojis` + return `/guilds/${encode(guildId)}/emojis`; }, events: { events: (guildId, withUserCount?: boolean) => { - let url = `/guilds/${encode(guildId)}/scheduled-events?` + let url = `/guilds/${encode(guildId)}/scheduled-events?`; if (withUserCount !== undefined) { - url += `with_user_count=${encode(withUserCount)}` + url += `with_user_count=${encode(withUserCount)}`; } - return url + return url; }, event: (guildId, eventId, withUserCount?: boolean) => { - let url = `/guilds/${encode(guildId)}/scheduled-events/${encode(eventId)}` + let url = `/guilds/${encode(guildId)}/scheduled-events/${encode(eventId)}`; if (withUserCount !== undefined) { - url += `with_user_count=${encode(withUserCount)}` + url += `with_user_count=${encode(withUserCount)}`; } - return url + return url; }, users: (guildId, eventId, options?: GetScheduledEventUsers) => { - let url = `/guilds/${encode(guildId)}/scheduled-events/${encode(eventId)}/users?` + let url = `/guilds/${encode(guildId)}/scheduled-events/${encode(eventId)}/users?`; if (options) { - if (options.limit !== undefined) url += `limit=${encode(options.limit)}` + if (options.limit !== undefined) url += `limit=${encode(options.limit)}`; if (options.withMember !== undefined) { - url += `&with_member=${encode(options.withMember)}` + url += `&with_member=${encode(options.withMember)}`; } - if (options.after !== undefined) url += `&after=${encode(options.after)}` - if (options.before !== undefined) url += `&before=${encode(options.before)}` + if (options.after !== undefined) url += `&after=${encode(options.after)}`; + if (options.before !== undefined) url += `&before=${encode(options.before)}`; } - return url + return url; }, }, guild(guildId, withCounts) { - let url = `/guilds/${encode(guildId)}?` + let url = `/guilds/${encode(guildId)}?`; if (withCounts !== undefined) { - url += `with_counts=${encode(withCounts)}` + url += `with_counts=${encode(withCounts)}`; } - return url + return url; }, integration(guildId, integrationId) { - return `/guilds/${encode(guildId)}/integrations/${encode(integrationId)}` + return `/guilds/${encode(guildId)}/integrations/${encode(integrationId)}`; }, integrations: (guildId) => { - return `/guilds/${encode(guildId)}/integrations?include_applications=true` + return `/guilds/${encode(guildId)}/integrations?include_applications=true`; }, invite(inviteCode, options) { - let url = `/invites/${encode(inviteCode)}?` + let url = `/invites/${encode(inviteCode)}?`; if (options) { if (options.withCounts !== undefined) { - url += `with_counts=${encode(options.withCounts)}` + url += `with_counts=${encode(options.withCounts)}`; } if (options.scheduledEventId) { - url += `&guild_scheduled_event_id=${encode(options.scheduledEventId)}` + url += `&guild_scheduled_event_id=${encode(options.scheduledEventId)}`; } } - return url + return url; }, invites: (guildId) => { - return `/guilds/${encode(guildId)}/invites` + return `/guilds/${encode(guildId)}/invites`; }, leave: (guildId) => { - return `/users/@me/guilds/${encode(guildId)}` + return `/users/@me/guilds/${encode(guildId)}`; }, members: { ban: (guildId, userId) => { - return `/guilds/${encode(guildId)}/bans/${encode(userId)}` + return `/guilds/${encode(guildId)}/bans/${encode(userId)}`; }, bans: (guildId, options) => { - let url = `/guilds/${encode(guildId)}/bans?` + let url = `/guilds/${encode(guildId)}/bans?`; if (options) { - if (options.limit) url += `limit=${encode(options.limit)}` - if (options.after) url += `&after=${encode(options.after)}` - if (options.before) url += `&before=${encode(options.before)}` + if (options.limit) url += `limit=${encode(options.limit)}`; + if (options.after) url += `&after=${encode(options.after)}`; + if (options.before) url += `&before=${encode(options.before)}`; } - return url + return url; }, bulkBan: (guildId) => { - return `/guilds/${encode(guildId)}/bulk-ban` + return `/guilds/${encode(guildId)}/bulk-ban`; }, bot: (guildId) => { - return `/guilds/${encode(guildId)}/members/@me` + return `/guilds/${encode(guildId)}/members/@me`; }, member: (guildId, userId) => { - return `/guilds/${encode(guildId)}/members/${encode(userId)}` + return `/guilds/${encode(guildId)}/members/${encode(userId)}`; }, currentMember: (guildId) => { - return `/users/@me/guilds/${encode(guildId)}/member` + return `/users/@me/guilds/${encode(guildId)}/member`; }, members: (guildId, options) => { - let url = `/guilds/${encode(guildId)}/members?` + let url = `/guilds/${encode(guildId)}/members?`; if (options !== undefined) { - if (options.limit) url += `limit=${encode(options.limit)}` - if (options.after) url += `&after=${encode(options.after)}` + if (options.limit) url += `limit=${encode(options.limit)}`; + if (options.after) url += `&after=${encode(options.after)}`; } - return url + return url; }, search: (guildId, query, options) => { - let url = `/guilds/${encode(guildId)}/members/search?query=${encode(query)}` + let url = `/guilds/${encode(guildId)}/members/search?query=${encode(query)}`; if (options) { - if (options.limit !== undefined) url += `&limit=${encode(options.limit)}` + if (options.limit !== undefined) url += `&limit=${encode(options.limit)}`; } - return url + return url; }, prune: (guildId, options) => { - let url = `/guilds/${encode(guildId)}/prune?` + let url = `/guilds/${encode(guildId)}/prune?`; if (options) { - if (options.days) url += `days=${encode(options.days)}` + if (options.days) url += `days=${encode(options.days)}`; if (Array.isArray(options.includeRoles)) { - url += `&include_roles=${encode(options.includeRoles.join(','))}` + url += `&include_roles=${encode(options.includeRoles.join(','))}`; } else if (options.includeRoles) { - url += `&include_roles=${encode(options.includeRoles)}` + url += `&include_roles=${encode(options.includeRoles)}`; } } - return url + return url; }, }, preview: (guildId) => { - return `/guilds/${encode(guildId)}/preview` + return `/guilds/${encode(guildId)}/preview`; }, prune: (guildId, options) => { - let url = `/guilds/${encode(guildId)}/prune?` + let url = `/guilds/${encode(guildId)}/prune?`; if (options) { - if (options.days) url += `days=${encode(options.days)}` + if (options.days) url += `days=${encode(options.days)}`; if (Array.isArray(options.includeRoles)) { - url += `&include_roles=${encode(options.includeRoles.join(','))}` + url += `&include_roles=${encode(options.includeRoles.join(','))}`; } else if (options.includeRoles) { - url += `&include_roles=${encode(options.includeRoles)}` + url += `&include_roles=${encode(options.includeRoles)}`; } } - return url + return url; }, roles: { one: (guildId, roleId) => { - return `/guilds/${encode(guildId)}/roles/${encode(roleId)}` + return `/guilds/${encode(guildId)}/roles/${encode(roleId)}`; }, all: (guildId) => { - return `/guilds/${encode(guildId)}/roles` + return `/guilds/${encode(guildId)}/roles`; }, member: (guildId, memberId, roleId) => { - return `/guilds/${encode(guildId)}/members/${encode(memberId)}/roles/${encode(roleId)}` + return `/guilds/${encode(guildId)}/members/${encode(memberId)}/roles/${encode(roleId)}`; }, memberCounts: (guildId) => { - return `/guilds/${guildId}/roles/member-counts` + return `/guilds/${guildId}/roles/member-counts`; }, }, stickers: (guildId) => { - return `/guilds/${encode(guildId)}/stickers` + return `/guilds/${encode(guildId)}/stickers`; }, sticker: (guildId, stickerId) => { - return `/guilds/${encode(guildId)}/stickers/${encode(stickerId)}` + return `/guilds/${encode(guildId)}/stickers/${encode(stickerId)}`; }, voice: (guildId, userId) => { - return `/guilds/${encode(guildId)}/voice-states/${encode(userId ?? '@me')}` + return `/guilds/${encode(guildId)}/voice-states/${encode(userId ?? '@me')}`; }, templates: { code: (code) => { - return `/guilds/templates/${encode(code)}` + return `/guilds/templates/${encode(code)}`; }, guild: (guildId, code) => { - return `/guilds/${encode(guildId)}/templates/${encode(code)}` + return `/guilds/${encode(guildId)}/templates/${encode(code)}`; }, all: (guildId) => { - return `/guilds/${encode(guildId)}/templates` + return `/guilds/${encode(guildId)}/templates`; }, }, vanity: (guildId) => { - return `/guilds/${encode(guildId)}/vanity-url` + return `/guilds/${encode(guildId)}/vanity-url`; }, regions: (guildId) => { - return `/guilds/${encode(guildId)}/regions` + return `/guilds/${encode(guildId)}/regions`; }, webhooks: (guildId) => { - return `/guilds/${encode(guildId)}/webhooks` + return `/guilds/${encode(guildId)}/webhooks`; }, welcome: (guildId) => { - return `/guilds/${encode(guildId)}/welcome-screen` + return `/guilds/${encode(guildId)}/welcome-screen`; }, widget: (guildId) => { - return `/guilds/${encode(guildId)}/widget` + return `/guilds/${encode(guildId)}/widget`; }, widgetJson: (guildId) => { - return `/guilds/${encode(guildId)}/widget.json` + return `/guilds/${encode(guildId)}/widget.json`; }, onboarding: (guildId) => { - return `/guilds/${encode(guildId)}/onboarding` + return `/guilds/${encode(guildId)}/onboarding`; }, incidentActions: (guildId) => { - return `/guilds/${encode(guildId)}/incident-actions` + return `/guilds/${encode(guildId)}/incident-actions`; }, }, sticker: (stickerId) => { - return `/stickers/${encode(stickerId)}` + return `/stickers/${encode(stickerId)}`; }, regions: () => { - return '/voice/regions' + return '/voice/regions'; }, // Interaction Endpoints @@ -530,57 +530,57 @@ export function createRoutes(disableURIEncode: boolean = false): RestRoutes { commands: { // Application Endpoints commands: (applicationId, withLocalizations) => { - let url = `/applications/${encode(applicationId)}/commands?` + let url = `/applications/${encode(applicationId)}/commands?`; if (withLocalizations !== undefined) { - url += `with_localizations=${encode(withLocalizations)}` + url += `with_localizations=${encode(withLocalizations)}`; } - return url + return url; }, guilds: { all(applicationId, guildId, withLocalizations) { - let url = `/applications/${encode(applicationId)}/guilds/${encode(guildId)}/commands?` + let url = `/applications/${encode(applicationId)}/guilds/${encode(guildId)}/commands?`; if (withLocalizations !== undefined) { - url += `with_localizations=${encode(withLocalizations)}` + url += `with_localizations=${encode(withLocalizations)}`; } - return url + return url; }, one(applicationId, guildId, commandId) { - return `/applications/${encode(applicationId)}/guilds/${encode(guildId)}/commands/${encode(commandId)}` + return `/applications/${encode(applicationId)}/guilds/${encode(guildId)}/commands/${encode(commandId)}`; }, }, permissions: (applicationId, guildId) => { - return `/applications/${encode(applicationId)}/guilds/${encode(guildId)}/commands/permissions` + return `/applications/${encode(applicationId)}/guilds/${encode(guildId)}/commands/permissions`; }, permission: (applicationId, guildId, commandId) => { - return `/applications/${encode(applicationId)}/guilds/${encode(guildId)}/commands/${encode(commandId)}/permissions` + return `/applications/${encode(applicationId)}/guilds/${encode(guildId)}/commands/${encode(commandId)}/permissions`; }, command: (applicationId, commandId, withLocalizations) => { - let url = `/applications/${encode(applicationId)}/commands/${encode(commandId)}?` + let url = `/applications/${encode(applicationId)}/commands/${encode(commandId)}?`; if (withLocalizations !== undefined) { - url += `withLocalizations=${encode(withLocalizations)}` + url += `withLocalizations=${encode(withLocalizations)}`; } - return url + return url; }, }, responses: { // Interaction Endpoints callback: (interactionId, token, options) => { - return `/interactions/${encode(interactionId)}/${encode(token)}/callback?with_response=${encode(!!options?.withResponse)}` + return `/interactions/${encode(interactionId)}/${encode(token)}/callback?with_response=${encode(!!options?.withResponse)}`; }, original: (interactionId, token) => { - return `/webhooks/${encode(interactionId)}/${encode(token)}/messages/@original` + return `/webhooks/${encode(interactionId)}/${encode(token)}/messages/@original`; }, message: (applicationId, token, messageId) => { - return `/webhooks/${encode(applicationId)}/${encode(token)}/messages/${encode(messageId)}` + return `/webhooks/${encode(applicationId)}/${encode(token)}/messages/${encode(messageId)}`; }, }, }, @@ -588,153 +588,153 @@ export function createRoutes(disableURIEncode: boolean = false): RestRoutes { // OAuth2 endpoints oauth2: { tokenExchange: () => { - return '/oauth2/token' + return '/oauth2/token'; }, tokenRevoke: () => { - return '/oauth2/token/revoke' + return '/oauth2/token/revoke'; }, currentAuthorization: () => { - return '/oauth2/@me' + return '/oauth2/@me'; }, application: () => { - return '/oauth2/applications/@me' + return '/oauth2/applications/@me'; }, connections: () => { - return '/users/@me/connections' + return '/users/@me/connections'; }, roleConnections: (applicationId) => { - return `/users/@me/applications/${encode(applicationId)}/role-connection` + return `/users/@me/applications/${encode(applicationId)}/role-connection`; }, }, monetization: { entitlements: (applicationId, options) => { - let url = `/applications/${encode(applicationId)}/entitlements?` + let url = `/applications/${encode(applicationId)}/entitlements?`; if (options) { - if (options.after) url += `after=${encode(options.after)}` - if (options.before) url += `&before=${encode(options.before)}` - if (options.excludeEnded) url += `&exclude_ended=${encode(options.excludeEnded)}` - if (options.guildId) url += `&guild_id=${encode(options.guildId)}` - if (options.limit) url += `&limit=${encode(options.limit)}` - if (options.skuIds) url += `&sku_ids=${encode(options.skuIds.join(','))}` - if (options.userId) url += `&user_id=${encode(options.userId)}` + if (options.after) url += `after=${encode(options.after)}`; + if (options.before) url += `&before=${encode(options.before)}`; + if (options.excludeEnded) url += `&exclude_ended=${encode(options.excludeEnded)}`; + if (options.guildId) url += `&guild_id=${encode(options.guildId)}`; + if (options.limit) url += `&limit=${encode(options.limit)}`; + if (options.skuIds) url += `&sku_ids=${encode(options.skuIds.join(','))}`; + if (options.userId) url += `&user_id=${encode(options.userId)}`; } - return url + return url; }, entitlement: (applicationId, entitlementId) => { - return `/applications/${encode(applicationId)}/entitlements/${encode(entitlementId)}` + return `/applications/${encode(applicationId)}/entitlements/${encode(entitlementId)}`; }, consumeEntitlement: (applicationId, entitlementId) => { - return `/applications/${encode(applicationId)}/entitlements/${encode(entitlementId)}/consume` + return `/applications/${encode(applicationId)}/entitlements/${encode(entitlementId)}/consume`; }, skus: (applicationId) => { - return `/applications/${encode(applicationId)}/skus` + return `/applications/${encode(applicationId)}/skus`; }, subscription: (skuId, subscriptionId) => { - return `/skus/${encode(skuId)}/subscriptions/${encode(subscriptionId)}` + return `/skus/${encode(skuId)}/subscriptions/${encode(subscriptionId)}`; }, subscriptions: (skuId, options) => { - let url = `/skus/${encode(skuId)}/subscriptions?` + let url = `/skus/${encode(skuId)}/subscriptions?`; if (options) { - if (options.after) url += `after=${encode(options.after)}` - if (options.before) url += `&before=${encode(options.before)}` - if (options.userId) url += `&user_id=${encode(options.userId)}` - if (options.limit) url += `&limit=${encode(options.limit)}` + if (options.after) url += `after=${encode(options.after)}`; + if (options.before) url += `&before=${encode(options.before)}`; + if (options.userId) url += `&user_id=${encode(options.userId)}`; + if (options.limit) url += `&limit=${encode(options.limit)}`; } - return url + return url; }, }, soundboard: { sendSound: (channelId) => { - return `/channels/${encode(channelId)}` + return `/channels/${encode(channelId)}`; }, listDefault: () => { - return `/soundboard-default-sounds` + return `/soundboard-default-sounds`; }, guildSounds: (guildId) => { - return `/guilds/${encode(guildId)}/soundboard-sounds` + return `/guilds/${encode(guildId)}/soundboard-sounds`; }, guildSound: (guildId, soundId) => { - return `/guilds/${encode(guildId)}/soundboard-sounds/${encode(soundId)}` + return `/guilds/${encode(guildId)}/soundboard-sounds/${encode(soundId)}`; }, }, lobby: { create: () => { - return '/lobbies' + return '/lobbies'; }, lobby: (lobbyId) => { - return `/lobbies/${encode(lobbyId)}` + return `/lobbies/${encode(lobbyId)}`; }, member: (lobbyId, userId) => { - return `/lobbies/${encode(lobbyId)}/members/${encode(userId)}` + return `/lobbies/${encode(lobbyId)}/members/${encode(userId)}`; }, leave: (lobbyId) => { - return `/lobbies/${encode(lobbyId)}/members/@me` + return `/lobbies/${encode(lobbyId)}/members/@me`; }, link: (lobbyId) => { - return `/lobbies/${encode(lobbyId)}/channel-linking` + return `/lobbies/${encode(lobbyId)}/channel-linking`; }, }, applicationEmoji(applicationId, emojiId) { - return `/applications/${encode(applicationId)}/emojis/${encode(emojiId)}` + return `/applications/${encode(applicationId)}/emojis/${encode(emojiId)}`; }, applicationEmojis(applicationId) { - return `/applications/${encode(applicationId)}/emojis` + return `/applications/${encode(applicationId)}/emojis`; }, applicationRoleConnectionMetadata(applicationId) { - return `/applications/${encode(applicationId)}/role-connections/metadata` + return `/applications/${encode(applicationId)}/role-connections/metadata`; }, // User endpoints user(userId) { - return `/users/${encode(userId)}` + return `/users/${encode(userId)}`; }, application() { - return '/applications/@me' + return '/applications/@me'; }, applicationActivityInstance(applicationId, instanceId) { - return `/applications/${encode(applicationId)}/activity-instances/${encode(instanceId)}` + return `/applications/${encode(applicationId)}/activity-instances/${encode(instanceId)}`; }, currentUser() { - return '/users/@me' + return '/users/@me'; }, gatewayBot() { - return '/gateway/bot' + return '/gateway/bot'; }, stickerPack(stickerPackId) { - return `/sticker-packs/${encode(stickerPackId)}` + return `/sticker-packs/${encode(stickerPackId)}`; }, stickerPacks() { - return '/sticker-packs' + return '/sticker-packs'; }, - } + }; } function encodeComponent(uriComponent: string | number | bigint | boolean): string { - if (typeof uriComponent !== 'string') return uriComponent.toString() - if (/^\d+$/.test(uriComponent)) return uriComponent + if (typeof uriComponent !== 'string') return uriComponent.toString(); + if (/^\d+$/.test(uriComponent)) return uriComponent; - return encodeURIComponent(uriComponent) + return encodeURIComponent(uriComponent); } diff --git a/packages/rest/src/types.ts b/packages/rest/src/types.ts index ac00d0946..f48952486 100644 --- a/packages/rest/src/types.ts +++ b/packages/rest/src/types.ts @@ -150,20 +150,20 @@ import type { StartThreadWithoutMessage, UpsertGlobalApplicationCommandOptions, UpsertGuildApplicationCommandOptions, -} from '@discordeno/types' -import type { logger } from '@discordeno/utils' -import type { InvalidRequestBucket } from './invalidBucket.js' -import type { Queue } from './queue.js' -import type { RestRoutes } from './typings/routes.js' +} from '@discordeno/types'; +import type { logger } from '@discordeno/utils'; +import type { InvalidRequestBucket } from './invalidBucket.js'; +import type { Queue } from './queue.js'; +import type { RestRoutes } from './typings/routes.js'; export interface CreateRestManagerOptions { /** The bot token which will be used to make requests. */ - token: string + token: string; /** * For old bots that have a different bot id and application id. * @default bot id from token */ - applicationId?: BigString + applicationId?: BigString; /** Configuration when using a proxy. */ proxy?: { /** @@ -171,9 +171,9 @@ export interface CreateRestManagerOptions { * IT SHOULD NOT END WITH A / * @default https://discord.com/api */ - baseUrl: string + baseUrl: string; /** The authorization header value to attach when sending requests to the proxy. */ - authorization?: string + authorization?: string; /** * The authorization header name to use when sending requests to the proxy * @@ -183,7 +183,7 @@ export interface CreateRestManagerOptions { * * @default "authorization" // For compatibility purposes */ - authorizationHeader?: string + authorizationHeader?: string; /** * The endpoint to use in the rest proxy to update the bearer tokens * @@ -192,101 +192,101 @@ export interface CreateRestManagerOptions { * * This value is actually required if you want to use `updateTokenQueues` */ - updateBearerTokenEndpoint?: string - } + updateBearerTokenEndpoint?: string; + }; /** * The api versions which can be used to make requests. * @default 10 */ - version?: ApiVersions + version?: ApiVersions; /** * The logger that the rest manager will use * @default logger // The logger exported by `@discordeno/utils` */ - logger?: Pick + logger?: Pick; /** Events for the rest manager */ - events?: Partial + events?: Partial; } export interface RestManager { /** The bot token which will be used to make requests. */ - token: string + token: string; /** The application id. Normally this is not required for recent bots but old bot's application id is sometimes different from the bot id so it is required for those bots. */ - applicationId: bigint + applicationId: bigint; /** The api version to use when making requests. Only the latest supported version will be tested. */ - version: ApiVersions + version: ApiVersions; /** * The base url to connect to. If you create a proxy rest, that url would go here. * IT SHOULD NOT END WITH A / * @default https://discord.com/api */ - baseUrl: string + baseUrl: string; /** * `true` if the `baseUrl` does not start with `https://discord.com/api`. * * Mostly used only for intern functions. */ - isProxied: boolean + isProxied: boolean; /** The authorization header value to attach when sending requests to the proxy. */ - authorization?: string + authorization?: string; /** The authorization header name to attach when sending requests to the proxy */ - authorizationHeader: string + authorizationHeader: string; /** The endpoint to use for `updateTokenQueues` when working with a rest proxy */ - updateBearerTokenEndpoint?: string + updateBearerTokenEndpoint?: string; /** The maximum amount of times a request should be retried. Defaults to Infinity */ - maxRetryCount: number + maxRetryCount: number; /** Whether or not the manager is rate limited globally across all requests. Defaults to false. */ - globallyRateLimited: boolean + globallyRateLimited: boolean; /** Whether or not the rate limited paths are being processed to allow requests to be made once time is up. Defaults to false. */ - processingRateLimitedPaths: boolean + processingRateLimitedPaths: boolean; /** The time in milliseconds to wait before deleting this queue if it is empty. Defaults to 60000(one minute). */ - deleteQueueDelay: number + deleteQueueDelay: number; /** The queues that hold all the requests to be processed. */ - queues: Map + queues: Map; /** The paths that are currently rate limited. */ - rateLimitedPaths: Map + rateLimitedPaths: Map; /** The bucket for handling any invalid requests. */ - invalidBucket: InvalidRequestBucket + invalidBucket: InvalidRequestBucket; /** The routes that are available for this manager. */ - routes: RestRoutes + routes: RestRoutes; /** The logger to use for the rest manager */ - logger: Pick + logger: Pick; /** Events for the rest manager */ - events: RestManagerEvents + events: RestManagerEvents; /** Allows the user to inject custom headers that will be sent with every request. */ - createBaseHeaders: () => Record + createBaseHeaders: () => Record; /** Whether or not the rest manager should keep objects in raw snake case from discord. */ - preferSnakeCase: (enabled: boolean) => RestManager + preferSnakeCase: (enabled: boolean) => RestManager; /** Check the rate limits for a url or a bucket. */ - checkRateLimits: (url: string, identifier: string) => number | false + checkRateLimits: (url: string, identifier: string) => number | false; /* Update the queues and ratelimit information to adapt to the new token */ - updateTokenQueues: (oldToken: string, newToken: string) => Promise + updateTokenQueues: (oldToken: string, newToken: string) => Promise; /** Reshapes and modifies the obj as needed to make it ready for discords api. */ - changeToDiscordFormat: (obj: any) => any + changeToDiscordFormat: (obj: any) => any; /** Creates the request body and headers that are necessary to send a request. Will handle different types of methods and everything necessary for discord. */ - createRequestBody: (method: RequestMethods, options?: CreateRequestBodyOptions) => RequestBody + createRequestBody: (method: RequestMethods, options?: CreateRequestBodyOptions) => RequestBody; /** This will create a infinite loop running in 1 seconds using tail recursion to keep rate limits clean. When a rate limit resets, this will remove it so the queue can proceed. */ - processRateLimitedPaths: () => void + processRateLimitedPaths: () => void; /** Processes the rate limit headers and determines if it needs to be rate limited and returns the bucket id if available */ - processHeaders: (url: string, headers: Headers, identifier: string) => string | undefined + processHeaders: (url: string, headers: Headers, identifier: string) => string | undefined; /** Sends a request to the api. */ - sendRequest: (options: SendRequestOptions) => Promise + sendRequest: (options: SendRequestOptions) => Promise; /** Split a url to separate rate limit buckets based on major/minor parameters. */ - simplifyUrl: (url: string, method: RequestMethods) => string + simplifyUrl: (url: string, method: RequestMethods) => string; /** Make a request to be sent to the api. */ - makeRequest: (method: RequestMethods, url: string, options?: MakeRequestOptions) => Promise + makeRequest: (method: RequestMethods, url: string, options?: MakeRequestOptions) => Promise; /** Takes a request and processes it into a queue. */ - processRequest: (request: SendRequestOptions) => Promise + processRequest: (request: SendRequestOptions) => Promise; /** Make a get request to the api */ - get: (url: string, options?: Omit) => Promise> + get: (url: string, options?: Omit) => Promise>; /** Make a post request to the api. */ - post: (url: string, options?: MakeRequestOptions) => Promise> + post: (url: string, options?: MakeRequestOptions) => Promise>; /** Make a put request to the api. */ - put: (url: string, options?: MakeRequestOptions) => Promise> + put: (url: string, options?: MakeRequestOptions) => Promise>; /** Make a delete request to the api. */ - delete: (url: string, options?: Omit) => Promise + delete: (url: string, options?: Omit) => Promise; /** Make a patch request to the api. */ - patch: (url: string, options?: MakeRequestOptions) => Promise> + patch: (url: string, options?: MakeRequestOptions) => Promise>; /** * Adds a reaction to a message. * @@ -305,7 +305,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/channel#create-reaction} */ - addReaction: (channelId: BigString, messageId: BigString, reaction: string) => Promise + addReaction: (channelId: BigString, messageId: BigString, reaction: string) => Promise; /** * Adds multiple a reaction to a message. * @@ -324,7 +324,7 @@ export interface RestManager { * * Fires a _Message Reaction Add_ gateway event for every reaction added. */ - addReactions: (channelId: BigString, messageId: BigString, reactions: string[], ordered?: boolean) => Promise + addReactions: (channelId: BigString, messageId: BigString, reactions: string[], ordered?: boolean) => Promise; /** * Adds a role to a member. * @@ -340,7 +340,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/guild#add-guild-member-role} */ - addRole: (guildId: BigString, userId: BigString, roleId: BigString, reason?: string) => Promise + addRole: (guildId: BigString, userId: BigString, roleId: BigString, reason?: string) => Promise; /** * Adds a member to a thread. * @@ -355,7 +355,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/channel#add-thread-member} */ - addThreadMember: (channelId: BigString, userId: BigString) => Promise + addThreadMember: (channelId: BigString, userId: BigString) => Promise; /** * Adds a recipient to a group DM. * @@ -368,7 +368,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/channel#group-dm-add-recipient} */ - addDmRecipient: (channelId: BigString, userId: BigString, options: AddDmRecipientOptions) => Promise + addDmRecipient: (channelId: BigString, userId: BigString, options: AddDmRecipientOptions) => Promise; /** * Adds a member to a guild. * @@ -384,7 +384,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/guild#add-guild-member} */ - addGuildMember: (guildId: BigString, userId: BigString, options: AddGuildMemberOptions) => Promise + addGuildMember: (guildId: BigString, userId: BigString, options: AddGuildMemberOptions) => Promise; /** * Creates an automod rule in a guild. * @@ -400,7 +400,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/auto-moderation#create-auto-moderation-rule} */ - createAutomodRule: (guildId: BigString, options: CreateAutoModerationRuleOptions, reason?: string) => Promise> + createAutomodRule: (guildId: BigString, options: CreateAutoModerationRuleOptions, reason?: string) => Promise>; /** * Creates a channel within a guild. * @@ -420,7 +420,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/guild#create-guild-channel} */ - createChannel: (guildId: BigString, options: CreateGuildChannel, reason?: string) => Promise> + createChannel: (guildId: BigString, options: CreateGuildChannel, reason?: string) => Promise>; /** * Creates an emoji in a guild. * @@ -438,7 +438,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/emoji#create-guild-emoji} */ - createEmoji: (guildId: BigString, options: CreateGuildEmoji, reason?: string) => Promise> + createEmoji: (guildId: BigString, options: CreateGuildEmoji, reason?: string) => Promise>; /** * Creates an emoji for the application. * @@ -447,7 +447,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/emoji#create-application-emoji} */ - createApplicationEmoji: (options: CreateApplicationEmoji) => Promise> + createApplicationEmoji: (options: CreateApplicationEmoji) => Promise>; /** * Creates a new thread in a forum channel or media channel, and sends a message within the created thread. * @@ -464,7 +464,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/channel#start-thread-in-forum-or-media-channel} */ - createForumThread: (channelId: BigString, options: CreateForumPostWithMessage, reason?: string) => Promise> + createForumThread: (channelId: BigString, options: CreateForumPostWithMessage, reason?: string) => Promise>; /** * Creates an application command accessible globally; across different guilds and channels. * @@ -485,7 +485,7 @@ export interface RestManager { createGlobalApplicationCommand: ( command: CreateApplicationCommand, options?: CreateGlobalApplicationCommandOptions, - ) => Promise> + ) => Promise>; /** * Creates an application command only accessible in a specific guild. * @@ -507,7 +507,7 @@ export interface RestManager { command: CreateApplicationCommand, guildId: BigString, options?: CreateGuildApplicationCommandOptions, - ) => Promise> + ) => Promise>; /** * Create a new sticker for the guild. * @@ -523,7 +523,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/sticker#create-guild-sticker} */ - createGuildSticker: (guildId: BigString, options: CreateGuildStickerOptions, reason?: string) => Promise> + createGuildSticker: (guildId: BigString, options: CreateGuildStickerOptions, reason?: string) => Promise>; /** * Creates a template from a guild. * @@ -538,7 +538,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/guild-template#create-guild-template} */ - createGuildTemplate: (guildId: BigString, options: CreateTemplate) => Promise> + createGuildTemplate: (guildId: BigString, options: CreateTemplate) => Promise>; /** * Creates an invite to a channel in a guild. * @@ -557,7 +557,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/channel#create-channel-invite} */ - createInvite: (channelId: BigString, options?: CreateChannelInvite, reason?: string) => Promise> + createInvite: (channelId: BigString, options?: CreateChannelInvite, reason?: string) => Promise>; /** * Get guild role member counts * @@ -567,7 +567,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/guild#get-guild-role-member-counts} */ - getGuildRoleMemberCounts: (guildId: BigString) => Promise> + getGuildRoleMemberCounts: (guildId: BigString) => Promise>; /** * Creates a role in a guild. * @@ -583,7 +583,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/guild#create-guild-role} */ - createRole: (guildId: BigString, options: CreateGuildRole, reason?: string) => Promise> + createRole: (guildId: BigString, options: CreateGuildRole, reason?: string) => Promise>; /** * Creates a scheduled event in a guild. * @@ -601,7 +601,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/guild-scheduled-event#create-guild-scheduled-event} */ - createScheduledEvent: (guildId: BigString, options: CreateScheduledEvent, reason?: string) => Promise> + createScheduledEvent: (guildId: BigString, options: CreateScheduledEvent, reason?: string) => Promise>; /** * Creates a stage instance associated with a stage channel. * @@ -616,7 +616,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/stage-instance#create-stage-instance} */ - createStageInstance: (options: CreateStageInstance, reason?: string) => Promise> + createStageInstance: (options: CreateStageInstance, reason?: string) => Promise>; /** * Creates a webhook. * @@ -634,7 +634,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/webhook#create-webhook} */ - createWebhook: (channelId: BigString, options: CreateWebhook, reason?: string) => Promise> + createWebhook: (channelId: BigString, options: CreateWebhook, reason?: string) => Promise>; /** * Deletes an automod rule. * @@ -649,7 +649,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/auto-moderation#delete-auto-moderation-rule} */ - deleteAutomodRule: (guildId: BigString, ruleId: BigString, reason?: string) => Promise + deleteAutomodRule: (guildId: BigString, ruleId: BigString, reason?: string) => Promise; /** * Deletes a channel from within a guild. * @@ -675,7 +675,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/channel#deleteclose-channel} */ - deleteChannel: (channelId: BigString, reason?: string) => Promise + deleteChannel: (channelId: BigString, reason?: string) => Promise; /** * Deletes a permission override for a user or role in a channel. * @@ -690,7 +690,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/channel#delete-channel-permission} */ - deleteChannelPermissionOverride: (channelId: BigString, overwriteId: BigString, reason?: string) => Promise + deleteChannelPermissionOverride: (channelId: BigString, overwriteId: BigString, reason?: string) => Promise; /** * Deletes an emoji from a guild. * @@ -706,7 +706,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/emoji#delete-guild-emoji} */ - deleteEmoji: (guildId: BigString, id: BigString, reason?: string) => Promise + deleteEmoji: (guildId: BigString, id: BigString, reason?: string) => Promise; /** * Deletes an emoji from the application. * @@ -714,7 +714,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/emoji#delete-application-emoji} */ - deleteApplicationEmoji: (id: BigString) => Promise + deleteApplicationEmoji: (id: BigString) => Promise; /** * Deletes a follow-up message to an interaction. * @@ -728,7 +728,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/interactions/receiving-and-responding#delete-followup-message} */ - deleteFollowupMessage: (token: string, messageId: BigString) => Promise + deleteFollowupMessage: (token: string, messageId: BigString) => Promise; /** * Deletes an application command registered globally. * @@ -736,7 +736,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/interactions/application-commands#delete-global-application-command} */ - deleteGlobalApplicationCommand: (commandId: BigString) => Promise + deleteGlobalApplicationCommand: (commandId: BigString) => Promise; /** * Deletes an application command registered in a guild. * @@ -745,7 +745,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/interactions/application-commands#delete-guild-application-command} */ - deleteGuildApplicationCommand: (commandId: BigString, guildId: BigString) => Promise + deleteGuildApplicationCommand: (commandId: BigString, guildId: BigString) => Promise; /** * Delete a new sticker for the guild. * @@ -762,7 +762,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/sticker#delete-guild-sticker} */ - deleteGuildSticker: (guildId: BigString, stickerId: BigString, reason?: string) => Promise + deleteGuildSticker: (guildId: BigString, stickerId: BigString, reason?: string) => Promise; /** * Deletes a template from a guild. * @@ -776,7 +776,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/guild-template#delete-guild-template} */ - deleteGuildTemplate: (guildId: BigString, templateCode: string) => Promise + deleteGuildTemplate: (guildId: BigString, templateCode: string) => Promise; /** * Deletes an integration attached to a guild. * @@ -794,7 +794,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/guild#delete-guild-integration} */ - deleteIntegration: (guildId: BigString, integrationId: BigString, reason?: string) => Promise + deleteIntegration: (guildId: BigString, integrationId: BigString, reason?: string) => Promise; /** * Deletes an invite to a channel. * @@ -808,7 +808,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/channel#delete-channel-invite} */ - deleteInvite: (inviteCode: string, reason?: string) => Promise + deleteInvite: (inviteCode: string, reason?: string) => Promise; /** * Deletes a message from a channel. * @@ -824,7 +824,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/channel#delete-message} */ - deleteMessage: (channelId: BigString, messageId: BigString, reason?: string) => Promise + deleteMessage: (channelId: BigString, messageId: BigString, reason?: string) => Promise; /** * Deletes multiple messages from a channel. * @@ -841,7 +841,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/channel#bulk-delete-messages} */ - deleteMessages: (channelId: BigString, messageIds: BigString[], reason?: string) => Promise + deleteMessages: (channelId: BigString, messageIds: BigString[], reason?: string) => Promise; /** * Deletes the initial message response to an interaction. * @@ -854,7 +854,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/interactions/receiving-and-responding#delete-original-interaction-response} */ - deleteOriginalInteractionResponse: (token: string) => Promise + deleteOriginalInteractionResponse: (token: string) => Promise; /** * Deletes a reaction added by the bot user from a message. * @@ -869,7 +869,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/channel#delete-own-reaction} */ - deleteOwnReaction: (channelId: BigString, messageId: BigString, reaction: string) => Promise + deleteOwnReaction: (channelId: BigString, messageId: BigString, reaction: string) => Promise; /** * Deletes all reactions for all emojis from a message. * @@ -885,7 +885,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/channel#delete-all-reactions} */ - deleteReactionsAll: (channelId: BigString, messageId: BigString) => Promise + deleteReactionsAll: (channelId: BigString, messageId: BigString) => Promise; /** * Deletes all reactions for an emoji from a message. * @@ -902,7 +902,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/channel#delete-all-reactions-for-emoji} */ - deleteReactionsEmoji: (channelId: BigString, messageId: BigString, reaction: string) => Promise + deleteReactionsEmoji: (channelId: BigString, messageId: BigString, reaction: string) => Promise; /** * Deletes a role from a guild. * @@ -917,7 +917,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/guild#delete-guild-role} */ - deleteRole: (guildId: BigString, roleId: BigString, reason?: string) => Promise + deleteRole: (guildId: BigString, roleId: BigString, reason?: string) => Promise; /** * Deletes a scheduled event from a guild. * @@ -931,7 +931,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/guild-scheduled-event#delete-guild-scheduled-event} */ - deleteScheduledEvent: (guildId: BigString, eventId: BigString) => Promise + deleteScheduledEvent: (guildId: BigString, eventId: BigString) => Promise; /** * Deletes the stage instance associated with a stage channel, if one exists. * @@ -945,7 +945,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/stage-instance#delete-stage-instance} */ - deleteStageInstance: (channelId: BigString, reason?: string) => Promise + deleteStageInstance: (channelId: BigString, reason?: string) => Promise; /** * Deletes a user's reaction from a message. * @@ -963,7 +963,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/channel#delete-user-reaction} */ - deleteUserReaction: (channelId: BigString, messageId: BigString, userId: BigString, reaction: string) => Promise + deleteUserReaction: (channelId: BigString, messageId: BigString, userId: BigString, reaction: string) => Promise; /** * Deletes a webhook. * @@ -976,7 +976,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/webhook#delete-webhook} */ - deleteWebhook: (webhookId: BigString, reason?: string) => Promise + deleteWebhook: (webhookId: BigString, reason?: string) => Promise; /** * Deletes a webhook message. * @@ -990,7 +990,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/webhook#delete-webhook} */ - deleteWebhookMessage: (webhookId: BigString, token: string, messageId: BigString, options?: DeleteWebhookMessageOptions) => Promise + deleteWebhookMessage: (webhookId: BigString, token: string, messageId: BigString, options?: DeleteWebhookMessageOptions) => Promise; /** * Deletes a webhook message using the webhook token, thereby bypassing the need for authentication + permissions. * @@ -1002,7 +1002,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/webhook#delete-webhook-with-token} */ - deleteWebhookWithToken: (webhookId: BigString, token: string) => Promise + deleteWebhookWithToken: (webhookId: BigString, token: string) => Promise; /** * Edits the permissions for a guild application command. * @@ -1022,7 +1022,7 @@ export interface RestManager { commandId: BigString, bearerToken: string, options: Camelize[], - ) => Promise> + ) => Promise>; /** * Edits an automod rule. * @@ -1044,12 +1044,12 @@ export interface RestManager { ruleId: BigString, options: Partial, reason?: string, - ) => Promise> + ) => Promise>; /** * Modifies the bot's username, avatar or banner. * NOTE: username: if changed may cause the bot's discriminator to be randomized. */ - editBotProfile: (options: { username?: string; botAvatarURL?: string | null; botBannerURL?: string | null }) => Promise> + editBotProfile: (options: { username?: string; botAvatarURL?: string | null; botBannerURL?: string | null }) => Promise>; /** * Edits a channel's settings. * @@ -1080,7 +1080,7 @@ export interface RestManager { * - Otherwise: * - Fires a _Channel Update_ gateway event. */ - editChannel: (channelId: BigString, options: ModifyChannel, reason?: string) => Promise> + editChannel: (channelId: BigString, options: ModifyChannel, reason?: string) => Promise>; /** * Edits the permission overrides for a user or role in a channel. * @@ -1097,7 +1097,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/channel#edit-channel-permissions} */ - editChannelPermissionOverrides: (channelId: BigString, options: EditChannelPermissionOverridesOptions, reason?: string) => Promise + editChannelPermissionOverrides: (channelId: BigString, options: EditChannelPermissionOverridesOptions, reason?: string) => Promise; /** * Edits the positions of a set of channels in a guild. * @@ -1111,7 +1111,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/guild#modify-guild-channel-positions} */ - editChannelPositions: (guildId: BigString, channelPositions: ModifyGuildChannelPositions[]) => Promise + editChannelPositions: (guildId: BigString, channelPositions: ModifyGuildChannelPositions[]) => Promise; /** * Edits an emoji. * @@ -1129,7 +1129,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/emoji#modify-guild-emoji} */ - editEmoji: (guildId: BigString, id: BigString, options: ModifyGuildEmoji, reason?: string) => Promise> + editEmoji: (guildId: BigString, id: BigString, options: ModifyGuildEmoji, reason?: string) => Promise>; /** * Edits an application emoji. * @@ -1139,7 +1139,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/emoji#modify-application-emoji} */ - editApplicationEmoji: (id: BigString, options: ModifyApplicationEmoji) => Promise> + editApplicationEmoji: (id: BigString, options: ModifyApplicationEmoji) => Promise>; /** * Edits a follow-up message to an interaction. * @@ -1157,7 +1157,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/interactions/receiving-and-responding#edit-followup-message} */ - editFollowupMessage: (token: string, messageId: BigString, options: InteractionCallbackData) => Promise> + editFollowupMessage: (token: string, messageId: BigString, options: InteractionCallbackData) => Promise>; /** * Edits a global application command. * @@ -1167,7 +1167,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/interactions/application-commands#edit-global-application-command} */ - editGlobalApplicationCommand: (commandId: BigString, options: CreateApplicationCommand) => Promise> + editGlobalApplicationCommand: (commandId: BigString, options: CreateApplicationCommand) => Promise>; /** * Edits a guild's settings. * @@ -1186,7 +1186,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/guild#modify-guild} */ - editGuild: (guildId: BigString, options: ModifyGuild, reason?: string) => Promise> + editGuild: (guildId: BigString, options: ModifyGuild, reason?: string) => Promise>; /** * Edits an application command registered in a guild. * @@ -1201,7 +1201,7 @@ export interface RestManager { commandId: BigString, guildId: BigString, options: CreateApplicationCommand, - ) => Promise> + ) => Promise>; /** * Edit the given sticker. * @@ -1221,7 +1221,7 @@ export interface RestManager { stickerId: BigString, options: AtLeastOne, reason?: string, - ) => Promise> + ) => Promise>; /** * Edits a template's settings. * @@ -1237,7 +1237,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/guild-template#modify-guild-template} */ - editGuildTemplate: (guildId: BigString, templateCode: string, options: ModifyGuildTemplate) => Promise> + editGuildTemplate: (guildId: BigString, templateCode: string, options: ModifyGuildTemplate) => Promise>; /** * Edits a message. * @@ -1255,7 +1255,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/channel#edit-message} */ - editMessage: (channelId: BigString, messageId: BigString, options: EditMessage) => Promise> + editMessage: (channelId: BigString, messageId: BigString, options: EditMessage) => Promise>; /** * Edits the initial message response to an interaction. * @@ -1272,7 +1272,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/interactions/receiving-and-responding#edit-original-interaction-response} */ - editOriginalInteractionResponse: (token: string, options: InteractionCallbackData) => Promise> + editOriginalInteractionResponse: (token: string, options: InteractionCallbackData) => Promise>; /** * Edits the voice state of the bot user. * @@ -1290,7 +1290,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/voice#modify-current-user-voice-state} */ - editOwnVoiceState: (guildId: BigString, options: EditOwnVoiceState) => Promise + editOwnVoiceState: (guildId: BigString, options: EditOwnVoiceState) => Promise; /** * Edits a role in a guild. * @@ -1307,7 +1307,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/guild#modify-guild-role} */ - editRole: (guildId: BigString, roleId: BigString, options: EditGuildRole, reason?: string) => Promise> + editRole: (guildId: BigString, roleId: BigString, options: EditGuildRole, reason?: string) => Promise>; /** * Edits the positions of a set of roles. * @@ -1323,7 +1323,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/guild#modify-guild-role-positions} */ - editRolePositions: (guildId: BigString, options: ModifyRolePositions[], reason?: string) => Promise[]> + editRolePositions: (guildId: BigString, options: ModifyRolePositions[], reason?: string) => Promise[]>; /** * Edits a scheduled event. * @@ -1348,7 +1348,7 @@ export interface RestManager { eventId: BigString, options: Partial, reason?: string, - ) => Promise> + ) => Promise>; /** * Edits a stage instance. * @@ -1364,7 +1364,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/stage-instance#modify-stage-instance} */ - editStageInstance: (channelId: BigString, topic: string, reason?: string) => Promise> + editStageInstance: (channelId: BigString, topic: string, reason?: string) => Promise>; /** * Edits the voice state of another user. * @@ -1378,7 +1378,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/voice#modify-user-voice-state} */ - editUserVoiceState: (guildId: BigString, options: EditUserVoiceState) => Promise + editUserVoiceState: (guildId: BigString, options: EditUserVoiceState) => Promise; /** * Edit the current user application role connection for the application. * @@ -1396,7 +1396,7 @@ export interface RestManager { bearerToken: string, applicationId: BigString, options: Camelize, - ) => Promise> + ) => Promise>; /** * Edits a webhook. * @@ -1411,7 +1411,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/webhook#edit-webhook} */ - editWebhook: (webhookId: BigString, options: ModifyWebhook, reason?: string) => Promise> + editWebhook: (webhookId: BigString, options: ModifyWebhook, reason?: string) => Promise>; /** * Edits a webhook message. * @@ -1431,7 +1431,7 @@ export interface RestManager { token: string, messageId: BigString, options: EditWebhookMessageOptions, - ) => Promise> + ) => Promise>; /** * Edits a webhook using the webhook token, thereby bypassing the need for authentication + permissions. * @@ -1446,7 +1446,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/webhook#modify-webhook-with-token} */ - editWebhookWithToken: (webhookId: BigString, token: string, options: Omit) => Promise> + editWebhookWithToken: (webhookId: BigString, token: string, options: Omit) => Promise>; /** * Edits a guild's welcome screen. * @@ -1462,7 +1462,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/guild#modify-guild-welcome-screen} */ - editWelcomeScreen: (guildId: BigString, options: ModifyGuildWelcomeScreen, reason?: string) => Promise> + editWelcomeScreen: (guildId: BigString, options: ModifyGuildWelcomeScreen, reason?: string) => Promise>; /** * Edits the settings of a guild's widget. * @@ -1481,7 +1481,7 @@ export interface RestManager { guildId: BigString, options: Camelize, reason?: string, - ) => Promise> + ) => Promise>; /** * Executes a webhook, causing a message to be posted in the channel configured for the webhook. * @@ -1495,7 +1495,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/webhook#execute-webhook} */ - executeWebhook: (webhookId: BigString, token: string, options: ExecuteWebhook) => Promise | undefined> + executeWebhook: (webhookId: BigString, token: string, options: ExecuteWebhook) => Promise | undefined>; /** * Follows an announcement channel, allowing messages posted within it to be cross-posted into the target channel. * @@ -1511,7 +1511,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/channel#follow-announcement-channel} */ - followAnnouncement: (sourceChannelId: BigString, targetChannelId: BigString, reason?: string) => Promise> + followAnnouncement: (sourceChannelId: BigString, targetChannelId: BigString, reason?: string) => Promise>; /** * Gets the list of all active threads for a guild. * @@ -1525,16 +1525,16 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/guild#list-active-guild-threads} */ - getActiveThreads: (guildId: BigString) => Promise> + getActiveThreads: (guildId: BigString) => Promise>; /** Get the applications info */ - getApplicationInfo: () => Promise> + getApplicationInfo: () => Promise>; /** * Edit properties of the app associated with the requesting bot user. * * @remarks * Only properties that are passed will be updated. */ - editApplicationInfo: (body: EditApplication) => Promise> + editApplicationInfo: (body: EditApplication) => Promise>; /** * Get the current authentication info for the authenticated user * @@ -1545,7 +1545,7 @@ export interface RestManager { * The user object is not defined if the scopes do not include `identify`. * In the user object, if defined, the email is not included if the scopes do not include `email` */ - getCurrentAuthenticationInfo: (bearerToken: string) => Promise> + getCurrentAuthenticationInfo: (bearerToken: string) => Promise>; /** * Exchange the information to get a OAuth2 accessToken token * @@ -1553,7 +1553,11 @@ export interface RestManager { * @param clientSecret - application's client secret * @param options - The options to make the exchange with discord */ - exchangeToken: (clientId: BigString, clientSecret: string, options: Camelize) => Promise> + exchangeToken: ( + clientId: BigString, + clientSecret: string, + options: Camelize, + ) => Promise>; /** * Revoke an access_token * @@ -1561,7 +1565,7 @@ export interface RestManager { * @param clientSecret - application's client secret * @param options - The options to revoke the access_token */ - revokeToken: (clientId: BigString, clientSecret: string, options: Camelize) => Promise + revokeToken: (clientId: BigString, clientSecret: string, options: Camelize) => Promise; /** * Gets the permissions of a guild application command. * @@ -1579,7 +1583,7 @@ export interface RestManager { guildId: BigString, commandId: BigString, options?: GetApplicationCommandPermissionOptions, - ) => Promise> + ) => Promise>; /** * Gets the permissions of all application commands registered in a guild by the ID of the guild and optionally an external application. * @@ -1595,7 +1599,7 @@ export interface RestManager { getApplicationCommandPermissions: ( guildId: BigString, options?: GetApplicationCommandPermissionOptions, - ) => Promise[]> + ) => Promise[]>; /** * Gets a guild's audit log. * @@ -1608,7 +1612,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/audit-log#get-guild-audit-log} */ - getAuditLog: (guildId: BigString, options?: GetGuildAuditLog) => Promise> + getAuditLog: (guildId: BigString, options?: GetGuildAuditLog) => Promise>; /** * Gets an automod rule by its ID. * @@ -1621,7 +1625,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/auto-moderation#get-auto-moderation-rule} */ - getAutomodRule: (guildId: BigString, ruleId: BigString) => Promise> + getAutomodRule: (guildId: BigString, ruleId: BigString) => Promise>; /** * Gets the list of automod rules for a guild. * @@ -1633,13 +1637,13 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/auto-moderation#list-auto-moderation-rules-for-guild} */ - getAutomodRules: (guildId: BigString) => Promise[]> + getAutomodRules: (guildId: BigString) => Promise[]>; /** * Gets the list of available voice regions. * * @returns A collection of {@link DiscordVoiceRegion} objects assorted by voice region ID. */ - getAvailableVoiceRegions: () => Promise[]> + getAvailableVoiceRegions: () => Promise[]>; /** * Gets a ban by user ID. * @@ -1652,7 +1656,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/guild#get-guild-ban} */ - getBan: (guildId: BigString, userId: BigString) => Promise> + getBan: (guildId: BigString, userId: BigString) => Promise>; /** * Gets the list of bans for a guild. * @@ -1667,7 +1671,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/guild#get-guild-bans} */ - getBans: (guildId: BigString, options?: GetBans) => Promise[]> + getBans: (guildId: BigString, options?: GetBans) => Promise[]>; /** * Gets a channel by its ID. * @@ -1679,7 +1683,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/channel#get-channel} */ - getChannel: (channelId: BigString) => Promise> + getChannel: (channelId: BigString) => Promise>; /** * Gets the list of invites for a channel. * @@ -1693,7 +1697,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/channel#get-channel-invites} */ - getChannelInvites: (channelId: BigString) => Promise[]> + getChannelInvites: (channelId: BigString) => Promise[]>; /** * Gets the list of channels for a guild. * @@ -1705,7 +1709,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/guild#get-guild-channels} */ - getChannels: (guildId: BigString) => Promise[]> + getChannels: (guildId: BigString) => Promise[]>; /** * Gets a list of webhooks for a channel. * @@ -1717,7 +1721,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/webhook#get-channel-webhooks} */ - getChannelWebhooks: (channelId: BigString) => Promise[]> + getChannelWebhooks: (channelId: BigString) => Promise[]>; /** * Gets or creates a DM channel with a user. * @@ -1726,7 +1730,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/user#create-dm} */ - getDmChannel: (userId: BigString) => Promise> + getDmChannel: (userId: BigString) => Promise>; /** * Create a new group DM channel with multiple users. * @@ -1742,7 +1746,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/user#create-group-dm} */ - getGroupDmChannel: (options: CreateGroupDmOptions) => Promise> + getGroupDmChannel: (options: CreateGroupDmOptions) => Promise>; /** * Gets an emoji by its ID. * @@ -1756,7 +1760,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/emoji#get-guild-emoji} */ - getEmoji: (guildId: BigString, emojiId: BigString) => Promise> + getEmoji: (guildId: BigString, emojiId: BigString) => Promise>; /** * Gets an application emoji by its ID. * @@ -1768,7 +1772,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/emoji#get-application-emoji} */ - getApplicationEmoji: (emojiId: BigString) => Promise> + getApplicationEmoji: (emojiId: BigString) => Promise>; /** * Gets the list of emojis for a guild. * @@ -1780,7 +1784,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/emoji#list-guild-emojis} */ - getEmojis: (guildId: BigString) => Promise[]> + getEmojis: (guildId: BigString) => Promise[]>; /** * Gets the list of emojis for an application. * @@ -1791,7 +1795,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/emoji#list-application-emojis} */ - getApplicationEmojis: () => Promise<{ items: Camelize[] }> + getApplicationEmojis: () => Promise<{ items: Camelize[] }>; /** * Gets a follow-up message to an interaction by the ID of the message. * @@ -1808,9 +1812,9 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/interactions/receiving-and-responding#get-followup-message} */ - getFollowupMessage: (token: string, messageId: BigString) => Promise> + getFollowupMessage: (token: string, messageId: BigString) => Promise>; /** Get the bots Gateway metadata that can help during the operation of large or sharded bots. */ - getGatewayBot: () => Promise> + getGatewayBot: () => Promise>; /** * Gets a global application command by its ID. * @@ -1819,7 +1823,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/interactions/application-commands#get-global-application-command} */ - getGlobalApplicationCommand: (commandId: BigString) => Promise> + getGlobalApplicationCommand: (commandId: BigString) => Promise>; /** * Gets the list of your bot's global application commands. * @@ -1828,7 +1832,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/interactions/application-commands#get-global-application-commands} */ - getGlobalApplicationCommands: (options?: GetGlobalApplicationCommandsOptions) => Promise[]> + getGlobalApplicationCommands: (options?: GetGlobalApplicationCommandsOptions) => Promise[]>; /** * Gets a guild by its ID. * @@ -1838,7 +1842,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/guild#get-guild} */ - getGuild: (guildId: BigString, options?: { counts?: boolean }) => Promise> + getGuild: (guildId: BigString, options?: { counts?: boolean }) => Promise>; /** * Get the user guilds. * @@ -1851,7 +1855,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/user#get-current-user-guilds} */ - getGuilds: (bearerToken?: string, options?: GetUserGuilds) => Promise>[]> + getGuilds: (bearerToken?: string, options?: GetUserGuilds) => Promise>[]>; /** * Gets a guild application command by its ID. * @@ -1861,7 +1865,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/interactions/application-commands#get-guild-application-command} */ - getGuildApplicationCommand: (commandId: BigString, guildId: BigString) => Promise> + getGuildApplicationCommand: (commandId: BigString, guildId: BigString) => Promise>; /** * Gets the list of application commands registered by your bot in a guild. * @@ -1871,7 +1875,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/interactions/application-commands#get-global-application-commandss} */ - getGuildApplicationCommands: (guildId: BigString, options?: GetGuildApplicationCommandsOptions) => Promise[]> + getGuildApplicationCommands: (guildId: BigString, options?: GetGuildApplicationCommandsOptions) => Promise[]>; /** * Gets the preview of a guild by a guild's ID. * @@ -1883,7 +1887,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/guild#get-guild-preview} */ - getGuildPreview: (guildId: BigString) => Promise> + getGuildPreview: (guildId: BigString) => Promise>; /** * Returns a sticker object for the given guild and sticker IDs. * @@ -1895,7 +1899,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/sticker#get-guild-sticker} */ - getGuildSticker: (guildId: BigString, stickerId: BigString) => Promise> + getGuildSticker: (guildId: BigString, stickerId: BigString) => Promise>; /** * Returns an array of sticker objects for the given guild. * @@ -1906,7 +1910,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/sticker#list-guild-stickers} */ - getGuildStickers: (guildId: BigString) => Promise[]> + getGuildStickers: (guildId: BigString) => Promise[]>; /** * Gets a template by its code. * @@ -1918,7 +1922,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/guild-template#get-guild-template} */ - getGuildTemplate: (templateCode: string) => Promise> + getGuildTemplate: (templateCode: string) => Promise>; /** * Gets the list of templates for a guild. * @@ -1930,7 +1934,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/guild-template#get-guild-templates} */ - getGuildTemplates: (guildId: BigString) => Promise[]> + getGuildTemplates: (guildId: BigString) => Promise[]>; /** * Gets the list of webhooks for a guild. * @@ -1942,7 +1946,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/webhook#get-guild-webhooks} */ - getGuildWebhooks: (guildId: BigString) => Promise[]> + getGuildWebhooks: (guildId: BigString) => Promise[]>; /** * Gets the list of integrations attached to a guild. * @@ -1954,7 +1958,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/guild#get-guild-integrations} */ - getIntegrations: (guildId: BigString) => Promise[]> + getIntegrations: (guildId: BigString) => Promise[]>; /** * Gets an invite to a channel by its invite code. * @@ -1964,7 +1968,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/invite#get-invite} */ - getInvite: (inviteCode: string, options?: GetInvite) => Promise> + getInvite: (inviteCode: string, options?: GetInvite) => Promise>; /** * Gets the list of invites for a guild. * @@ -1976,7 +1980,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/invite#get-invites} */ - getInvites: (guildId: BigString) => Promise[]> + getInvites: (guildId: BigString) => Promise[]>; /** * Gets a message from a channel by the ID of the message. * @@ -1992,7 +1996,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/channel#get-channel-message} */ - getMessage: (channelId: BigString, messageId: BigString) => Promise> + getMessage: (channelId: BigString, messageId: BigString) => Promise>; /** * Gets multiple messages from a channel. * @@ -2008,7 +2012,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/channel#get-channel-messages} */ - getMessages: (channelId: BigString, options?: GetMessagesOptions) => Promise[]> + getMessages: (channelId: BigString, options?: GetMessagesOptions) => Promise[]>; /** * Returns a sticker pack for the given ID. * @@ -2016,7 +2020,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/sticker#get-sticker-pack} */ - getStickerPack: (stickerPackId: BigString) => Promise> + getStickerPack: (stickerPackId: BigString) => Promise>; /** * Returns the list of sticker packs available. * @@ -2024,7 +2028,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/sticker#list-sticker-packs} */ - getStickerPacks: () => Promise[]> + getStickerPacks: () => Promise[]>; /** * Gets the initial message response to an interaction. * @@ -2040,7 +2044,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/interactions/receiving-and-responding#get-original-interaction-response} */ - getOriginalInteractionResponse: (token: string) => Promise> + getOriginalInteractionResponse: (token: string) => Promise>; /** * Retrieves the list of pins in a channel. * @@ -2055,7 +2059,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/message#get-channel-pins} */ - getChannelPins: (channelId: BigString, options?: GetChannelPinsOptions) => Promise> + getChannelPins: (channelId: BigString, options?: GetChannelPinsOptions) => Promise>; /** * Gets the pinned messages for a channel. * @@ -2071,7 +2075,7 @@ export interface RestManager { * @see {@link https://discord.com/developers/docs/resources/message#get-pinned-messages-deprecated} * @deprecated Use {@link getChannelPins} instead. */ - getPinnedMessages: (channelId: BigString) => Promise[]> + getPinnedMessages: (channelId: BigString) => Promise[]>; /** * Gets the list of private archived threads for a channel. * @@ -2089,7 +2093,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/channel#list-private-archived-threads} */ - getPrivateArchivedThreads: (channelId: BigString, options?: ListArchivedThreads) => Promise> + getPrivateArchivedThreads: (channelId: BigString, options?: ListArchivedThreads) => Promise>; /** * Gets the list of private archived threads the bot is a member of for a channel. * @@ -2106,7 +2110,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/channel#list-joined-private-archived-threads} */ - getPrivateJoinedArchivedThreads: (channelId: BigString, options?: ListArchivedThreads) => Promise> + getPrivateJoinedArchivedThreads: (channelId: BigString, options?: ListArchivedThreads) => Promise>; /** * Gets the number of members that would be kicked from a guild during pruning. * @@ -2119,7 +2123,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/guild#get-guild-prune-count} */ - getPruneCount: (guildId: BigString, options?: GetGuildPruneCountQuery) => Promise> + getPruneCount: (guildId: BigString, options?: GetGuildPruneCountQuery) => Promise>; /** * Gets the list of public archived threads for a channel. * @@ -2137,7 +2141,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/channel#list-public-archived-threads} */ - getPublicArchivedThreads: (channelId: BigString, options?: ListArchivedThreads) => Promise> + getPublicArchivedThreads: (channelId: BigString, options?: ListArchivedThreads) => Promise>; /** * Gets the list of roles for a guild. * @@ -2149,7 +2153,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/guild#get-guild-roles} */ - getRoles: (guildId: BigString) => Promise[]> + getRoles: (guildId: BigString) => Promise[]>; /** * Gets a role by id for a guild. * @@ -2159,7 +2163,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/guild#get-guild-role} */ - getRole: (guildId: BigString, roleId: BigString) => Promise> + getRole: (guildId: BigString, roleId: BigString) => Promise>; /** * Gets a scheduled event by its ID. * @@ -2170,7 +2174,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/guild-scheduled-event#get-guild-scheduled-event} */ - getScheduledEvent: (guildId: BigString, eventId: BigString, options?: { withUserCount?: boolean }) => Promise> + getScheduledEvent: (guildId: BigString, eventId: BigString, options?: { withUserCount?: boolean }) => Promise>; /** * Gets the list of scheduled events for a guild. * @@ -2180,7 +2184,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/guild-scheduled-event#list-scheduled-events-for-guild} */ - getScheduledEvents: (guildId: BigString, options?: GetScheduledEvents) => Promise[]> + getScheduledEvents: (guildId: BigString, options?: GetScheduledEvents) => Promise[]>; /** * Gets the list of subscribers to a scheduled event from a guild. * @@ -2200,9 +2204,9 @@ export interface RestManager { guildId: BigString, eventId: BigString, options?: GetScheduledEventUsers, - ) => Promise; member?: Camelize }>> + ) => Promise; member?: Camelize }>>; /** Get the bots Gateway metadata that can help during the operation of large or sharded bots. */ - getSessionInfo: () => Promise> + getSessionInfo: () => Promise>; /** * Gets the stage instance associated with a stage channel, if one exists. * @@ -2211,7 +2215,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/stage-instance#get-stage-instance} */ - getStageInstance: (channelId: BigString) => Promise> + getStageInstance: (channelId: BigString) => Promise>; /** * Returns the current user's voice state in the guild. * @@ -2220,7 +2224,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/voice#get-current-user-voice-state} */ - getOwnVoiceState: (guildId: BigString) => Promise> + getOwnVoiceState: (guildId: BigString) => Promise>; /** * Returns the specified user's voice state in the guild. * @@ -2230,7 +2234,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/voice#get-user-voice-state} */ - getUserVoiceState: (guildId: BigString, userId: BigString) => Promise> + getUserVoiceState: (guildId: BigString, userId: BigString) => Promise>; /** * Returns a sticker object for the given sticker ID. * @@ -2239,7 +2243,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/sticker#get-sticker} */ - getSticker: (stickerId: BigString) => Promise> + getSticker: (stickerId: BigString) => Promise>; /** * Gets a thread member by their user ID. * @@ -2250,7 +2254,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/channel#get-thread-member} */ - getThreadMember: (channelId: BigString, userId: BigString, options?: GetThreadMember) => Promise> + getThreadMember: (channelId: BigString, userId: BigString, options?: GetThreadMember) => Promise>; /** * Gets the list of thread members for a thread. * @@ -2263,7 +2267,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/channel#list-thread-members} */ - getThreadMembers: (channelId: BigString, options?: ListThreadMembers) => Promise[]> + getThreadMembers: (channelId: BigString, options?: ListThreadMembers) => Promise[]>; /** * Gets the list of users that reacted with an emoji to a message. * @@ -2275,14 +2279,14 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/channel#get-reactions} */ - getReactions: (channelId: BigString, messageId: BigString, reaction: string, options?: GetReactions) => Promise[]> + getReactions: (channelId: BigString, messageId: BigString, reaction: string, options?: GetReactions) => Promise[]>; /** * Get a user's data from the api * * @param id The user's id * @returns {DiscordUser} */ - getUser: (id: BigString) => Promise> + getUser: (id: BigString) => Promise>; /** * Get the current user data. * @@ -2294,7 +2298,7 @@ export interface RestManager { * * To get the mail this also requires the `email` scope */ - getCurrentUser: (bearerToken: string) => Promise> + getCurrentUser: (bearerToken: string) => Promise>; /** * Get the current user connections. * @@ -2304,7 +2308,7 @@ export interface RestManager { * @remarks * This requires the `connections` scope. */ - getUserConnections: (bearerToken: string) => Promise[]> + getUserConnections: (bearerToken: string) => Promise[]>; /** * Get the current user application role connection for the application. * @@ -2317,7 +2321,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/user#get-user-application-role-connection} */ - getUserApplicationRoleConnection: (bearerToken: string, applicationId: BigString) => Promise> + getUserApplicationRoleConnection: (bearerToken: string, applicationId: BigString) => Promise>; /** * Gets information about the vanity url of a guild. * @@ -2331,7 +2335,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/guild#get-guild-vanity-url} */ - getVanityUrl: (guildId: BigString) => Promise> + getVanityUrl: (guildId: BigString) => Promise>; /** * Gets the list of voice regions for a guild. * @@ -2340,7 +2344,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/guild#get-guild-voice-regions} */ - getVoiceRegions: (guildId: BigString) => Promise[]> + getVoiceRegions: (guildId: BigString) => Promise[]>; /** * Gets a webhook by its ID. * @@ -2352,7 +2356,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/webhook#get-webhook} */ - getWebhook: (webhookId: BigString) => Promise> + getWebhook: (webhookId: BigString) => Promise>; /** * Gets a webhook message by its ID. * @@ -2369,7 +2373,7 @@ export interface RestManager { token: string, messageId: BigString, options?: GetWebhookMessageOptions, - ) => Promise> + ) => Promise>; /** * Gets a webhook using the webhook token, thereby bypassing the need for authentication + permissions. * @@ -2379,7 +2383,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/webhook#get-webhook-with-token} */ - getWebhookWithToken: (webhookId: BigString, token: string) => Promise> + getWebhookWithToken: (webhookId: BigString, token: string) => Promise>; /** * Gets the welcome screen for a guild. * @@ -2392,7 +2396,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/guild#get-guild-welcome-screen} */ - getWelcomeScreen: (guildId: BigString) => Promise> + getWelcomeScreen: (guildId: BigString) => Promise>; /** * Gets the guild widget by guild ID. * @@ -2404,7 +2408,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/guild#get-guild-widget} */ - getWidget: (guildId: BigString) => Promise> + getWidget: (guildId: BigString) => Promise>; /** * Gets the settings of a guild's widget. * @@ -2416,7 +2420,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/guild#get-guild-widget-settings} */ - getWidgetSettings: (guildId: BigString) => Promise> + getWidgetSettings: (guildId: BigString) => Promise>; /** * Adds the bot user to a thread. * @@ -2429,7 +2433,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/channel#join-thread} */ - joinThread: (channelId: BigString) => Promise + joinThread: (channelId: BigString) => Promise; /** * Leaves a guild. * @@ -2440,7 +2444,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/user#leave-guild} */ - leaveGuild: (guildId: BigString) => Promise + leaveGuild: (guildId: BigString) => Promise; /** * Removes the bot user from a thread. * @@ -2453,7 +2457,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/channel#leave-thread} */ - leaveThread: (channelId: BigString) => Promise + leaveThread: (channelId: BigString) => Promise; /** * Cross-posts a message posted in an announcement channel to subscribed channels. * @@ -2471,7 +2475,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/channel#crosspost-message} */ - publishMessage: (channelId: BigString, messageId: BigString) => Promise> + publishMessage: (channelId: BigString, messageId: BigString) => Promise>; /** * Removes a role from a member. * @@ -2487,7 +2491,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/guild#remove-guild-member-role} */ - removeRole: (guildId: BigString, userId: BigString, roleId: BigString, reason?: string) => Promise + removeRole: (guildId: BigString, userId: BigString, roleId: BigString, reason?: string) => Promise; /** * Removes a member from a thread. * @@ -2504,7 +2508,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/channel#remove-thread-member} */ - removeThreadMember: (channelId: BigString, userId: BigString) => Promise + removeThreadMember: (channelId: BigString, userId: BigString) => Promise; /** * Removes a member from a Group DM. * @@ -2513,7 +2517,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/channel#group-dm-remove-recipient} */ - removeDmRecipient: (channelId: BigString, userId: BigString) => Promise + removeDmRecipient: (channelId: BigString, userId: BigString) => Promise; /** * Sends a message to a channel. * @@ -2540,7 +2544,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/channel#create-message} */ - sendMessage: (channelId: BigString, options: CreateMessageOptions) => Promise> + sendMessage: (channelId: BigString, options: CreateMessageOptions) => Promise>; /** * Sends a follow-up message to an interaction. * @@ -2564,7 +2568,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/interactions/receiving-and-responding#create-followup-message} */ - sendFollowupMessage: (token: string, options: InteractionCallbackData) => Promise> + sendFollowupMessage: (token: string, options: InteractionCallbackData) => Promise>; /** * Sends a response to an interaction. * @@ -2592,7 +2596,7 @@ export interface RestManager { token: string, options: InteractionResponse, params?: InteractionCallbackOptions, - ) => Promise> + ) => Promise>; /** * Creates a thread, using an existing message as its point of origin. * @@ -2618,7 +2622,7 @@ export interface RestManager { messageId: BigString, options: StartThreadWithMessage, reason?: string, - ) => Promise> + ) => Promise>; /** * Creates a thread without using a message as the thread's point of origin. * @@ -2634,7 +2638,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/channel#start-thread-without-message} */ - startThreadWithoutMessage: (channelId: BigString, options: StartThreadWithoutMessage, reason?: string) => Promise> + startThreadWithoutMessage: (channelId: BigString, options: StartThreadWithoutMessage, reason?: string) => Promise>; /** * Get a list of users that voted for this specific answer. * @@ -2649,7 +2653,7 @@ export interface RestManager { messageId: BigString, answerId: number, options?: GetPollAnswerVotes, - ) => Promise> + ) => Promise>; /** * Immediately ends the poll. * @@ -2662,7 +2666,7 @@ export interface RestManager { * * Fires a _Message Update_ gateway event */ - endPoll: (channelId: BigString, messageId: BigString) => Promise> + endPoll: (channelId: BigString, messageId: BigString) => Promise>; /** * Synchronises a template with the current state of a guild. * @@ -2676,7 +2680,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/guild-template#get-guild-templates} */ - syncGuildTemplate: (guildId: BigString) => Promise> + syncGuildTemplate: (guildId: BigString) => Promise>; /** * Triggers a typing indicator for the specified channel, which expires after 10 seconds. * @@ -2691,7 +2695,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/channel#trigger-typing-indicator} */ - triggerTypingIndicator: (channelId: BigString) => Promise + triggerTypingIndicator: (channelId: BigString) => Promise; /** * Re-registers the list of global application commands, overwriting the previous commands completely. * @@ -2712,7 +2716,7 @@ export interface RestManager { upsertGlobalApplicationCommands: ( commands: CreateApplicationCommand[], options?: UpsertGlobalApplicationCommandOptions, - ) => Promise[]> + ) => Promise[]>; /** * Re-registers the list of application commands registered in a guild, overwriting the previous commands completely. * @@ -2735,7 +2739,7 @@ export interface RestManager { guildId: BigString, commands: CreateApplicationCommand[], options?: UpsertGuildApplicationCommandOptions, - ) => Promise[]> + ) => Promise[]>; /** * Bans a user from a guild. * @@ -2751,7 +2755,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/guild#create-guild-ban} */ - banMember: (guildId: BigString, userId: BigString, options?: CreateGuildBan, reason?: string) => Promise + banMember: (guildId: BigString, userId: BigString, options?: CreateGuildBan, reason?: string) => Promise; /** * Bans up to 200 users from a guild. * @@ -2768,7 +2772,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/guild#bulk-guild-ban} */ - bulkBanMembers: (guildId: BigString, options: CreateGuildBulkBan, reason?: string) => Promise> + bulkBanMembers: (guildId: BigString, options: CreateGuildBulkBan, reason?: string) => Promise>; /** * Edits the nickname of the bot user. * @@ -2782,7 +2786,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/guild#modify-current-member} */ - editBotMember: (guildId: BigString, options: EditBotMemberOptions, reason?: string) => Promise> + editBotMember: (guildId: BigString, options: EditBotMemberOptions, reason?: string) => Promise>; /** * Edits a member's properties. * @@ -2799,7 +2803,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/guild#modify-guild-member} */ - editMember: (guildId: BigString, userId: BigString, options: ModifyGuildMember, reason?: string) => Promise> + editMember: (guildId: BigString, userId: BigString, options: ModifyGuildMember, reason?: string) => Promise>; /** * Gets the member object by user ID. * @@ -2810,7 +2814,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/guild#get-guild-member} */ - getMember: (guildId: BigString, userId: BigString) => Promise> + getMember: (guildId: BigString, userId: BigString) => Promise>; /** * Gets the current member object. * @@ -2823,7 +2827,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/user#get-current-user-guild-member} */ - getCurrentMember: (guildId: BigString, bearerToken: string) => Promise> + getCurrentMember: (guildId: BigString, bearerToken: string) => Promise>; /** * Gets the list of members for a guild. * @@ -2842,14 +2846,14 @@ export interface RestManager { * @see {@link https://discord.com/developers/docs/topics/gateway#request-guild-members} * @see {@link https://discord.com/developers/docs/topics/rate-limits#rate-limits} */ - getMembers: (guildId: BigString, options: ListGuildMembers) => Promise[]> + getMembers: (guildId: BigString, options: ListGuildMembers) => Promise[]>; /** * Returns a serialized activity instance, if it exists. Useful for preventing unwanted activity sessions. * * @param applicationId - The ID of the application * @param instanceId - The ID of the activity instance */ - getApplicationActivityInstance: (applicationId: BigString, instanceId: string) => Promise> + getApplicationActivityInstance: (applicationId: BigString, instanceId: string) => Promise>; /** * Kicks a member from a guild. * @@ -2865,7 +2869,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/guild#remove-guild-member} */ - kickMember: (guildId: BigString, userId: BigString, reason?: string) => Promise + kickMember: (guildId: BigString, userId: BigString, reason?: string) => Promise; /** * Pins a message in a channel. * @@ -2880,7 +2884,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/message#pin-message} */ - pinMessage: (channelId: BigString, messageId: BigString, reason?: string) => Promise + pinMessage: (channelId: BigString, messageId: BigString, reason?: string) => Promise; /** * Initiates the process of pruning inactive members. * @@ -2901,7 +2905,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/guild#begin-guild-prune} */ - pruneMembers: (guildId: BigString, options: BeginGuildPrune, reason?: string) => Promise<{ pruned: number | null }> + pruneMembers: (guildId: BigString, options: BeginGuildPrune, reason?: string) => Promise<{ pruned: number | null }>; /** * Gets the list of members whose usernames or nicknames start with a provided string. * @@ -2913,7 +2917,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/guild#search-guild-members} */ - searchMembers: (guildId: BigString, query: string, options?: Omit) => Promise[]> + searchMembers: (guildId: BigString, query: string, options?: Omit) => Promise[]>; /** * Unbans a user from a guild. * @@ -2929,7 +2933,7 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/guild#remove-guild-ban} */ - unbanMember: (guildId: BigString, userId: BigString, reason?: string) => Promise + unbanMember: (guildId: BigString, userId: BigString, reason?: string) => Promise; /** * Unpin a message in a channel. * @@ -2944,13 +2948,13 @@ export interface RestManager { * * @see {@link https://discord.com/developers/docs/resources/message#unpin-message} */ - unpinMessage: (channelId: BigString, messageId: BigString, reason?: string) => Promise + unpinMessage: (channelId: BigString, messageId: BigString, reason?: string) => Promise; /** * Get the guild onboarding * * @param guildId - The guild to get the onboarding from */ - getGuildOnboarding: (guildId: BigString) => Promise> + getGuildOnboarding: (guildId: BigString) => Promise>; /** * Modifies the onboarding configuration of the guild. * @@ -2966,7 +2970,7 @@ export interface RestManager { * * The `mode` field modifies what is considered when enforcing these constraints. */ - editGuildOnboarding: (guildId: BigString, options: EditGuildOnboarding, reason?: string) => Promise> + editGuildOnboarding: (guildId: BigString, options: EditGuildOnboarding, reason?: string) => Promise>; /** * Modifies the incident actions of the guild. * @@ -2976,21 +2980,21 @@ export interface RestManager { * @remarks * Requires the `MANAGE_GUILD` permission. */ - modifyGuildIncidentActions: (guildId: BigString, options: ModifyGuildIncidentActions) => Promise> + modifyGuildIncidentActions: (guildId: BigString, options: ModifyGuildIncidentActions) => Promise>; /** * Returns all entitlements for a given app, active and expired. * * @param applicationId - The id of the application to get the entitlements * @param {GetEntitlements} [options] - The optional query params for the endpoint */ - listEntitlements: (applicationId: BigString, options?: GetEntitlements) => Promise[]> + listEntitlements: (applicationId: BigString, options?: GetEntitlements) => Promise[]>; /** * Returns an entitlement. * * @param applicationId - The id of the application to get the entitlement * @param entitlementId - The id of the entitlement to get */ - getEntitlement: (applicationId: BigString, entitlementId: BigString) => Promise> + getEntitlement: (applicationId: BigString, entitlementId: BigString) => Promise>; /** * Creates a test entitlement to a given SKU for a given guild or user. Discord will act as though that user or guild has entitlement to your premium offering. * @@ -3001,39 +3005,39 @@ export interface RestManager { * This endpoint returns a partial entitlement object. * It will not contain subscription_id, starts_at, or ends_at, as it's valid in perpetuity. */ - createTestEntitlement: (applicationId: BigString, body: CreateTestEntitlement) => Promise>> + createTestEntitlement: (applicationId: BigString, body: CreateTestEntitlement) => Promise>>; /** * Deletes a currently-active test entitlement. Discord will act as though that user or guild no longer has entitlement to your premium offering. * * @param applicationId - The id of the application from where delete the entitlement * @param entitlementId - The id of the entitlement to delete */ - deleteTestEntitlement: (applicationId: BigString, entitlementId: BigString) => Promise + deleteTestEntitlement: (applicationId: BigString, entitlementId: BigString) => Promise; /** * For One-Time Purchase consumable SKUs, marks a given entitlement for the user as consumed. The entitlement will have `consumed: true` when using {@link listEntitlements | List Entitlements} * * @param applicationId - The id of the application to get the entitlement * @param entitlementId - The id of the entitlement to get */ - consumeEntitlement: (applicationId: BigString, entitlementId: BigString) => Promise + consumeEntitlement: (applicationId: BigString, entitlementId: BigString) => Promise; /** * Returns all SKUs for a given application * * @param applicationId - The id of the application to get the SKUs */ - listSkus: (applicationId: BigString) => Promise[]> + listSkus: (applicationId: BigString) => Promise[]>; /** * Returns all subscriptions containing the SKU, filtered by user. * * @param skuId - The id of the sku of get the subscriptions for */ - listSubscriptions: (skuId: BigString, options?: ListSkuSubscriptionsOptions) => Promise> + listSubscriptions: (skuId: BigString, options?: ListSkuSubscriptionsOptions) => Promise>; /** * Get a subscription by its ID. * * @param skuId - The id of the sku of get the subscriptions for */ - getSubscription: (skuId: BigString, subscriptionId: BigString) => Promise> + getSubscription: (skuId: BigString, subscriptionId: BigString) => Promise>; /** * Send a soundboard sound to a voice channel the user is connected to. * @@ -3045,9 +3049,9 @@ export interface RestManager { * Requires the `SPEAK` and `USE_SOUNDBOARD` permissions, and also the `USE_EXTERNAL_SOUNDS` permission if the sound is from a different server. * Additionally, requires the user to be connected to the voice channel, having a voice state without `deaf`, `self_deaf`, `mute`, or `suppress` enabled. */ - sendSoundboardSound: (channelId: BigString, options: SendSoundboardSound) => Promise + sendSoundboardSound: (channelId: BigString, options: SendSoundboardSound) => Promise; /** Returns an array of soundboard sound objects that can be used by all users. */ - listDefaultSoundboardSounds: () => Promise[]> + listDefaultSoundboardSounds: () => Promise[]>; /** * Returns a list of the guild's soundboard sounds. * @@ -3056,7 +3060,7 @@ export interface RestManager { * @remarks * Includes `user` fields if the bot has the `CREATE_GUILD_EXPRESSIONS` or `MANAGE_GUILD_EXPRESSIONS` permission. */ - listGuildSoundboardSounds: (guildId: BigString) => Promise<{ items: Camelize[] }> + listGuildSoundboardSounds: (guildId: BigString) => Promise<{ items: Camelize[] }>; /** * Returns a soundboard sound object for the given sound id. * @@ -3066,7 +3070,7 @@ export interface RestManager { * @remarks * Includes `user` fields if the bot has the `CREATE_GUILD_EXPRESSIONS` or `MANAGE_GUILD_EXPRESSIONS` permission. */ - getGuildSoundboardSound: (guildId: BigString, soundId: BigString) => Promise> + getGuildSoundboardSound: (guildId: BigString, soundId: BigString) => Promise>; /** * Create a new soundboard sound for the guild. * @@ -3079,7 +3083,7 @@ export interface RestManager { * * Requires the `CREATE_GUILD_EXPRESSIONS` permission. */ - createGuildSoundboardSound: (guildId: BigString, options: CreateGuildSoundboardSound, reason?: string) => Promise> + createGuildSoundboardSound: (guildId: BigString, options: CreateGuildSoundboardSound, reason?: string) => Promise>; /** * Modify the given soundboard sound. * @@ -3099,7 +3103,7 @@ export interface RestManager { soundId: BigString, options: ModifyGuildSoundboardSound, reason?: string, - ) => Promise> + ) => Promise>; /** * Delete the given soundboard sound. * @@ -3113,14 +3117,14 @@ export interface RestManager { * For sounds created by the current user, requires either the `CREATE_GUILD_EXPRESSIONS` or `MANAGE_GUILD_EXPRESSIONS` permission. * For other sounds, requires the `MANAGE_GUILD_EXPRESSIONS` permission. */ - deleteGuildSoundboardSound: (guildId: BigString, soundId: BigString, reason?: string) => Promise + deleteGuildSoundboardSound: (guildId: BigString, soundId: BigString, reason?: string) => Promise; /** * Returns a list of application role connection metadata objects for the given application. * * @param applicationId - The application to get the role connections from * @returns A list of application role connection metadata objects */ - listApplicationRoleConnectionsMetadataRecords: (applicationId: BigString) => Promise[]> + listApplicationRoleConnectionsMetadataRecords: (applicationId: BigString) => Promise[]>; /** * Updates and returns a list of application role connection metadata objects for the given application. * @@ -3134,21 +3138,21 @@ export interface RestManager { updateApplicationRoleConnectionsMetadataRecords: ( applicationId: BigString, options: Camelize[], - ) => Promise[]> + ) => Promise[]>; /** * Creates a new lobby, adding any of the specified members to it, if provided. * * @param options - The options to create the lobby * @returns The created lobby */ - createLobby: (options: CreateLobby) => Promise> + createLobby: (options: CreateLobby) => Promise>; /** * Returns a lobby object for the specified lobby id, if it exists. * * @param lobbyId - The ID of the lobby to get * @returns The lobby object */ - getLobby: (lobbyId: BigString) => Promise> + getLobby: (lobbyId: BigString) => Promise>; /** * Modifies the specified lobby with new values, if provided. * @@ -3156,7 +3160,7 @@ export interface RestManager { * @param options - The options to modify the lobby * @returns The modified lobby */ - modifyLobby: (lobbyId: BigString, options: ModifyLobby) => Promise> + modifyLobby: (lobbyId: BigString, options: ModifyLobby) => Promise>; /** * Deletes the specified lobby if it exists. * @@ -3165,7 +3169,7 @@ export interface RestManager { * @param lobbyId - The ID of the lobby to delete * @returns Nothing */ - deleteLobby: (lobbyId: BigString) => Promise + deleteLobby: (lobbyId: BigString) => Promise; /** * Adds the provided user to the specified lobby. If called when the user is already a member of the lobby will update fields such as metadata on that user instead. * @@ -3174,7 +3178,7 @@ export interface RestManager { * @param options - The options to add the user to the lobby * @returns The lobby member object */ - addMemberToLobby: (lobbyId: BigString, userId: BigString, options: AddLobbyMember) => Promise> + addMemberToLobby: (lobbyId: BigString, userId: BigString, options: AddLobbyMember) => Promise>; /** * Removes the provided user from the specified lobby. It is safe to call this even if the user is no longer a member of the lobby, but will fail if the lobby does not exist. * @@ -3182,7 +3186,7 @@ export interface RestManager { * @param userId - The ID of the user to remove from the lobby * @returns Nothing */ - removeMemberFromLobby: (lobbyId: BigString, userId: BigString) => Promise + removeMemberFromLobby: (lobbyId: BigString, userId: BigString) => Promise; /** * Removes the current user from the specified lobby. It is safe to call this even if the user is no longer a member of the lobby, but will fail if the lobby does not exist. * @@ -3193,7 +3197,7 @@ export interface RestManager { * @remarks * This requires a bearer token for authorization */ - leaveLobby: (lobbyId: BigString, bearerToken: string) => Promise + leaveLobby: (lobbyId: BigString, bearerToken: string) => Promise; /** * Links an existing text channel to a lobby. * @@ -3205,7 +3209,7 @@ export interface RestManager { * @remarks * Uses bearer token for authorization and the user must be a lobby member with the CanLinkLobby lobby member flag. */ - linkChannelToLobby: (lobbyId: BigString, bearerToken: string, options: LinkChannelToLobby) => Promise> + linkChannelToLobby: (lobbyId: BigString, bearerToken: string, options: LinkChannelToLobby) => Promise>; /** * Unlinks any currently linked channels from the specified lobby. * @@ -3216,73 +3220,73 @@ export interface RestManager { * @remarks * Uses bearer token for authorization and the user must be a lobby member with the CanLinkLobby lobby member flag. */ - unlinkChannelToLobby: (lobbyId: BigString, bearerToken: string) => Promise> + unlinkChannelToLobby: (lobbyId: BigString, bearerToken: string) => Promise>; } -export type RequestMethods = 'GET' | 'POST' | 'DELETE' | 'PATCH' | 'PUT' -export type ApiVersions = 9 | 10 +export type RequestMethods = 'GET' | 'POST' | 'DELETE' | 'PATCH' | 'PUT'; +export type ApiVersions = 9 | 10; export interface CreateRequestBodyOptions { - headers?: Record - body?: any - unauthorized?: boolean - reason?: string - files?: FileContent[] + headers?: Record; + body?: any; + unauthorized?: boolean; + reason?: string; + files?: FileContent[]; } -export type MakeRequestOptions = Omit & Pick +export type MakeRequestOptions = Omit & Pick; export interface RequestBody { - headers: Record - body?: string | FormData - method: RequestMethods + headers: Record; + body?: string | FormData; + method: RequestMethods; } export interface SendRequestOptions { /** The route to send the request to. */ - route: string + route: string; /** The method to use for sending the request. */ - method: RequestMethods + method: RequestMethods; /** The amount of times this request has been retried. */ - retryCount: number + retryCount: number; /** Handler to retry a request should it be rate limited. */ - retryRequest?: (options: SendRequestOptions) => Promise + retryRequest?: (options: SendRequestOptions) => Promise; /** Resolve handler when a request succeeds. */ - resolve: (value: RestRequestResponse) => void + resolve: (value: RestRequestResponse) => void; /** Reject handler when a request fails. */ - reject: (value: RestRequestRejection) => void + reject: (value: RestRequestRejection) => void; /** If this request has a bucket id which it falls under for rate limit */ - bucketId?: string + bucketId?: string; /** Additional request options, used for things like overriding authorization header. */ - requestBodyOptions?: CreateRequestBodyOptions + requestBodyOptions?: CreateRequestBodyOptions; /** * Whether the request should be run through the queue. * Useful for routes which do not have any rate limits. */ - runThroughQueue?: boolean + runThroughQueue?: boolean; } export interface RestRateLimitedPath { - url: string - resetTimestamp: number - bucketId?: string + url: string; + resetTimestamp: number; + bucketId?: string; } export interface RestRequestResponse { - ok: boolean - status: number + ok: boolean; + status: number; /** The returned body parsed if it was JSON, otherwise it will be the raw body as a string */ - body?: string | object + body?: string | object; } export interface RestRequestRejection { - ok: boolean - status: number + ok: boolean; + status: number; /** The HTTP 1.1 status code text */ - statusText?: string + statusText?: string; /** The returned body parsed if it was JSON, otherwise it will be the raw body as a string */ - body?: string | object - error?: string + body?: string | object; + error?: string; } export interface RestManagerEvents { @@ -3292,7 +3296,7 @@ export interface RestManagerEvents { * @remarks * The body that will be sent to the API is available in the `extra` parameter. Do not consume the body in the `Request` object and use the one in the `extra` parameter instead. */ - request: (request: Request, extra: { body: any }) => void + request: (request: Request, extra: { body: any }) => void; /** * Emitted when a response is received from the API. * @@ -3301,12 +3305,12 @@ export interface RestManagerEvents { * * Both the request and the response body are available in the `extra` parameter. Do not consume the body in the `Request` or `Response` object and use the one in the `extra` parameter instead. */ - response: (request: Request, response: Response, extra: { requestBody: any; responseBody: string | object }) => void + response: (request: Request, response: Response, extra: { requestBody: any; responseBody: string | object }) => void; /** * Emitted when a request errors due to fetch error. * * @remarks * The body that was sent to the API is available in the `extra` parameter. */ - requestError: (request: Request, error: any, extra: { body: any }) => void + requestError: (request: Request, error: any, extra: { body: any }) => void; } diff --git a/packages/rest/src/typings/routes.ts b/packages/rest/src/typings/routes.ts index e9ea0b6c7..e693bd779 100644 --- a/packages/rest/src/typings/routes.ts +++ b/packages/rest/src/typings/routes.ts @@ -17,316 +17,316 @@ import type { ListGuildMembers, ListSkuSubscriptionsOptions, ListThreadMembers, -} from '@discordeno/types' +} from '@discordeno/types'; export interface RestRoutes { /** A specific user route. */ - user: (id: BigString) => string + user: (id: BigString) => string; // Gateway Bot - gatewayBot: () => string + gatewayBot: () => string; // Standard Sticker Packs - stickerPacks: () => string - stickerPack: (stickerPackId: BigString) => string + stickerPacks: () => string; + stickerPack: (stickerPackId: BigString) => string; /** Routes for webhook related routes. */ webhooks: { /** Route for webhook with a id. */ - id: (webhookId: BigString) => string + id: (webhookId: BigString) => string; /** Route for handling a webhook with a token. */ - webhook: (webhookId: BigString, token: string, options?: { wait?: boolean; threadId?: BigString; withComponents?: boolean }) => string + webhook: (webhookId: BigString, token: string, options?: { wait?: boolean; threadId?: BigString; withComponents?: boolean }) => string; /** Route for handling a message that was sent through a webhook. */ - message: (webhookId: BigString, token: string, messageId: BigString, options?: { threadId?: BigString; withComponents?: boolean }) => string - } + message: (webhookId: BigString, token: string, messageId: BigString, options?: { threadId?: BigString; withComponents?: boolean }) => string; + }; /** Routes for channel related endpoints. */ channels: { /** Route for handling bulk messages in a channel. */ - bulk: (channelId: BigString) => string + bulk: (channelId: BigString) => string; /** Route for non-specific dm channel. */ - dm: () => string + dm: () => string; /** Route to add a user to an exiting group DM, requires an access token with the OAuth2 `gdm.join` scope */ - dmRecipient: (channelId: BigString, userId: BigString) => string + dmRecipient: (channelId: BigString, userId: BigString) => string; /** Route for handling a specific pin. */ - pin: (channelId: BigString, messageId: BigString) => string + pin: (channelId: BigString, messageId: BigString) => string; /** Route for handling a channel's pins. */ - pins: (channelId: BigString) => string + pins: (channelId: BigString) => string; /** Route for handling a channel's pins. */ - messagePins: (channelId: BigString, options?: GetChannelPinsOptions) => string + messagePins: (channelId: BigString, options?: GetChannelPinsOptions) => string; /** Route for handling a specific pin. */ - messagePin: (channelId: BigString, messageId: BigString) => string + messagePin: (channelId: BigString, messageId: BigString) => string; /** Route for non-specific webhook in a channel. */ - webhooks: (channelId: BigString) => string + webhooks: (channelId: BigString) => string; /** Route for a specific channel. */ - channel: (channelId: BigString) => string + channel: (channelId: BigString) => string; /** Route for following a specific channel. */ - follow: (channelId: BigString) => string + follow: (channelId: BigString) => string; /** Route for managing a forum with a message. */ - forum: (channelId: BigString) => string + forum: (channelId: BigString) => string; /** Route for a specific channel's invites. */ - invites: (channelId: BigString) => string + invites: (channelId: BigString) => string; /** Route for a specific message */ - message: (channelId: BigString, id: BigString) => string + message: (channelId: BigString, id: BigString) => string; /** Route for handling non-specific messages. */ - messages: (channelId: BigString, options?: GetMessagesOptions) => string + messages: (channelId: BigString, options?: GetMessagesOptions) => string; /** Route for handling a specific overwrite. */ - overwrite: (channelId: BigString, overwriteId: BigString) => string + overwrite: (channelId: BigString, overwriteId: BigString) => string; /** Route for handling crossposting a specific message. */ - crosspost: (channelId: BigString, messageId: BigString) => string + crosspost: (channelId: BigString, messageId: BigString) => string; /** Route for handling non-specific stages */ - stages: () => string + stages: () => string; /** Route for handling a specific stage */ - stage: (channelId: BigString) => string + stage: (channelId: BigString) => string; /** Routes for handling thread related to a channel. */ threads: { /** Route for thread a specific message. */ - message: (channelId: BigString, messageId: BigString) => string + message: (channelId: BigString, messageId: BigString) => string; /** Route for thread without a message. */ - all: (channelId: BigString) => string + all: (channelId: BigString) => string; /** Route for active threads. */ - active: (guildId: BigString) => string + active: (guildId: BigString) => string; /** Route for members in a thread. */ - members: (channelId: BigString, options?: ListThreadMembers) => string + members: (channelId: BigString, options?: ListThreadMembers) => string; /** Route for the bot member in a thread. */ - me: (channelId: BigString) => string + me: (channelId: BigString) => string; /** Route for getting a specific member in a thread. */ - getUser: (channelId: BigString, userId: BigString, options?: GetThreadMember) => string + getUser: (channelId: BigString, userId: BigString, options?: GetThreadMember) => string; /** Route for a specific member in a thread apart from the route for getting the member. */ - user: (channelId: BigString, userId: BigString) => string + user: (channelId: BigString, userId: BigString) => string; /** Route for handling archived threads. */ - archived: (channelId: BigString) => string + archived: (channelId: BigString) => string; /** Route for handling publically archived threads. */ - public: (channelId: BigString, options?: ListArchivedThreads) => string + public: (channelId: BigString, options?: ListArchivedThreads) => string; /** Route for handling private archived threads. */ - private: (channelId: BigString, options?: ListArchivedThreads) => string + private: (channelId: BigString, options?: ListArchivedThreads) => string; /** Route for handling private archived threads that the bot has joined. */ - joined: (channelId: BigString, options?: ListArchivedThreads) => string - } + joined: (channelId: BigString, options?: ListArchivedThreads) => string; + }; /** Route for handling typing indicators in a c«hannel. */ - typing: (channelId: BigString) => string + typing: (channelId: BigString) => string; /** Routes for handling reactions on a message. */ reactions: { /** Route for handling a bots reaction. */ - bot: (channelId: BigString, messageId: BigString, emoji: string) => string + bot: (channelId: BigString, messageId: BigString, emoji: string) => string; /** Route for handling a user's reactions. */ - user: (channelId: BigString, messageId: BigString, emoji: string, userId: BigString) => string + user: (channelId: BigString, messageId: BigString, emoji: string, userId: BigString) => string; /** Route for handling all the reactions on a message. */ - all: (channelId: BigString, messageId: BigString) => string + all: (channelId: BigString, messageId: BigString) => string; /** Route for handling all reactions for a single emoji on a message. */ - emoji: (channelId: BigString, messageId: BigString, emoji: string, options?: GetReactions) => string + emoji: (channelId: BigString, messageId: BigString, emoji: string, options?: GetReactions) => string; /** Route for handling a specific reaction on a message. */ - message: (channelId: BigString, messageId: BigString, emoji: string, options?: GetReactions) => string - } + message: (channelId: BigString, messageId: BigString, emoji: string, options?: GetReactions) => string; + }; polls: { - votes: (channelId: BigString, messageId: BigString, answerId: number, options?: GetPollAnswerVotes) => string - expire: (channelId: BigString, messageId: BigString) => string - } - } + votes: (channelId: BigString, messageId: BigString, answerId: number, options?: GetPollAnswerVotes) => string; + expire: (channelId: BigString, messageId: BigString) => string; + }; + }; /** Routes for guild related endpoints. */ guilds: { /** Routes for handling a non-specific guild. */ - all: () => string + all: () => string; /** Route for fetching an user guilds. Requires `guilds` OAuth2 scope */ - userGuilds: (options?: GetUserGuilds) => string + userGuilds: (options?: GetUserGuilds) => string; /** Route for handling audit logs in a guild. */ - auditlogs: (guildId: BigString, options?: GetGuildAuditLog) => string + auditlogs: (guildId: BigString, options?: GetGuildAuditLog) => string; /** Routes for a guilds automoderation. */ automod: { /** Route for handling a guild's automoderation. */ - rules: (guildId: BigString) => string + rules: (guildId: BigString) => string; /** Route for handling a specific automoderation rule guild's */ - rule: (guildId: BigString, ruleId: BigString) => string - } + rule: (guildId: BigString, ruleId: BigString) => string; + }; /** Routes for handling a guild's scheduled events. */ events: { /** Route for handling non-specific scheduled event. */ - events: (guildId: BigString, withUserCount?: boolean) => string + events: (guildId: BigString, withUserCount?: boolean) => string; /** Route for handling a specific scheduled event. */ - event: (guildId: BigString, eventId: BigString, withUserCount?: boolean) => string + event: (guildId: BigString, eventId: BigString, withUserCount?: boolean) => string; /** Route for handling a scheduled event users. */ - users: (guildId: BigString, eventId: BigString, options?: GetScheduledEventUsers) => string - } + users: (guildId: BigString, eventId: BigString, options?: GetScheduledEventUsers) => string; + }; /** Route for handling non-specific channels in a guild */ - channels: (guildId: BigString) => string + channels: (guildId: BigString) => string; /** Route for handling a specific emoji. */ - emoji: (guildId: BigString, id: BigString) => string + emoji: (guildId: BigString, id: BigString) => string; /** Route for handling non-specific emojis. */ - emojis: (guildId: BigString) => string + emojis: (guildId: BigString) => string; /** Route for handling a specific guild. */ - guild: (guildId: BigString, withCounts?: boolean) => string + guild: (guildId: BigString, withCounts?: boolean) => string; /** Route for handling a specific integration. */ - integration: (guildId: BigString, integrationId: BigString) => string + integration: (guildId: BigString, integrationId: BigString) => string; /** Route for handling non-specific integrations. */ - integrations: (guildId: BigString) => string + integrations: (guildId: BigString) => string; /** Route for handling a specific guild invite. */ - invite: (inviteCode: string, options?: GetInvite) => string + invite: (inviteCode: string, options?: GetInvite) => string; /** Route for handling non-specific invites in a guild. */ - invites: (guildId: BigString) => string + invites: (guildId: BigString) => string; /** Route for handling a bot leaving a guild. */ - leave: (guildId: BigString) => string + leave: (guildId: BigString) => string; /** Route for handling a guild's preview. */ - preview: (guildId: BigString) => string + preview: (guildId: BigString) => string; /** Route for handling pruning of a guild. */ - prune: (guildId: BigString, options?: GetGuildPruneCountQuery) => string + prune: (guildId: BigString, options?: GetGuildPruneCountQuery) => string; /** Route for handling non-specific webhooks in a guild */ - webhooks: (guildId: BigString) => string + webhooks: (guildId: BigString) => string; /** Route for handling a guild's welcome screen. */ - welcome: (guildId: BigString) => string + welcome: (guildId: BigString) => string; /** Route for handling a guild's widget. */ - widget: (guildId: BigString) => string + widget: (guildId: BigString) => string; /** Route for handling a guild's widget in the form of json. */ - widgetJson: (guildId: BigString) => string + widgetJson: (guildId: BigString) => string; /** Routes for handling a guild's members. */ members: { /** Route for handling a specific guild member's ban. */ - ban: (guildId: BigString, userId: BigString) => string + ban: (guildId: BigString, userId: BigString) => string; /** Route for handling non-specific bans in a guild. */ - bans: (guildId: BigString, options?: GetBans) => string + bans: (guildId: BigString, options?: GetBans) => string; /** Route for bulk-banning members. */ - bulkBan: (guildId: BigString) => string + bulkBan: (guildId: BigString) => string; /** Route for handling a the bot guild member. */ - bot: (guildId: BigString) => string + bot: (guildId: BigString) => string; /** Route for handling a specific guild member. */ - member: (guildId: BigString, userId: BigString) => string + member: (guildId: BigString, userId: BigString) => string; /** Route to get the authenticated user. Requires the `guilds.members.read` OAuth2 scope */ - currentMember: (guildId: BigString) => string + currentMember: (guildId: BigString) => string; /** Route for handling non-specific guild members. */ - members: (guildId: BigString, options?: ListGuildMembers) => string + members: (guildId: BigString, options?: ListGuildMembers) => string; /** Route for handling member searching in a guild. */ - search: (guildId: BigString, query: string, options?: { limit?: number }) => string + search: (guildId: BigString, query: string, options?: { limit?: number }) => string; /** Route for handling pruning guild members. */ - prune: (guildId: BigString, options?: GetGuildPruneCountQuery) => string - } + prune: (guildId: BigString, options?: GetGuildPruneCountQuery) => string; + }; /** Routes for handling a guild's templates. */ templates: { /** Route for handling a specifc guild's templates with a code only. */ - code: (code: string) => string + code: (code: string) => string; /** Route for handling a specific guild's template with a guild id and code. */ - guild: (guildId: BigString, code: string) => string + guild: (guildId: BigString, code: string) => string; /** Route for handling non-specific guild's templates. */ - all: (guildId: BigString) => string - } + all: (guildId: BigString) => string; + }; /** Route for handling a guild's vanity url. */ - vanity: (guildId: BigString) => string + vanity: (guildId: BigString) => string; /** Route for handling a guild's regions. */ - regions: (guildId: BigString) => string + regions: (guildId: BigString) => string; /** Routes for handling a guild's roles. */ roles: { /** Route for handling a specific guild role. */ - one: (guildId: BigString, roleId: BigString) => string + one: (guildId: BigString, roleId: BigString) => string; /** Route for handling a guild's roles. */ - all: (guildId: BigString) => string + all: (guildId: BigString) => string; /** Route for handling a members roles in a guild. */ - member: (guildId: BigString, memberId: BigString, roleId: BigString) => string + member: (guildId: BigString, memberId: BigString, roleId: BigString) => string; /** Route for the role member counts */ - memberCounts: (guildId: BigString) => string - } + memberCounts: (guildId: BigString) => string; + }; /** Route for handling a specific guild sticker. */ - stickers: (guildId: BigString) => string + stickers: (guildId: BigString) => string; /** Route for handling non-specific guild stickers. */ - sticker: (guildId: BigString, stickerId: BigString) => string + sticker: (guildId: BigString, stickerId: BigString) => string; /** Route for handling a voice state. */ - voice: (guildId: BigString, userId?: BigString) => string + voice: (guildId: BigString, userId?: BigString) => string; /** Route for the onboarding */ - onboarding: (guildId: BigString) => string + onboarding: (guildId: BigString) => string; /** Route for guild incident actions */ - incidentActions: (guildId: BigString) => string - } + incidentActions: (guildId: BigString) => string; + }; /** Routes for interaction related endpoints. */ interactions: { /** Routes for interaction command related endpoints. */ commands: { /** Route for non-specific commands. */ - commands: (applicationId: BigString, withLocalizations?: boolean) => string + commands: (applicationId: BigString, withLocalizations?: boolean) => string; /** Route for guild related commands. */ guilds: { /** Route for non-specific guild commands. */ - all: (applicationId: BigString, guildId: BigString, withLocalizations?: boolean) => string + all: (applicationId: BigString, guildId: BigString, withLocalizations?: boolean) => string; /** Route for a specific guild command. */ - one: (applicationId: BigString, guildId: BigString, commandId: BigString) => string - } + one: (applicationId: BigString, guildId: BigString, commandId: BigString) => string; + }; /** Route for non-specific command permissions. */ - permissions: (applicationId: BigString, guildId: BigString) => string + permissions: (applicationId: BigString, guildId: BigString) => string; /** Route for a specific command's permission. */ - permission: (applicationId: BigString, guildId: BigString, commandId: BigString) => string + permission: (applicationId: BigString, guildId: BigString, commandId: BigString) => string; /** Route for a specific command. */ - command: (applicationId: BigString, commandId: BigString, withLocalizations?: boolean) => string - } + command: (applicationId: BigString, commandId: BigString, withLocalizations?: boolean) => string; + }; /** Routes for interaction response related endpoints. */ responses: { /** Route for handling a callback response with id and token. */ - callback: (interactionId: BigString, token: string, options?: InteractionCallbackOptions) => string + callback: (interactionId: BigString, token: string, options?: InteractionCallbackOptions) => string; /** Route for handling the original response using id and token. */ - original: (interactionId: BigString, token: string) => string + original: (interactionId: BigString, token: string) => string; /** Route for handling a followup message from a interaction response. */ - message: (applicationId: BigString, token: string, messageId: BigString) => string - } - } + message: (applicationId: BigString, token: string, messageId: BigString) => string; + }; + }; /** Routes related to OAuth2 */ oauth2: { /** Route to generate a new access token */ - tokenExchange: () => string + tokenExchange: () => string; /** Route to revoke an OAuth2 access_token */ - tokenRevoke: () => string + tokenRevoke: () => string; /** Route to get information about the current authorization. Requires an access token */ - currentAuthorization: () => string + currentAuthorization: () => string; /** Route to get information about the current application. */ - application: () => string + application: () => string; /** Route to get the connection the user has. Requires the `connections` OAuth2 scope */ - connections: () => string + connections: () => string; /** Route to handling role-connection for an application */ - roleConnections: (applicationId: BigString) => string - } + roleConnections: (applicationId: BigString) => string; + }; /** Routes related to monetization (entitlements and SKU) */ monetization: { /** Route to list / create entitlements */ - entitlements: (applicationId: BigString, options?: GetEntitlements) => string + entitlements: (applicationId: BigString, options?: GetEntitlements) => string; /** Route to delete an entitlement */ - entitlement: (applicationId: BigString, entitlementId: BigString) => string + entitlement: (applicationId: BigString, entitlementId: BigString) => string; /** Route to consume an entitlement */ - consumeEntitlement: (applicationId: BigString, entitlementId: BigString) => string + consumeEntitlement: (applicationId: BigString, entitlementId: BigString) => string; /** Route to list the SKUs */ - skus: (applicationId: BigString) => string + skus: (applicationId: BigString) => string; /** Route to list the SKU subscriptions */ - subscriptions: (skuId: BigString, options?: ListSkuSubscriptionsOptions) => string + subscriptions: (skuId: BigString, options?: ListSkuSubscriptionsOptions) => string; /** Route to get a SKU subscription */ - subscription: (skuId: BigString, subscriptionId: BigString) => string - } + subscription: (skuId: BigString, subscriptionId: BigString) => string; + }; /** Routes related to soundboard sounds */ soundboard: { /** Send a soundboard sound to a voice channel the user is connected to. */ - sendSound: (channelId: BigString) => string + sendSound: (channelId: BigString) => string; /** List the discord default soundboard sounds */ - listDefault: () => string + listDefault: () => string; /** Route for list/create a guild sounds */ - guildSounds: (guildId: BigString) => string + guildSounds: (guildId: BigString) => string; /** Route for get/edit/delete of a guild sound */ - guildSound: (guildId: BigString, soundId: BigString) => string - } + guildSound: (guildId: BigString, soundId: BigString) => string; + }; /** Routes realted to lobbies */ lobby: { /** Route to create a lobby */ - create: () => string + create: () => string; /** Route to get a specific lobby */ - lobby: (lobbyId: BigString) => string + lobby: (lobbyId: BigString) => string; /** Route to add/remove a member from a lobby */ - member: (lobbyId: BigString, userId: BigString) => string + member: (lobbyId: BigString, userId: BigString) => string; /** Route to leave a lobby */ - leave: (lobbyId: BigString) => string + leave: (lobbyId: BigString) => string; /** Route to link a lobby */ - link: (lobbyId: BigString) => string - } + link: (lobbyId: BigString) => string; + }; /** Route to list / create an application emoji */ - applicationEmojis: (applicationId: BigString) => string + applicationEmojis: (applicationId: BigString) => string; /** Route to list / update application role connection metadata records */ - applicationRoleConnectionMetadata: (applicationId: BigString) => string + applicationRoleConnectionMetadata: (applicationId: BigString) => string; /** Route to get / edit / delete an application emoji */ - applicationEmoji: (applicationId: BigString, emojiId: BigString) => string + applicationEmoji: (applicationId: BigString, emojiId: BigString) => string; /** Get information about the current OAuth2 user / bot user. If used with a OAuth2 token requires the `identify` OAuth2 scope */ - currentUser: () => string + currentUser: () => string; /** Route to get and edit information about the current application. */ - application: () => string + application: () => string; /** Route for get an activity instance */ - applicationActivityInstance: (applicationId: BigString, instanceId: string) => string + applicationActivityInstance: (applicationId: BigString, instanceId: string) => string; /** Route for handling a sticker. */ - sticker: (stickerId: BigString) => string + sticker: (stickerId: BigString) => string; /** Route for handling all voice regions. */ - regions: () => string + regions: () => string; } diff --git a/packages/rest/tests/constants.ts b/packages/rest/tests/constants.ts index 9420cf0e9..1b2870672 100644 --- a/packages/rest/tests/constants.ts +++ b/packages/rest/tests/constants.ts @@ -1,3 +1,3 @@ -import { Buffer } from 'node:buffer' +import { Buffer } from 'node:buffer'; -export const fakeToken = `${Buffer.from('1033452747380494366').toString('base64')}.zawsxedcrftvgybhu` +export const fakeToken = `${Buffer.from('1033452747380494366').toString('base64')}.zawsxedcrftvgybhu`; diff --git a/packages/rest/tests/e2e/automod.spec.ts b/packages/rest/tests/e2e/automod.spec.ts index 340c2c8b0..b5fca6021 100644 --- a/packages/rest/tests/e2e/automod.spec.ts +++ b/packages/rest/tests/e2e/automod.spec.ts @@ -1,6 +1,6 @@ -import { AutoModerationActionType, AutoModerationEventTypes, AutoModerationTriggerTypes } from '@discordeno/types' -import { expect } from 'chai' -import { e2eCache, rest, toDispose } from './utils.js' +import { AutoModerationActionType, AutoModerationEventTypes, AutoModerationTriggerTypes } from '@discordeno/types'; +import { expect } from 'chai'; +import { e2eCache, rest, toDispose } from './utils.js'; describe('Automod tests', () => { it('Create a MessageSend rule for Keyword with BlockMessage action.', async () => { @@ -16,22 +16,22 @@ describe('Automod tests', () => { type: AutoModerationActionType.BlockMessage, }, ], - }) - toDispose.add(async () => await rest.deleteAutomodRule(e2eCache.guild.id, rule.id)) + }); + toDispose.add(async () => await rest.deleteAutomodRule(e2eCache.guild.id, rule.id)); - const fetchedRule = await rest.getAutomodRule(e2eCache.guild.id, rule.id) + const fetchedRule = await rest.getAutomodRule(e2eCache.guild.id, rule.id); - expect(rule.id).to.be.exist - expect(fetchedRule.id).to.be.exist - expect(fetchedRule.id).to.equal(rule.id) - expect(fetchedRule.name).to.equal(rule.name) - expect(fetchedRule.eventType).to.equal(AutoModerationEventTypes.MessageSend) - expect(fetchedRule.triggerType).to.equal(AutoModerationTriggerTypes.Keyword) - expect(fetchedRule.triggerMetadata?.keywordFilter?.[0]).to.equal('iblamewolf') - expect(fetchedRule.actions).to.be.exist - expect(fetchedRule.actions[0]).to.be.exist - expect(fetchedRule.actions[0].type).to.equal(AutoModerationActionType.BlockMessage) - }) + expect(rule.id).to.be.exist; + expect(fetchedRule.id).to.be.exist; + expect(fetchedRule.id).to.equal(rule.id); + expect(fetchedRule.name).to.equal(rule.name); + expect(fetchedRule.eventType).to.equal(AutoModerationEventTypes.MessageSend); + expect(fetchedRule.triggerType).to.equal(AutoModerationTriggerTypes.Keyword); + expect(fetchedRule.triggerMetadata?.keywordFilter?.[0]).to.equal('iblamewolf'); + expect(fetchedRule.actions).to.be.exist; + expect(fetchedRule.actions[0]).to.be.exist; + expect(fetchedRule.actions[0].type).to.equal(AutoModerationActionType.BlockMessage); + }); it('Create a MessageSend rule for Keyword with Timeout action.', async () => { const rule = await rest.createAutomodRule(e2eCache.guild.id, { @@ -49,23 +49,23 @@ describe('Automod tests', () => { }, }, ], - }) - toDispose.add(async () => await rest.deleteAutomodRule(e2eCache.guild.id, rule.id)) + }); + toDispose.add(async () => await rest.deleteAutomodRule(e2eCache.guild.id, rule.id)); - const fetchedRule = await rest.getAutomodRule(e2eCache.guild.id, rule.id) + const fetchedRule = await rest.getAutomodRule(e2eCache.guild.id, rule.id); - expect(rule.id).to.be.exist - expect(fetchedRule.id).to.be.exist - expect(fetchedRule.id).to.equal(rule.id) - expect(fetchedRule.name).to.equal(rule.name) - expect(fetchedRule.eventType).to.equal(AutoModerationEventTypes.MessageSend) - expect(fetchedRule.triggerType).to.equal(AutoModerationTriggerTypes.Keyword) - expect(fetchedRule.triggerMetadata?.keywordFilter?.[0]).to.equal('iblamewolf') - expect(fetchedRule.actions).to.be.exist - expect(fetchedRule.actions[0]).to.be.exist - expect(fetchedRule.actions[0].type).to.equal(AutoModerationActionType.Timeout) - expect(fetchedRule.actions[0].metadata?.durationSeconds).to.equal(10) - }) + expect(rule.id).to.be.exist; + expect(fetchedRule.id).to.be.exist; + expect(fetchedRule.id).to.equal(rule.id); + expect(fetchedRule.name).to.equal(rule.name); + expect(fetchedRule.eventType).to.equal(AutoModerationEventTypes.MessageSend); + expect(fetchedRule.triggerType).to.equal(AutoModerationTriggerTypes.Keyword); + expect(fetchedRule.triggerMetadata?.keywordFilter?.[0]).to.equal('iblamewolf'); + expect(fetchedRule.actions).to.be.exist; + expect(fetchedRule.actions[0]).to.be.exist; + expect(fetchedRule.actions[0].type).to.equal(AutoModerationActionType.Timeout); + expect(fetchedRule.actions[0].metadata?.durationSeconds).to.equal(10); + }); it('Create a MessageSend rule for Keyword with BlockMessage & Timeout action.', async () => { const rule = await rest.createAutomodRule(e2eCache.guild.id, { @@ -86,23 +86,23 @@ describe('Automod tests', () => { }, }, ], - }) - toDispose.add(async () => await rest.deleteAutomodRule(e2eCache.guild.id, rule.id)) + }); + toDispose.add(async () => await rest.deleteAutomodRule(e2eCache.guild.id, rule.id)); - const fetchedRule = await rest.getAutomodRule(e2eCache.guild.id, rule.id) + const fetchedRule = await rest.getAutomodRule(e2eCache.guild.id, rule.id); - expect(rule.id).to.be.exist - expect(fetchedRule.id).to.be.exist - expect(fetchedRule.id).to.equal(rule.id) - expect(fetchedRule.name).to.equal(rule.name) - expect(fetchedRule.eventType).to.equal(AutoModerationEventTypes.MessageSend) - expect(fetchedRule.triggerType).to.equal(AutoModerationTriggerTypes.Keyword) - expect(fetchedRule.triggerMetadata?.keywordFilter?.[0]).to.equal('iblamewolf') - expect(fetchedRule.actions).to.have.length(2) - expect(fetchedRule.actions[0].type).to.equal(AutoModerationActionType.BlockMessage) - expect(fetchedRule.actions[1].type).to.equal(AutoModerationActionType.Timeout) - expect(fetchedRule.actions[1].metadata?.durationSeconds).to.equal(10) - }) + expect(rule.id).to.be.exist; + expect(fetchedRule.id).to.be.exist; + expect(fetchedRule.id).to.equal(rule.id); + expect(fetchedRule.name).to.equal(rule.name); + expect(fetchedRule.eventType).to.equal(AutoModerationEventTypes.MessageSend); + expect(fetchedRule.triggerType).to.equal(AutoModerationTriggerTypes.Keyword); + expect(fetchedRule.triggerMetadata?.keywordFilter?.[0]).to.equal('iblamewolf'); + expect(fetchedRule.actions).to.have.length(2); + expect(fetchedRule.actions[0].type).to.equal(AutoModerationActionType.BlockMessage); + expect(fetchedRule.actions[1].type).to.equal(AutoModerationActionType.Timeout); + expect(fetchedRule.actions[1].metadata?.durationSeconds).to.equal(10); + }); describe('with a channel', () => { it('Create a MessageSend rule for Keyword with SendAlertMessage action.', async () => { @@ -121,23 +121,23 @@ describe('Automod tests', () => { }, }, ], - }) - toDispose.add(async () => await rest.deleteAutomodRule(e2eCache.guild.id, rule.id)) + }); + toDispose.add(async () => await rest.deleteAutomodRule(e2eCache.guild.id, rule.id)); - const fetchedRule = await rest.getAutomodRule(e2eCache.guild.id, rule.id) + const fetchedRule = await rest.getAutomodRule(e2eCache.guild.id, rule.id); - expect(rule.id).to.be.exist - expect(fetchedRule.id).to.be.exist - expect(fetchedRule.id).to.equal(rule.id) - expect(fetchedRule.name).to.equal(rule.name) - expect(fetchedRule.eventType).to.equal(AutoModerationEventTypes.MessageSend) - expect(fetchedRule.triggerType).to.equal(AutoModerationTriggerTypes.Keyword) - expect(fetchedRule.triggerMetadata?.keywordFilter?.[0]).to.equal('iblamewolf') - expect(fetchedRule.actions).to.be.exist - expect(fetchedRule.actions[0]).to.be.exist - expect(fetchedRule.actions[0].type).to.equal(AutoModerationActionType.SendAlertMessage) - expect(fetchedRule.actions[0].metadata?.channelId).to.equal(e2eCache.channel.id) - }) + expect(rule.id).to.be.exist; + expect(fetchedRule.id).to.be.exist; + expect(fetchedRule.id).to.equal(rule.id); + expect(fetchedRule.name).to.equal(rule.name); + expect(fetchedRule.eventType).to.equal(AutoModerationEventTypes.MessageSend); + expect(fetchedRule.triggerType).to.equal(AutoModerationTriggerTypes.Keyword); + expect(fetchedRule.triggerMetadata?.keywordFilter?.[0]).to.equal('iblamewolf'); + expect(fetchedRule.actions).to.be.exist; + expect(fetchedRule.actions[0]).to.be.exist; + expect(fetchedRule.actions[0].type).to.equal(AutoModerationActionType.SendAlertMessage); + expect(fetchedRule.actions[0].metadata?.channelId).to.equal(e2eCache.channel.id); + }); it('Create a MessageSend rule for Keyword with SendAlertMessage & Timeout action.', async () => { const rule = await rest.createAutomodRule(e2eCache.guild.id, { @@ -161,25 +161,25 @@ describe('Automod tests', () => { }, }, ], - }) - toDispose.add(async () => await rest.deleteAutomodRule(e2eCache.guild.id, rule.id)) + }); + toDispose.add(async () => await rest.deleteAutomodRule(e2eCache.guild.id, rule.id)); - const fetchedRule = await rest.getAutomodRule(e2eCache.guild.id, rule.id) + const fetchedRule = await rest.getAutomodRule(e2eCache.guild.id, rule.id); - expect(rule.id).to.be.exist - expect(fetchedRule.id).to.be.exist - expect(fetchedRule.id).to.equal(rule.id) - expect(fetchedRule.name).to.equal(rule.name) - expect(fetchedRule.eventType).to.equal(AutoModerationEventTypes.MessageSend) - expect(fetchedRule.triggerType).to.equal(AutoModerationTriggerTypes.Keyword) - expect(fetchedRule.triggerMetadata?.keywordFilter?.[0]).to.equal('iblamewolf') - expect(fetchedRule.actions).to.have.length(2) - expect(fetchedRule.actions[0]).to.be.exist - expect(fetchedRule.actions[0].type).to.equal(AutoModerationActionType.SendAlertMessage) - expect(fetchedRule.actions[0].metadata?.channelId).to.equal(e2eCache.channel.id) - expect(fetchedRule.actions[1].type).to.equal(AutoModerationActionType.Timeout) - expect(fetchedRule.actions[1].metadata?.durationSeconds).to.equal(10) - }) + expect(rule.id).to.be.exist; + expect(fetchedRule.id).to.be.exist; + expect(fetchedRule.id).to.equal(rule.id); + expect(fetchedRule.name).to.equal(rule.name); + expect(fetchedRule.eventType).to.equal(AutoModerationEventTypes.MessageSend); + expect(fetchedRule.triggerType).to.equal(AutoModerationTriggerTypes.Keyword); + expect(fetchedRule.triggerMetadata?.keywordFilter?.[0]).to.equal('iblamewolf'); + expect(fetchedRule.actions).to.have.length(2); + expect(fetchedRule.actions[0]).to.be.exist; + expect(fetchedRule.actions[0].type).to.equal(AutoModerationActionType.SendAlertMessage); + expect(fetchedRule.actions[0].metadata?.channelId).to.equal(e2eCache.channel.id); + expect(fetchedRule.actions[1].type).to.equal(AutoModerationActionType.Timeout); + expect(fetchedRule.actions[1].metadata?.durationSeconds).to.equal(10); + }); it('Create a MessageSend rule for Keyword with BlockMessage & SendAlertMessage & Timeout action.', async () => { const rule = await rest.createAutomodRule(e2eCache.guild.id, { @@ -206,28 +206,28 @@ describe('Automod tests', () => { }, }, ], - }) - toDispose.add(async () => await rest.deleteAutomodRule(e2eCache.guild.id, rule.id)) + }); + toDispose.add(async () => await rest.deleteAutomodRule(e2eCache.guild.id, rule.id)); // Get the rule again to make sure it was created correctly - const fetchedRule = await rest.getAutomodRule(e2eCache.guild.id, rule.id) + const fetchedRule = await rest.getAutomodRule(e2eCache.guild.id, rule.id); - expect(rule.id).to.be.exist - expect(fetchedRule.id).to.be.exist - expect(fetchedRule.id).to.equal(rule.id) - expect(fetchedRule.name).to.equal(rule.name) - expect(fetchedRule.eventType).to.equal(AutoModerationEventTypes.MessageSend) - expect(fetchedRule.triggerType).to.equal(AutoModerationTriggerTypes.Keyword) - expect(fetchedRule.triggerMetadata?.keywordFilter?.[0]).to.equal('iblamewolf') - expect(fetchedRule.actions).to.be.exist - expect(fetchedRule.actions[0]).to.be.exist - expect(fetchedRule.actions[1].metadata).to.be.exist - expect(fetchedRule.actions[2].metadata).to.be.exist - expect(fetchedRule.actions[1].metadata?.channelId).to.equal(e2eCache.channel.id) - expect(fetchedRule.actions[2].metadata?.durationSeconds).to.equal(10) - expect(fetchedRule.actions[0].type).to.equal(AutoModerationActionType.BlockMessage) - expect(fetchedRule.actions[1].type).to.equal(AutoModerationActionType.SendAlertMessage) - expect(fetchedRule.actions[2].type).to.equal(AutoModerationActionType.Timeout) - }) - }) -}) + expect(rule.id).to.be.exist; + expect(fetchedRule.id).to.be.exist; + expect(fetchedRule.id).to.equal(rule.id); + expect(fetchedRule.name).to.equal(rule.name); + expect(fetchedRule.eventType).to.equal(AutoModerationEventTypes.MessageSend); + expect(fetchedRule.triggerType).to.equal(AutoModerationTriggerTypes.Keyword); + expect(fetchedRule.triggerMetadata?.keywordFilter?.[0]).to.equal('iblamewolf'); + expect(fetchedRule.actions).to.be.exist; + expect(fetchedRule.actions[0]).to.be.exist; + expect(fetchedRule.actions[1].metadata).to.be.exist; + expect(fetchedRule.actions[2].metadata).to.be.exist; + expect(fetchedRule.actions[1].metadata?.channelId).to.equal(e2eCache.channel.id); + expect(fetchedRule.actions[2].metadata?.durationSeconds).to.equal(10); + expect(fetchedRule.actions[0].type).to.equal(AutoModerationActionType.BlockMessage); + expect(fetchedRule.actions[1].type).to.equal(AutoModerationActionType.SendAlertMessage); + expect(fetchedRule.actions[2].type).to.equal(AutoModerationActionType.Timeout); + }); + }); +}); diff --git a/packages/rest/tests/e2e/constants.ts b/packages/rest/tests/e2e/constants.ts index fb4a97e32..2fe3ca94e 100644 --- a/packages/rest/tests/e2e/constants.ts +++ b/packages/rest/tests/e2e/constants.ts @@ -1,9 +1,9 @@ -import dotenv from 'dotenv' +import dotenv from 'dotenv'; -dotenv.config({ path: '../../.env', quiet: true }) +dotenv.config({ path: '../../.env', quiet: true }); -export const token = process.env.DISCORD_TOKEN! -if (!token) throw new Error('Token was not provided.') +export const token = process.env.DISCORD_TOKEN!; +if (!token) throw new Error('Token was not provided.'); -export const E2E_TEST_GUILD_ID = process.env.E2E_TEST_GUILD_ID! -if (!E2E_TEST_GUILD_ID) throw new Error('COMMUNITY guild id was not provided.') +export const E2E_TEST_GUILD_ID = process.env.E2E_TEST_GUILD_ID!; +if (!E2E_TEST_GUILD_ID) throw new Error('COMMUNITY guild id was not provided.'); diff --git a/packages/rest/tests/e2e/emoji.spec.ts b/packages/rest/tests/e2e/emoji.spec.ts index 15ffb9822..96c057b9e 100644 --- a/packages/rest/tests/e2e/emoji.spec.ts +++ b/packages/rest/tests/e2e/emoji.spec.ts @@ -1,11 +1,11 @@ -import type { Camelize, DiscordEmoji } from '@discordeno/types' -import { urlToBase64 } from '@discordeno/utils' -import { use as chaiUse, expect } from 'chai' -import chaiAsPromised from 'chai-as-promised' -import { describe, it } from 'mocha' -import { e2eCache, rest, toDispose } from './utils.js' +import type { Camelize, DiscordEmoji } from '@discordeno/types'; +import { urlToBase64 } from '@discordeno/utils'; +import { use as chaiUse, expect } from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +import { describe, it } from 'mocha'; +import { e2eCache, rest, toDispose } from './utils.js'; -chaiUse(chaiAsPromised) +chaiUse(chaiAsPromised); describe('Create and delete emojis', () => { it('create an emoji', async () => { @@ -13,13 +13,13 @@ describe('Create and delete emojis', () => { name: 'blamewolf', image: await urlToBase64('https://cdn.discordapp.com/emojis/814955268123000832.png'), roles: [], - }) + }); - toDispose.add(async () => await rest.deleteEmoji(e2eCache.guild.id, emoji.id!)) + toDispose.add(async () => await rest.deleteEmoji(e2eCache.guild.id, emoji.id!)); // Assertions - expect(emoji.id).to.exist - }) + expect(emoji.id).to.exist; + }); // delete an emoji without a reason it('delete an emoji without a reason', async () => { @@ -27,19 +27,19 @@ describe('Create and delete emojis', () => { name: 'blamewolf', image: await urlToBase64('https://cdn.discordapp.com/emojis/814955268123000832.png'), roles: [], - }) - const cleanEmoji = async () => await rest.deleteEmoji(e2eCache.guild.id, emoji.id!) - toDispose.add(cleanEmoji) + }); + const cleanEmoji = async () => await rest.deleteEmoji(e2eCache.guild.id, emoji.id!); + toDispose.add(cleanEmoji); // Assertions - expect(emoji.id).to.exist + expect(emoji.id).to.exist; - await rest.deleteEmoji(e2eCache.guild.id, emoji.id!) + await rest.deleteEmoji(e2eCache.guild.id, emoji.id!); // Remove from toDispose since we already deleted it - toDispose.delete(cleanEmoji) + toDispose.delete(cleanEmoji); - await expect(rest.getEmoji(e2eCache.guild.id, emoji.id!)).to.eventually.rejected - }) + await expect(rest.getEmoji(e2eCache.guild.id, emoji.id!)).to.eventually.rejected; + }); // delete an emoji with a reason it('delete an emoji with a reason', async () => { @@ -47,79 +47,79 @@ describe('Create and delete emojis', () => { name: 'blamewolf', image: await urlToBase64('https://cdn.discordapp.com/emojis/814955268123000832.png'), roles: [], - }) - const cleanEmoji = async () => await rest.deleteEmoji(e2eCache.guild.id, emoji.id!) - toDispose.add(cleanEmoji) + }); + const cleanEmoji = async () => await rest.deleteEmoji(e2eCache.guild.id, emoji.id!); + toDispose.add(cleanEmoji); // Assertions - expect(emoji.id).to.exist + expect(emoji.id).to.exist; - await rest.deleteEmoji(e2eCache.guild.id, emoji.id!, 'with a reason') + await rest.deleteEmoji(e2eCache.guild.id, emoji.id!, 'with a reason'); // Remove from toDispose since we already deleted it - toDispose.delete(cleanEmoji) + toDispose.delete(cleanEmoji); - await expect(rest.getEmoji(e2eCache.guild.id, emoji.id!)).to.eventually.rejected - }) -}) + await expect(rest.getEmoji(e2eCache.guild.id, emoji.id!)).to.eventually.rejected; + }); +}); describe('Edit and get emojis', () => { - let emoji: Camelize & { id: string } + let emoji: Camelize & { id: string }; beforeEach(async () => { emoji = (await rest.createEmoji(e2eCache.guild.id, { name: 'blamewolf', image: await urlToBase64('https://cdn.discordapp.com/emojis/814955268123000832.png'), roles: [], - })) as Camelize & { id: string } + })) as Camelize & { id: string }; - toDispose.add(async () => await rest.deleteEmoji(e2eCache.guild.id, emoji.id)) - }) + toDispose.add(async () => await rest.deleteEmoji(e2eCache.guild.id, emoji.id)); + }); // edit an emoji name it('Edit an emoji name', async () => { await rest.editEmoji(e2eCache.guild.id, emoji.id, { name: 'edited', - }) + }); - const edited = await rest.getEmoji(e2eCache.guild.id, emoji.id) - expect(edited.name).to.equal('edited') - }) + const edited = await rest.getEmoji(e2eCache.guild.id, emoji.id); + expect(edited.name).to.equal('edited'); + }); // edit an emoji roles it("Edit an emoji's roles", async () => { const role = await rest.createRole(e2eCache.guild.id, { name: 'dd-test-emoji', - }) - toDispose.add(async () => await rest.deleteRole(e2eCache.guild.id, role.id)) + }); + toDispose.add(async () => await rest.deleteRole(e2eCache.guild.id, role.id)); await rest.editEmoji(e2eCache.guild.id, emoji.id, { roles: [role.id], - }) + }); - const edited = await rest.getEmoji(e2eCache.guild.id, emoji.id) - expect(edited.roles?.length).to.equal(1) - }) + const edited = await rest.getEmoji(e2eCache.guild.id, emoji.id); + expect(edited.roles?.length).to.equal(1); + }); // get an emoji it('get an emoji', async () => { - const exists = await rest.getEmoji(e2eCache.guild.id, emoji.id) + const exists = await rest.getEmoji(e2eCache.guild.id, emoji.id); - expect(exists.id).to.be.exist - expect(emoji.id).to.equal(exists.id) - }) + expect(exists.id).to.be.exist; + expect(emoji.id).to.equal(exists.id); + }); it('get all guild emojis', async () => { const newEmoji = await rest.createEmoji(e2eCache.guild.id, { name: 'blamewolf2', image: await urlToBase64('https://cdn.discordapp.com/emojis/814955268123000832.png'), roles: [], - }) - toDispose.add(async () => await rest.deleteEmoji(e2eCache.guild.id, newEmoji.id!)) + }); + toDispose.add(async () => await rest.deleteEmoji(e2eCache.guild.id, newEmoji.id!)); - const exists = await rest.getEmojis(e2eCache.guild.id) + const exists = await rest.getEmojis(e2eCache.guild.id); - expect(exists.length).to.greaterThan(1) - expect(exists.find((x) => x.id === newEmoji.id)).to.exist - expect(exists.find((x) => x.id === emoji.id)).to.exist - }) -}) + expect(exists.length).to.greaterThan(1); + expect(exists.find((x) => x.id === newEmoji.id)).to.exist; + expect(exists.find((x) => x.id === emoji.id)).to.exist; + }); +}); diff --git a/packages/rest/tests/e2e/guild.spec.ts b/packages/rest/tests/e2e/guild.spec.ts index a82a34cfc..98fd7f623 100644 --- a/packages/rest/tests/e2e/guild.spec.ts +++ b/packages/rest/tests/e2e/guild.spec.ts @@ -1,86 +1,86 @@ -import { ChannelTypes } from '@discordeno/types' -import { use as chaiUse, expect } from 'chai' -import chaiAsPromised from 'chai-as-promised' -import { describe, it } from 'mocha' -import { e2eCache, rest, toDispose } from './utils.js' +import { ChannelTypes } from '@discordeno/types'; +import { use as chaiUse, expect } from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +import { describe, it } from 'mocha'; +import { e2eCache, rest, toDispose } from './utils.js'; -chaiUse(chaiAsPromised) +chaiUse(chaiAsPromised); describe('Manage Guilds', () => { it('Get a guild', async () => { - const exists = await rest.getGuild(e2eCache.guildId) - expect(exists).to.be.exist - expect(exists.id).to.be.exist - expect(exists.name).to.equal(e2eCache.guild.name) - }) + const exists = await rest.getGuild(e2eCache.guildId); + expect(exists).to.be.exist; + expect(exists.id).to.be.exist; + expect(exists.name).to.equal(e2eCache.guild.name); + }); it('AFK channel', async () => { // Prepare the AFK channel const voiceChannel = await rest.createChannel(e2eCache.guild.id, { name: 'e2e-afk-channel', type: ChannelTypes.GuildVoice, - }) - toDispose.add(async () => await rest.deleteChannel(voiceChannel.id)) + }); + toDispose.add(async () => await rest.deleteChannel(voiceChannel.id)); - expect(voiceChannel.id).to.be.exist + expect(voiceChannel.id).to.be.exist; // Set the AFK channel const edited = await rest.editGuild(e2eCache.guild.id, { afkChannelId: voiceChannel.id, - }) + }); - expect(e2eCache.guild.afkChannelId).to.not.equal(voiceChannel.id) - expect(edited.afkChannelId).to.equal(voiceChannel.id) - expect(edited.afkChannelId).to.not.be.null + expect(e2eCache.guild.afkChannelId).to.not.equal(voiceChannel.id); + expect(edited.afkChannelId).to.equal(voiceChannel.id); + expect(edited.afkChannelId).to.not.be.null; // Reset the AFK channel - const edited2 = await rest.editGuild(e2eCache.guild.id, { afkChannelId: null }) - expect(edited2.afkChannelId).to.be.null - }) + const edited2 = await rest.editGuild(e2eCache.guild.id, { afkChannelId: null }); + expect(edited2.afkChannelId).to.be.null; + }); it('Get audit logs', async () => { - const auditLogs = await rest.getAuditLog(e2eCache.guild.id, { limit: 1 }) - expect(auditLogs.auditLogEntries).to.have.lengthOf(1) - }) + const auditLogs = await rest.getAuditLog(e2eCache.guild.id, { limit: 1 }); + expect(auditLogs.auditLogEntries).to.have.lengthOf(1); + }); // Get available voice regions it('Get available voice regions', async () => { - const regions = await rest.getVoiceRegions(e2eCache.guild.id) - expect(regions).to.have.length.greaterThan(0) - }) + const regions = await rest.getVoiceRegions(e2eCache.guild.id); + expect(regions).to.have.length.greaterThan(0); + }); it('Banning members', async () => { // Ban members - await rest.banMember(e2eCache.guild.id, '379643682984296448', { deleteMessageSeconds: 604800 }, 'Blame Wolf') - await rest.banMember(e2eCache.guild.id, '416477607966670869') + await rest.banMember(e2eCache.guild.id, '379643682984296448', { deleteMessageSeconds: 604800 }, 'Blame Wolf'); + await rest.banMember(e2eCache.guild.id, '416477607966670869'); - const fetchedBan = await rest.getBan(e2eCache.guild.id, '379643682984296448') - const fetchedBans = await rest.getBans(e2eCache.guild.id) + const fetchedBan = await rest.getBan(e2eCache.guild.id, '379643682984296448'); + const fetchedBans = await rest.getBans(e2eCache.guild.id); // Assertions - expect(fetchedBan).to.be.exist - expect(fetchedBan.user.id).to.equal('379643682984296448') + expect(fetchedBan).to.be.exist; + expect(fetchedBan.user.id).to.equal('379643682984296448'); - expect(fetchedBans).to.be.exist - expect(fetchedBans.length).to.greaterThanOrEqual(2) + expect(fetchedBans).to.be.exist; + expect(fetchedBans.length).to.greaterThanOrEqual(2); // Unban members - await rest.unbanMember(e2eCache.guild.id, '416477607966670869') - await rest.unbanMember(e2eCache.guild.id, '379643682984296448') + await rest.unbanMember(e2eCache.guild.id, '416477607966670869'); + await rest.unbanMember(e2eCache.guild.id, '379643682984296448'); - const unbanned = await rest.getBans(e2eCache.guild.id) - expect(unbanned.length).to.equal(0) - }) + const unbanned = await rest.getBans(e2eCache.guild.id); + expect(unbanned.length).to.equal(0); + }); // Get vanity URL it('Get vanity URL', async () => { if (!e2eCache.guild.vanityUrlCode) { - await expect(rest.getVanityUrl(e2eCache.guild.id)).to.eventually.rejected - return + await expect(rest.getVanityUrl(e2eCache.guild.id)).to.eventually.rejected; + return; } - await expect(rest.getVanityUrl(e2eCache.guild.id)).to.eventually.fulfilled - }) + await expect(rest.getVanityUrl(e2eCache.guild.id)).to.eventually.fulfilled; + }); // Get a welcome screen // it('Get welcome screen', async () => { @@ -91,4 +91,4 @@ describe('Manage Guilds', () => { // }) // }) -}) +}); diff --git a/packages/rest/tests/e2e/member.spec.ts b/packages/rest/tests/e2e/member.spec.ts index 79e28db32..c9d7b142c 100644 --- a/packages/rest/tests/e2e/member.spec.ts +++ b/packages/rest/tests/e2e/member.spec.ts @@ -1,51 +1,51 @@ -import { use as chaiUse, expect } from 'chai' -import chaiAsPromised from 'chai-as-promised' -import { describe, it } from 'mocha' -import { e2eCache, rest } from './utils.js' +import { use as chaiUse, expect } from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +import { describe, it } from 'mocha'; +import { e2eCache, rest } from './utils.js'; -chaiUse(chaiAsPromised) +chaiUse(chaiAsPromised); describe('Member tests', () => { it("Fetches the bot and compares the bot's id with the fetched member's id", async () => { - const member = await rest.getMember(e2eCache.guildId, rest.applicationId) + const member = await rest.getMember(e2eCache.guildId, rest.applicationId); - expect(member?.user.id).to.exist - expect(member?.user.id).to.equal(rest.applicationId.toString()) - }) + expect(member?.user.id).to.exist; + expect(member?.user.id).to.equal(rest.applicationId.toString()); + }); it('Gets a member list and checks if the bot is in the member list', async () => { - const members = await rest.getMembers(e2eCache.guildId, { limit: 10 }) + const members = await rest.getMembers(e2eCache.guildId, { limit: 10 }); - expect(members.some((m) => m.user.id === rest.applicationId.toString())).to.equal(true) - }) + expect(members.some((m) => m.user.id === rest.applicationId.toString())).to.equal(true); + }); // fetch a single member by id it('Fetch a single member by id', async () => { - const member = await rest.getMember(e2eCache.guildId, rest.applicationId) + const member = await rest.getMember(e2eCache.guildId, rest.applicationId); - expect(member?.user.id).to.exist - }) + expect(member?.user.id).to.exist; + }); it("Edit a bot's nickname", async () => { - const nick = 'lts20050703' - const member = await rest.editBotMember(e2eCache.guildId, { nick }) - expect(member.nick).to.equal(nick) + const nick = 'lts20050703'; + const member = await rest.editBotMember(e2eCache.guildId, { nick }); + expect(member.nick).to.equal(nick); // Change nickname back - const member2 = await rest.editBotMember(e2eCache.guildId, { nick: null }) - expect(member2.nick).to.null - }) + const member2 = await rest.editBotMember(e2eCache.guildId, { nick: null }); + expect(member2.nick).to.null; + }); it('Send a direct message', async () => { // DM test only on dd unit testing bot - if (rest.applicationId.toString() !== '770381961553510451') return + if (rest.applicationId.toString() !== '770381961553510451') return; // Itoh Alt ID - const channel = await rest.getDmChannel(750661528360845322n) - expect(channel?.id).to.exist + const channel = await rest.getDmChannel(750661528360845322n); + expect(channel?.id).to.exist; const message = await rest.sendMessage(channel.id, { content: 'https://i.imgur.com/doG55NR.png', - }) - expect(message?.content).to.exist - }) -}) + }); + expect(message?.content).to.exist; + }); +}); diff --git a/packages/rest/tests/e2e/message.spec.ts b/packages/rest/tests/e2e/message.spec.ts index 8f6b34915..925ea141d 100644 --- a/packages/rest/tests/e2e/message.spec.ts +++ b/packages/rest/tests/e2e/message.spec.ts @@ -1,34 +1,34 @@ -import { processReactionString, urlToBase64 } from '@discordeno/utils' -import { expect } from 'chai' -import { describe, it } from 'mocha' -import { e2eCache, rest, toDispose } from './utils.js' +import { processReactionString, urlToBase64 } from '@discordeno/utils'; +import { expect } from 'chai'; +import { describe, it } from 'mocha'; +import { e2eCache, rest, toDispose } from './utils.js'; describe('Send a message', () => { it('With content', async () => { - const message = await rest.sendMessage(e2eCache.channel.id, { content: 'testing rate limit manager' }) + const message = await rest.sendMessage(e2eCache.channel.id, { content: 'testing rate limit manager' }); - expect(message.content).to.be.equal('testing rate limit manager') + expect(message.content).to.be.equal('testing rate limit manager'); - const edited = await rest.editMessage(message.channelId, message.id, { content: 'testing rate limit manager edited' }) + const edited = await rest.editMessage(message.channelId, message.id, { content: 'testing rate limit manager edited' }); - expect(message.content).to.be.not.equal(edited.content) + expect(message.content).to.be.not.equal(edited.content); - await rest.deleteMessage(message.channelId, message.id) - }) + await rest.deleteMessage(message.channelId, message.id); + }); it('With an image', async () => { const image = await fetch('https://cdn.discordapp.com/avatars/270010330782892032/d031ea881688526d1ae235fd2843e53c.jpg?size=2048') .then(async (res) => await res.blob()) - .catch(() => undefined) + .catch(() => undefined); - expect(image).to.not.be.undefined + expect(image).to.not.be.undefined; - const message = await rest.sendMessage(e2eCache.channel.id, { files: [{ blob: image!, name: 'gamer' }] }) - const [attachment] = message.attachments + const message = await rest.sendMessage(e2eCache.channel.id, { files: [{ blob: image!, name: 'gamer' }] }); + const [attachment] = message.attachments; - expect(message.attachments.length).to.be.greaterThan(0) - expect(attachment.filename).to.be.equal('gamer') - }) + expect(message.attachments.length).to.be.greaterThan(0); + expect(attachment.filename).to.be.equal('gamer'); + }); it('With a file attachment', async () => { const fileMsg = await rest.sendMessage(e2eCache.channel.id, { @@ -39,13 +39,13 @@ describe('Send a message', () => { blob: new Blob(['hello world'], { type: 'text/plain' }), }, ], - }) + }); - expect(fileMsg.id).not.equals(undefined) - expect(fileMsg.content).equals('222') - expect(fileMsg.attachments.length).equals(1) - expect(fileMsg.attachments.at(0)?.filename).equals('application.txt') - expect(fileMsg.attachments.at(0)?.size).equals(11) + expect(fileMsg.id).not.equals(undefined); + expect(fileMsg.content).equals('222'); + expect(fileMsg.attachments.length).equals(1); + expect(fileMsg.attachments.at(0)?.filename).equals('application.txt'); + expect(fileMsg.attachments.at(0)?.size).equals(11); const edited = await rest.editMessage(e2eCache.channel.id, fileMsg.id, { content: '222 edit', @@ -55,152 +55,152 @@ describe('Send a message', () => { blob: new Blob(['hello world edit'], { type: 'text/plain' }), }, ], - }) + }); - expect(edited.id).not.equals(undefined) - expect(edited.content).equals('222 edit') - expect(edited.attachments.length).equals(1) - expect(edited.attachments.at(0)?.filename).equals('application_edit.txt') - expect(edited.attachments.at(0)?.size).equals(16) - }) -}) + expect(edited.id).not.equals(undefined); + expect(edited.content).equals('222 edit'); + expect(edited.attachments.length).equals(1); + expect(edited.attachments.at(0)?.filename).equals('application_edit.txt'); + expect(edited.attachments.at(0)?.size).equals(16); + }); +}); describe('Manage reactions', () => { it('Add and delete a unicode reaction', async () => { - const message = await rest.sendMessage(e2eCache.channel.id, { content: 'add reaction test' }) - await rest.addReaction(message.channelId, message.id, '📙') + const message = await rest.sendMessage(e2eCache.channel.id, { content: 'add reaction test' }); + await rest.addReaction(message.channelId, message.id, '📙'); - const reacted = await rest.getMessage(message.channelId, message.id) - expect(reacted.reactions?.length).to.be.greaterThanOrEqual(1) + const reacted = await rest.getMessage(message.channelId, message.id); + expect(reacted.reactions?.length).to.be.greaterThanOrEqual(1); - await rest.deleteOwnReaction(message.channelId, message.id, '📙') - const unreacted = await rest.getMessage(message.channelId, message.id) + await rest.deleteOwnReaction(message.channelId, message.id, '📙'); + const unreacted = await rest.getMessage(message.channelId, message.id); // Use boolean comparison because when its 0 length discord sends undefined - expect(!!unreacted.reactions?.length).to.be.equal(false) - }) + expect(!!unreacted.reactions?.length).to.be.equal(false); + }); it('Add and delete a custom reaction', async () => { const emoji = await rest.createEmoji(e2eCache.guild.id, { name: 'discordeno', image: await urlToBase64('https://cdn.discordapp.com/emojis/785403373817823272.webp?size=96'), roles: [], - }) - toDispose.add(async () => await rest.deleteEmoji(e2eCache.guild.id, emoji.id!)) + }); + toDispose.add(async () => await rest.deleteEmoji(e2eCache.guild.id, emoji.id!)); - const emojiCode = `<:${emoji.name!}:${emoji.id!}>` + const emojiCode = `<:${emoji.name!}:${emoji.id!}>`; - const message = await rest.sendMessage(e2eCache.channel.id, { content: 'add reaction test' }) - await rest.addReaction(message.channelId, message.id, emojiCode) + const message = await rest.sendMessage(e2eCache.channel.id, { content: 'add reaction test' }); + await rest.addReaction(message.channelId, message.id, emojiCode); - const reacted = await rest.getMessage(message.channelId, message.id) - expect(reacted.reactions?.length).to.be.greaterThanOrEqual(1) + const reacted = await rest.getMessage(message.channelId, message.id); + expect(reacted.reactions?.length).to.be.greaterThanOrEqual(1); - const reactions = await rest.getReactions(e2eCache.channel.id, message.id, processReactionString(emojiCode)) - expect(reactions?.length).to.be.greaterThanOrEqual(1) + const reactions = await rest.getReactions(e2eCache.channel.id, message.id, processReactionString(emojiCode)); + expect(reactions?.length).to.be.greaterThanOrEqual(1); - await rest.deleteOwnReaction(message.channelId, message.id, emojiCode) - const unreacted = await rest.getMessage(message.channelId, message.id) + await rest.deleteOwnReaction(message.channelId, message.id, emojiCode); + const unreacted = await rest.getMessage(message.channelId, message.id); // Use boolean comparison because when its 0 length discord sends undefined - expect(!!unreacted.reactions?.length).to.be.equal(false) - }) + expect(!!unreacted.reactions?.length).to.be.equal(false); + }); it('Add several reactions with random order and delete all of them', async () => { const emoji = await rest.createEmoji(e2eCache.guild.id, { name: 'discordeno', image: await urlToBase64('https://cdn.discordapp.com/emojis/785403373817823272.webp?size=96'), roles: [], - }) - toDispose.add(async () => await rest.deleteEmoji(e2eCache.guild.id, emoji.id!)) + }); + toDispose.add(async () => await rest.deleteEmoji(e2eCache.guild.id, emoji.id!)); - const emojiCode = `<:${emoji.name!}:${emoji.id!}>` + const emojiCode = `<:${emoji.name!}:${emoji.id!}>`; - const message = await rest.sendMessage(e2eCache.channel.id, { content: 'add reaction test' }) - await rest.addReactions(message.channelId, message.id, [emojiCode, '📙']) + const message = await rest.sendMessage(e2eCache.channel.id, { content: 'add reaction test' }); + await rest.addReactions(message.channelId, message.id, [emojiCode, '📙']); - const reacted = await rest.getMessage(message.channelId, message.id) - expect(reacted.reactions?.length).to.be.greaterThanOrEqual(1) + const reacted = await rest.getMessage(message.channelId, message.id); + expect(reacted.reactions?.length).to.be.greaterThanOrEqual(1); - await rest.deleteReactionsAll(message.channelId, message.id) - const unreacted = await rest.getMessage(message.channelId, message.id) + await rest.deleteReactionsAll(message.channelId, message.id); + const unreacted = await rest.getMessage(message.channelId, message.id); // Use boolean comparison because when its 0 length discord sends undefined - expect(!!unreacted.reactions?.length).to.equal(false) - }) + expect(!!unreacted.reactions?.length).to.equal(false); + }); it('Add several reactions in an order and delete emoji reaction', async () => { const emoji = await rest.createEmoji(e2eCache.guild.id, { name: 'discordeno', image: await urlToBase64('https://cdn.discordapp.com/emojis/785403373817823272.webp?size=96'), roles: [], - }) - toDispose.add(async () => await rest.deleteEmoji(e2eCache.guild.id, emoji.id!)) + }); + toDispose.add(async () => await rest.deleteEmoji(e2eCache.guild.id, emoji.id!)); - const emojiCode = `<:${emoji.name!}:${emoji.id!}>` + const emojiCode = `<:${emoji.name!}:${emoji.id!}>`; - const message = await rest.sendMessage(e2eCache.channel.id, { content: 'add reaction test' }) - await rest.addReactions(message.channelId, message.id, [emojiCode, '📙'], true) + const message = await rest.sendMessage(e2eCache.channel.id, { content: 'add reaction test' }); + await rest.addReactions(message.channelId, message.id, [emojiCode, '📙'], true); - const reacted = await rest.getMessage(message.channelId, message.id) - expect(reacted.reactions?.length).to.be.greaterThanOrEqual(1) + const reacted = await rest.getMessage(message.channelId, message.id); + expect(reacted.reactions?.length).to.be.greaterThanOrEqual(1); - await rest.deleteReactionsEmoji(message.channelId, message.id, emojiCode) + await rest.deleteReactionsEmoji(message.channelId, message.id, emojiCode); - const unreacted = await rest.getMessage(message.channelId, message.id) - expect(unreacted.reactions?.length).to.greaterThanOrEqual(1) + const unreacted = await rest.getMessage(message.channelId, message.id); + expect(unreacted.reactions?.length).to.greaterThanOrEqual(1); - await rest.deleteUserReaction(message.channelId, message.id, rest.applicationId.toString(), '📙') - const noreacted = await rest.getMessage(message.channelId, message.id) + await rest.deleteUserReaction(message.channelId, message.id, rest.applicationId.toString(), '📙'); + const noreacted = await rest.getMessage(message.channelId, message.id); // Use boolean comparison because when its 0 length discord sends undefined - expect(!!noreacted.reactions?.length).to.equal(false) - }) -}) + expect(!!noreacted.reactions?.length).to.equal(false); + }); +}); describe('Manage pins', () => { it('Pin, get, and unpin messages', async () => { - const message = await rest.sendMessage(e2eCache.channel.id, { content: 'pin me' }) - const message2 = await rest.sendMessage(e2eCache.channel.id, { content: 'pin me 2' }) + const message = await rest.sendMessage(e2eCache.channel.id, { content: 'pin me' }); + const message2 = await rest.sendMessage(e2eCache.channel.id, { content: 'pin me 2' }); - await rest.pinMessage(e2eCache.channel.id, message.id) - await rest.pinMessage(e2eCache.channel.id, message2.id, 'with a reason') + await rest.pinMessage(e2eCache.channel.id, message.id); + await rest.pinMessage(e2eCache.channel.id, message2.id, 'with a reason'); - const pins = await rest.getChannelPins(e2eCache.channel.id) + const pins = await rest.getChannelPins(e2eCache.channel.id); - expect(pins.items.length).to.equal(2) - expect(pins.items.some((p) => p.message.id === message.id)).to.equal(true) + expect(pins.items.length).to.equal(2); + expect(pins.items.some((p) => p.message.id === message.id)).to.equal(true); - await rest.unpinMessage(e2eCache.channel.id, message.id) - await rest.unpinMessage(e2eCache.channel.id, message2.id, 'with a reason') + await rest.unpinMessage(e2eCache.channel.id, message.id); + await rest.unpinMessage(e2eCache.channel.id, message2.id, 'with a reason'); - const unpinned = await rest.getChannelPins(e2eCache.channel.id) - expect(unpinned.items.length).to.equal(0) - }) -}) + const unpinned = await rest.getChannelPins(e2eCache.channel.id); + expect(unpinned.items.length).to.equal(0); + }); +}); describe('Rate limit manager testing', () => { it('Send 10 messages to 1 channel', async () => { const promises = Array.from({ length: 10 }, async (_, i) => { - await rest.sendMessage(e2eCache.channel.id, { content: `10 messages to 1 channel testing rate limit manager ${i}` }) - }) + await rest.sendMessage(e2eCache.channel.id, { content: `10 messages to 1 channel testing rate limit manager ${i}` }); + }); - await Promise.all(promises) - }) + await Promise.all(promises); + }); it('Send 10 messages to 10 channels', async () => { // Create 10 channels and send a message to each const promises = Array.from({ length: 10 }, async (_, i) => { - const channel = await rest.createChannel(e2eCache.guild.id, { name: `rate-limit-${i}` }) - toDispose.add(async () => await rest.deleteChannel(channel.id)) + const channel = await rest.createChannel(e2eCache.guild.id, { name: `rate-limit-${i}` }); + toDispose.add(async () => await rest.deleteChannel(channel.id)); const messagePromises = Array.from({ length: 10 }, async (_, j) => { - await rest.sendMessage(channel.id, { content: `testing rate limit manager ${j}` }) - }) + await rest.sendMessage(channel.id, { content: `testing rate limit manager ${j}` }); + }); - await Promise.all(messagePromises) - }) + await Promise.all(messagePromises); + }); - await Promise.all(promises) - }) -}) + await Promise.all(promises); + }); +}); diff --git a/packages/rest/tests/e2e/misc.spec.ts b/packages/rest/tests/e2e/misc.spec.ts index d0f3e8f92..60519c6ca 100644 --- a/packages/rest/tests/e2e/misc.spec.ts +++ b/packages/rest/tests/e2e/misc.spec.ts @@ -1,15 +1,15 @@ -import { use as chaiUse, expect } from 'chai' -import chaiAsPromised from 'chai-as-promised' -import { describe } from 'mocha' -import { e2eCache, rest } from './utils.js' +import { use as chaiUse, expect } from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +import { describe } from 'mocha'; +import { e2eCache, rest } from './utils.js'; -chaiUse(chaiAsPromised) +chaiUse(chaiAsPromised); describe('Typings', () => { it('Trigger Typing Indication', async () => { - await rest.triggerTypingIndicator(e2eCache.channel.id) - }) -}) + await rest.triggerTypingIndicator(e2eCache.channel.id); + }); +}); describe('Commands', () => { it('Upsert global commands', async () => { @@ -18,24 +18,24 @@ describe('Commands', () => { name: 'ping', description: 'Ping the bot', }, - ]) + ]); - const cmds = await rest.getGlobalApplicationCommands() - const created = cmds.find((cmd) => cmd.name === 'ping' && cmd.description === 'Ping the bot') - expect(!!created?.id).to.be.true + const cmds = await rest.getGlobalApplicationCommands(); + const created = cmds.find((cmd) => cmd.name === 'ping' && cmd.description === 'Ping the bot'); + expect(!!created?.id).to.be.true; - const made = await rest.getGlobalApplicationCommand(created!.id) - expect(created?.name).to.be.equal(made.name) - expect(created?.description).to.be.equal(made.description) + const made = await rest.getGlobalApplicationCommand(created!.id); + expect(created?.name).to.be.equal(made.name); + expect(created?.description).to.be.equal(made.description); - const edited = await rest.editGlobalApplicationCommand(created!.id, { name: 'pong', description: 'edited description' }) - expect(edited.name).to.be.equal('pong') - expect(edited.name).to.not.be.equal(made.name) - expect(edited.description).to.be.equal('edited description') - expect(edited.description).to.not.be.equal(made.description) + const edited = await rest.editGlobalApplicationCommand(created!.id, { name: 'pong', description: 'edited description' }); + expect(edited.name).to.be.equal('pong'); + expect(edited.name).to.not.be.equal(made.name); + expect(edited.description).to.be.equal('edited description'); + expect(edited.description).to.not.be.equal(made.description); - await rest.deleteGlobalApplicationCommand(created!.id) + await rest.deleteGlobalApplicationCommand(created!.id); - await expect(rest.getGlobalApplicationCommand(created!.id)).to.eventually.be.rejected - }) -}) + await expect(rest.getGlobalApplicationCommand(created!.id)).to.eventually.be.rejected; + }); +}); diff --git a/packages/rest/tests/e2e/role.spec.ts b/packages/rest/tests/e2e/role.spec.ts index faa33d857..8eaa5da9b 100644 --- a/packages/rest/tests/e2e/role.spec.ts +++ b/packages/rest/tests/e2e/role.spec.ts @@ -1,45 +1,45 @@ -import { calculateBits } from '@discordeno/utils' -import { expect } from 'chai' -import { describe, it } from 'mocha' -import { e2eCache, rest, toDispose } from './utils.js' +import { calculateBits } from '@discordeno/utils'; +import { expect } from 'chai'; +import { describe, it } from 'mocha'; +import { e2eCache, rest, toDispose } from './utils.js'; describe('Role tests', () => { // Create a role with a reason it('Create a role with a reason', async () => { - const role = await rest.createRole(e2eCache.guild?.id, { name: `test role ${Date.now()}` }, 'test reason') - toDispose.add(async () => await rest.deleteRole(e2eCache.guild.id, role.id)) + const role = await rest.createRole(e2eCache.guild?.id, { name: `test role ${Date.now()}` }, 'test reason'); + toDispose.add(async () => await rest.deleteRole(e2eCache.guild.id, role.id)); - expect(role.id).to.exist - }) + expect(role.id).to.exist; + }); // Create a role without a reason it('Create a role without a reason', async () => { const role = await rest.createRole(e2eCache.guild.id, { name: `test role ${Date.now()}`, - }) - toDispose.add(async () => await rest.deleteRole(e2eCache.guild.id, role.id)) + }); + toDispose.add(async () => await rest.deleteRole(e2eCache.guild.id, role.id)); - expect(role.id).to.exist - }) + expect(role.id).to.exist; + }); // Delete a role it('Delete a role', async () => { const role = await rest.createRole(e2eCache.guild.id, { name: `test role ${Date.now()}`, - }) + }); - await rest.deleteRole(e2eCache.guild.id, role.id) + await rest.deleteRole(e2eCache.guild.id, role.id); - const deletedRoles = await rest.getRoles(e2eCache.guild.id) - expect(deletedRoles.some((r) => r.id === role.id)).to.equal(false) - }) + const deletedRoles = await rest.getRoles(e2eCache.guild.id); + expect(deletedRoles.some((r) => r.id === role.id)).to.equal(false); + }); // Edit a role it('Edit a role', async () => { const role = await rest.createRole(e2eCache.guild.id, { name: `test role ${Date.now()}`, - }) - toDispose.add(async () => await rest.deleteRole(e2eCache.guild.id, role.id)) + }); + toDispose.add(async () => await rest.deleteRole(e2eCache.guild.id, role.id)); const edited = await rest.editRole(e2eCache.guild.id, role.id, { name: 'test role 4', @@ -47,47 +47,47 @@ describe('Role tests', () => { hoist: true, mentionable: true, permissions: ['SEND_MESSAGES', 'VIEW_CHANNEL'], - }) + }); - expect(edited.name).to.equal('test role 4') - expect(edited.color).to.equal(0x0000ff) - expect(edited.hoist).to.equal(true) - expect(edited.mentionable).to.equal(true) - expect(edited.permissions.toString()).to.equal(calculateBits(['SEND_MESSAGES', 'VIEW_CHANNEL'])) + expect(edited.name).to.equal('test role 4'); + expect(edited.color).to.equal(0x0000ff); + expect(edited.hoist).to.equal(true); + expect(edited.mentionable).to.equal(true); + expect(edited.permissions.toString()).to.equal(calculateBits(['SEND_MESSAGES', 'VIEW_CHANNEL'])); await rest.editRole(e2eCache.guild.id, role.id, { hoist: false, mentionable: false, - }) + }); - const roles = await rest.getRoles(e2eCache.guild.id) - const unedited = roles.find((r) => r.id === role.id) - expect(unedited?.hoist).to.equal(false) - expect(unedited?.mentionable).to.equal(false) - }) + const roles = await rest.getRoles(e2eCache.guild.id); + const unedited = roles.find((r) => r.id === role.id); + expect(unedited?.hoist).to.equal(false); + expect(unedited?.mentionable).to.equal(false); + }); it('Add and remove role from user', async () => { const role = await rest.createRole(e2eCache.guild.id, { name: `test role ${Date.now()}`, - }) - toDispose.add(async () => await rest.deleteRole(e2eCache.guild.id, role.id)) + }); + toDispose.add(async () => await rest.deleteRole(e2eCache.guild.id, role.id)); // Assign the role to the user - await rest.addRole(e2eCache.guild.id, rest.applicationId, role.id) - const member = await rest.getMember(e2eCache.guild.id, rest.applicationId) - expect(member?.roles.includes(role.id)).to.equal(true) + await rest.addRole(e2eCache.guild.id, rest.applicationId, role.id); + const member = await rest.getMember(e2eCache.guild.id, rest.applicationId); + expect(member?.roles.includes(role.id)).to.equal(true); - await rest.removeRole(e2eCache.guild.id, rest.applicationId, role.id) - const removed = await rest.getMember(e2eCache.guild.id, rest.applicationId) - expect(removed?.roles.includes(role.id)).to.equal(false) + await rest.removeRole(e2eCache.guild.id, rest.applicationId, role.id); + const removed = await rest.getMember(e2eCache.guild.id, rest.applicationId); + expect(removed?.roles.includes(role.id)).to.equal(false); // With a reason - await rest.addRole(e2eCache.guild.id, rest.applicationId, role.id, 'test reason') - const member2 = await rest.getMember(e2eCache.guild.id, rest.applicationId) - expect(member2?.roles.includes(role.id)).to.equal(true) + await rest.addRole(e2eCache.guild.id, rest.applicationId, role.id, 'test reason'); + const member2 = await rest.getMember(e2eCache.guild.id, rest.applicationId); + expect(member2?.roles.includes(role.id)).to.equal(true); - await rest.removeRole(e2eCache.guild.id, rest.applicationId, role.id, 'test reason') - const member3 = await rest.getMember(e2eCache.guild.id, rest.applicationId) - expect(member3?.roles.includes(role.id)).to.equal(false) - }) -}) + await rest.removeRole(e2eCache.guild.id, rest.applicationId, role.id, 'test reason'); + const member3 = await rest.getMember(e2eCache.guild.id, rest.applicationId); + expect(member3?.roles.includes(role.id)).to.equal(false); + }); +}); diff --git a/packages/rest/tests/e2e/stickers.spec.ts b/packages/rest/tests/e2e/stickers.spec.ts index 6eeb3b3be..21323bb8c 100644 --- a/packages/rest/tests/e2e/stickers.spec.ts +++ b/packages/rest/tests/e2e/stickers.spec.ts @@ -1,17 +1,17 @@ -import { StickerFormatTypes } from '@discordeno/types' -import { use as chaiUse, expect } from 'chai' -import chaiAsPromised from 'chai-as-promised' -import { describe, it } from 'mocha' -import { e2eCache, rest, toDispose } from './utils.js' +import { StickerFormatTypes } from '@discordeno/types'; +import { use as chaiUse, expect } from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +import { describe, it } from 'mocha'; +import { e2eCache, rest, toDispose } from './utils.js'; -chaiUse(chaiAsPromised) +chaiUse(chaiAsPromised); // waiting for channel describe('Sticker tests', () => { it('Can get a sticker', async () => { - const sticker = await rest.getSticker(749054660769218631n) - expect(sticker.name).to.equal('Wave') - }) + const sticker = await rest.getSticker(749054660769218631n); + expect(sticker.name).to.equal('Wave'); + }); it('Create, edit, get, and delete guild sticker', async () => { const sticker = await rest.createGuildSticker(e2eCache.guild.id, { @@ -22,39 +22,39 @@ describe('Sticker tests', () => { blob: await (await fetch('https://i.imgur.com/ejqd6Ro.png')).blob(), name: 'ddlogo.png', }, - }) - const cleanSticker = async () => await rest.deleteGuildSticker(e2eCache.guild.id, sticker.id) + }); + const cleanSticker = async () => await rest.deleteGuildSticker(e2eCache.guild.id, sticker.id); // We may remove this as we also test sticker deletion at the end of the test, so we need a var to reference the function - toDispose.add(cleanSticker) + toDispose.add(cleanSticker); - expect(sticker.name).to.equal('sticker name') - expect(sticker.description).to.equal('sticker description') - expect(sticker.tags).to.equal('sticker tags') + expect(sticker.name).to.equal('sticker name'); + expect(sticker.description).to.equal('sticker description'); + expect(sticker.tags).to.equal('sticker tags'); const message = await rest.sendMessage(e2eCache.channel.id, { stickerIds: [sticker.id], - }) + }); - expect(message.stickerItems?.[0].formatType).to.equal(StickerFormatTypes.Png) - expect(message.stickerItems?.[0].id).to.equal(sticker.id) - expect(message.stickerItems?.[0].name).to.equal(sticker.name) + expect(message.stickerItems?.[0].formatType).to.equal(StickerFormatTypes.Png); + expect(message.stickerItems?.[0].id).to.equal(sticker.id); + expect(message.stickerItems?.[0].name).to.equal(sticker.name); - const getSticker = await rest.getGuildSticker(e2eCache.guild.id, sticker.id) + const getSticker = await rest.getGuildSticker(e2eCache.guild.id, sticker.id); - expect(getSticker.name).to.equal('sticker name') - expect(getSticker.description).to.equal('sticker description') - expect(getSticker.tags).to.equal('sticker tags') + expect(getSticker.name).to.equal('sticker name'); + expect(getSticker.description).to.equal('sticker description'); + expect(getSticker.tags).to.equal('sticker tags'); const editSticker = await rest.editGuildSticker(e2eCache.guild.id, sticker.id, { name: 'sticker name', description: 'sticker description', tags: 'sticker tags', - }) + }); - expect(editSticker.name).to.equal('sticker name') - expect(editSticker.description).to.equal('sticker description') - expect(editSticker.tags).to.equal('sticker tags') + expect(editSticker.name).to.equal('sticker name'); + expect(editSticker.description).to.equal('sticker description'); + expect(editSticker.tags).to.equal('sticker tags'); const sticker2 = await rest.createGuildSticker(e2eCache.guild.id, { name: 'sticker 2', @@ -64,17 +64,17 @@ describe('Sticker tests', () => { blob: await (await fetch('https://i.imgur.com/ejqd6Ro.png')).blob(), name: 'ddlogo.png', }, - }) + }); - toDispose.add(async () => await rest.deleteGuildSticker(e2eCache.guild.id, sticker2.id)) + toDispose.add(async () => await rest.deleteGuildSticker(e2eCache.guild.id, sticker2.id)); - const stickers = await rest.getGuildStickers(e2eCache.guild.id) - expect(stickers.length).to.greaterThan(1) + const stickers = await rest.getGuildStickers(e2eCache.guild.id); + expect(stickers.length).to.greaterThan(1); - await rest.deleteGuildSticker(e2eCache.guild.id, sticker.id) + await rest.deleteGuildSticker(e2eCache.guild.id, sticker.id); // Since we have already deleted the sticker, we can remove it from the toDispose set - toDispose.delete(cleanSticker) + toDispose.delete(cleanSticker); - await expect(rest.getGuildSticker(e2eCache.guild.id, sticker.id)).to.eventually.rejected - }) -}) + await expect(rest.getGuildSticker(e2eCache.guild.id, sticker.id)).to.eventually.rejected; + }); +}); diff --git a/packages/rest/tests/e2e/user.spec.ts b/packages/rest/tests/e2e/user.spec.ts index 8464bf18a..156b4a6ac 100644 --- a/packages/rest/tests/e2e/user.spec.ts +++ b/packages/rest/tests/e2e/user.spec.ts @@ -1,37 +1,37 @@ -import { use as chaiUse, expect } from 'chai' -import chaiAsPromised from 'chai-as-promised' -import { describe, it } from 'mocha' -import { rest } from './utils.js' +import { use as chaiUse, expect } from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +import { describe, it } from 'mocha'; +import { rest } from './utils.js'; -chaiUse(chaiAsPromised) +chaiUse(chaiAsPromised); describe('Get a user from the api', () => { it('With a valid user id', async () => { - const user = await rest.getUser('130136895395987456') + const user = await rest.getUser('130136895395987456'); describe('User has correct shape and form', () => { it('Has correct id', () => { - expect(user.id).to.be.equal('130136895395987456') - }) + expect(user.id).to.be.equal('130136895395987456'); + }); it('Has a valid username', () => { - expect(user.username.length).to.be.greaterThanOrEqual(1) - }) + expect(user.username.length).to.be.greaterThanOrEqual(1); + }); it('Has a valid discriminator', () => { - expect(user.discriminator.length).to.be.oneOf([1, 4]) - }) + expect(user.discriminator.length).to.be.oneOf([1, 4]); + }); it('Has been camelized', () => { - const keys = Object.keys(user) + const keys = Object.keys(user); - expect(keys.includes('public_flags')).to.be.false - expect(keys.includes('publicFlags')).to.be.true - }) - }) - }) + expect(keys.includes('public_flags')).to.be.false; + expect(keys.includes('publicFlags')).to.be.true; + }); + }); + }); it('With an invalid user id', async () => { - await expect(rest.getUser('123')).eventually.rejected - }) -}) + await expect(rest.getUser('123')).eventually.rejected; + }); +}); diff --git a/packages/rest/tests/e2e/utils.ts b/packages/rest/tests/e2e/utils.ts index f6487baca..406ef407d 100644 --- a/packages/rest/tests/e2e/utils.ts +++ b/packages/rest/tests/e2e/utils.ts @@ -1,52 +1,52 @@ -import { after } from 'mocha' -import { createRestManager } from '../../src/manager.js' -import { E2E_TEST_GUILD_ID, token } from './constants.js' +import { after } from 'mocha'; +import { createRestManager } from '../../src/manager.js'; +import { E2E_TEST_GUILD_ID, token } from './constants.js'; // For debugging purposes // logger.setLevel(LogLevels.Debug) export const rest = createRestManager({ token, -}) -rest.deleteQueueDelay = 10000 +}); +rest.deleteQueueDelay = 10000; -const guild = await rest.getGuild(E2E_TEST_GUILD_ID) -if (!guild) throw new Error('E2E_TEST_GUILD_ID does not exist or is not accessible.') +const guild = await rest.getGuild(E2E_TEST_GUILD_ID); +if (!guild) throw new Error('E2E_TEST_GUILD_ID does not exist or is not accessible.'); const channel = await rest.createChannel(guild.id, { name: 'discordeno-e2e', -}) +}); after(async () => { // Clean up the channel created for testing if (channel.id) { - await rest.deleteChannel(channel.id) + await rest.deleteChannel(channel.id); } -}) +}); export const e2eCache = { guildId: E2E_TEST_GUILD_ID, guild, channel, -} +}; // Some resources created during tests need to be disposed of afterwards, as they will persist otherwise (e.g., emojis, roles, automod rules) -export const toDispose = new Set<() => Promise>() +export const toDispose = new Set<() => Promise>(); afterEach(async () => { - let aggregateError: AggregateError | null = null + let aggregateError: AggregateError | null = null; for (const dispose of toDispose) { try { - await dispose() + await dispose(); } catch (error) { - console.error('Error during cleanup:', error) + console.error('Error during cleanup:', error); - aggregateError ??= new AggregateError([], 'Errors occurred during cleanup') - aggregateError.errors.push(error) + aggregateError ??= new AggregateError([], 'Errors occurred during cleanup'); + aggregateError.errors.push(error); } } - toDispose.clear() + toDispose.clear(); - if (aggregateError) throw aggregateError -}) + if (aggregateError) throw aggregateError; +}); diff --git a/packages/rest/tests/e2e/webhook.spec.ts b/packages/rest/tests/e2e/webhook.spec.ts index 654452275..55f1fbc7f 100644 --- a/packages/rest/tests/e2e/webhook.spec.ts +++ b/packages/rest/tests/e2e/webhook.spec.ts @@ -1,81 +1,81 @@ -import { use as chaiUse, expect } from 'chai' -import chaiAsPromised from 'chai-as-promised' -import { describe, it } from 'mocha' -import { e2eCache, rest } from './utils.js' +import { use as chaiUse, expect } from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +import { describe, it } from 'mocha'; +import { e2eCache, rest } from './utils.js'; -chaiUse(chaiAsPromised) +chaiUse(chaiAsPromised); describe('Webhook helpers', () => { it('Manage webhooks', async () => { const webhook = await rest.createWebhook(e2eCache.channel.id, { name: 'idk', - }) - expect(webhook).to.exist - expect(webhook.name).to.equal('idk') - expect(webhook.token).to.exist + }); + expect(webhook).to.exist; + expect(webhook.name).to.equal('idk'); + expect(webhook.token).to.exist; - const fetched = await rest.getWebhook(webhook.id) - expect(fetched).to.exist - expect(webhook.id).to.equal(fetched.id) + const fetched = await rest.getWebhook(webhook.id); + expect(fetched).to.exist; + expect(webhook.id).to.equal(fetched.id); - const fetched2 = await rest.getWebhookWithToken(webhook.id, webhook.token!) - expect(webhook.id).to.equal(fetched2.id) + const fetched2 = await rest.getWebhookWithToken(webhook.id, webhook.token!); + expect(webhook.id).to.equal(fetched2.id); const edited = await rest.editWebhook(webhook.id, { name: 'edited', - }) - expect(webhook.name).to.not.equal(edited.name) + }); + expect(webhook.name).to.not.equal(edited.name); const edited2 = await rest.editWebhookWithToken(webhook.id, webhook.token!, { name: 'editedtoken', - }) - expect(edited.name).to.not.equal(edited2.name) + }); + expect(edited.name).to.not.equal(edited2.name); - await rest.createWebhook(e2eCache.channel.id, { name: 'idkk' }) - const hooks = await rest.getChannelWebhooks(e2eCache.channel.id) - expect(hooks.length).to.greaterThan(1) + await rest.createWebhook(e2eCache.channel.id, { name: 'idkk' }); + const hooks = await rest.getChannelWebhooks(e2eCache.channel.id); + expect(hooks.length).to.greaterThan(1); - const guildHooks = await rest.getGuildWebhooks(e2eCache.guild.id) - expect(guildHooks.length).to.greaterThan(1) + const guildHooks = await rest.getGuildWebhooks(e2eCache.guild.id); + expect(guildHooks.length).to.greaterThan(1); - await rest.deleteWebhook(webhook.id) + await rest.deleteWebhook(webhook.id); // Fetch the webhook to validate it was deleted - await expect(rest.getWebhook(webhook.id)).to.eventually.rejected + await expect(rest.getWebhook(webhook.id)).to.eventually.rejected; const hookToDelete = await rest.createWebhook(e2eCache.channel.id, { name: 'delme', - }) - expect(hookToDelete?.id).to.exist - expect(hookToDelete.token).to.exist + }); + expect(hookToDelete?.id).to.exist; + expect(hookToDelete.token).to.exist; - await rest.deleteWebhookWithToken(hookToDelete.id, hookToDelete.token!) + await rest.deleteWebhookWithToken(hookToDelete.id, hookToDelete.token!); // Fetch the webhook to validate it was deleted - await expect(rest.getWebhook(hookToDelete.id)).to.eventually.rejected - }) + await expect(rest.getWebhook(hookToDelete.id)).to.eventually.rejected; + }); it('Manage webhook messages', async () => { const webhook = await rest.createWebhook(e2eCache.channel.id, { name: 'idk', - }) - expect(webhook).to.exist + }); + expect(webhook).to.exist; const message = await rest.executeWebhook(webhook.id, webhook.token!, { content: 'discordeno is best lib', wait: true, - }) - expect(message?.id).to.exist + }); + expect(message?.id).to.exist; - const message2 = await rest.getWebhookMessage(webhook.id, webhook.token!, message!.id) - expect(message2).to.exist - expect(message2.content).to.equal(message?.content) + const message2 = await rest.getWebhookMessage(webhook.id, webhook.token!, message!.id); + expect(message2).to.exist; + expect(message2.content).to.equal(message?.content); const edited3 = await rest.editWebhookMessage(webhook.id, webhook.token!, message!.id, { content: 'different', - }) - expect(edited3).to.exist - expect(edited3.content).to.not.equal(message2.content) + }); + expect(edited3).to.exist; + expect(edited3.content).to.not.equal(message2.content); - await rest.deleteWebhookMessage(webhook.id, webhook.token!, message!.id) - await expect(rest.getWebhookMessage(webhook.id, webhook.token!, message!.id)).to.eventually.rejected - }) -}) + await rest.deleteWebhookMessage(webhook.id, webhook.token!, message!.id); + await expect(rest.getWebhookMessage(webhook.id, webhook.token!, message!.id)).to.eventually.rejected; + }); +}); diff --git a/packages/rest/tests/unit/index.spec.ts b/packages/rest/tests/unit/index.spec.ts index 3ca08a54b..18a17c85c 100644 --- a/packages/rest/tests/unit/index.spec.ts +++ b/packages/rest/tests/unit/index.spec.ts @@ -1,7 +1,7 @@ -import { describe, it } from 'mocha' +import { describe, it } from 'mocha'; describe('index.ts', () => { it('will import without error', async () => { - await import('../../src/index.js') - }) -}) + await import('../../src/index.js'); + }); +}); diff --git a/packages/rest/tests/unit/manager.spec.ts b/packages/rest/tests/unit/manager.spec.ts index 23cb0f49e..999d86649 100644 --- a/packages/rest/tests/unit/manager.spec.ts +++ b/packages/rest/tests/unit/manager.spec.ts @@ -1,22 +1,22 @@ -import { expect } from 'chai' -import { afterEach, beforeEach, describe, it } from 'mocha' -import sinon from 'sinon' -import { createRestManager } from '../../src/manager.js' -import type { RestManager } from '../../src/types.js' -import { fakeToken as token } from '../constants.js' +import { expect } from 'chai'; +import { afterEach, beforeEach, describe, it } from 'mocha'; +import sinon from 'sinon'; +import { createRestManager } from '../../src/manager.js'; +import type { RestManager } from '../../src/types.js'; +import { fakeToken as token } from '../constants.js'; describe('[rest] manager', () => { describe('create a rest manager with only a token', () => { - const rest = createRestManager({ token }) + const rest = createRestManager({ token }); it('Token is set properly.', () => { - expect(rest.token).to.be.equal(token) - }) + expect(rest.token).to.be.equal(token); + }); it('Default values are set when none are provided.', () => { - expect(rest.version).to.be.equal(10) - expect(rest.baseUrl).to.be.equal('https://discord.com/api') - }) - }) + expect(rest.version).to.be.equal(10); + expect(rest.baseUrl).to.be.equal('https://discord.com/api'); + }); + }); describe('create a manager with other options', () => { const options = { @@ -26,201 +26,201 @@ describe('[rest] manager', () => { baseUrl: 'https://localhost:8000', authorization: token, }, - } as const + } as const; - const rest = createRestManager(options) + const rest = createRestManager(options); it('With a version', () => { - expect(rest.version).to.be.equal(options.version) - }) + expect(rest.version).to.be.equal(options.version); + }); it('With a base url', () => { - expect(rest.baseUrl).to.be.equal(options.proxy.baseUrl) - }) + expect(rest.baseUrl).to.be.equal(options.proxy.baseUrl); + }); it('With an application id', () => { - const subrest = createRestManager({ ...options, applicationId: '130136895395987456' }) - expect(subrest.applicationId).to.be.equal(130136895395987456n) - }) - }) + const subrest = createRestManager({ ...options, applicationId: '130136895395987456' }); + expect(subrest.applicationId).to.be.equal(130136895395987456n); + }); + }); describe('rest.simplifyUrl', () => { describe('the ending id', () => { it('Will change to x minor params', () => { - const rest = createRestManager({ token }) - expect(rest.simplifyUrl('/messages/555555555555555555', 'PUT')).to.be.equal('PUT:/messages/x') - expect(rest.simplifyUrl('/users/555555555555555555', 'PUT')).to.be.equal('PUT:/users/x') - expect(rest.simplifyUrl('/abc/555555555555555555', 'PUT')).to.be.equal('PUT:/abc/x') - expect(rest.simplifyUrl('/test1/555555555555555555', 'PUT')).to.be.equal('PUT:/test1/x') - expect(rest.simplifyUrl('/test2/555555555555555555', 'PUT')).to.be.equal('PUT:/test2/x') - }) + const rest = createRestManager({ token }); + expect(rest.simplifyUrl('/messages/555555555555555555', 'PUT')).to.be.equal('PUT:/messages/x'); + expect(rest.simplifyUrl('/users/555555555555555555', 'PUT')).to.be.equal('PUT:/users/x'); + expect(rest.simplifyUrl('/abc/555555555555555555', 'PUT')).to.be.equal('PUT:/abc/x'); + expect(rest.simplifyUrl('/test1/555555555555555555', 'PUT')).to.be.equal('PUT:/test1/x'); + expect(rest.simplifyUrl('/test2/555555555555555555', 'PUT')).to.be.equal('PUT:/test2/x'); + }); it('Will not change to x major params', () => { - const rest = createRestManager({ token }) - expect(rest.simplifyUrl('/channels/555555555555555555', 'PUT')).to.be.equal('PUT:/channels/555555555555555555') - expect(rest.simplifyUrl('/guilds/555555555555555555', 'PUT')).to.be.equal('PUT:/guilds/555555555555555555') - expect(rest.simplifyUrl('/webhooks/555555555555555555', 'PUT')).to.be.equal('PUT:/webhooks/555555555555555555') - }) - }) + const rest = createRestManager({ token }); + expect(rest.simplifyUrl('/channels/555555555555555555', 'PUT')).to.be.equal('PUT:/channels/555555555555555555'); + expect(rest.simplifyUrl('/guilds/555555555555555555', 'PUT')).to.be.equal('PUT:/guilds/555555555555555555'); + expect(rest.simplifyUrl('/webhooks/555555555555555555', 'PUT')).to.be.equal('PUT:/webhooks/555555555555555555'); + }); + }); describe('with route', () => { describe('/reactions', () => { it('Will remove path after reactions', () => { - const rest = createRestManager({ token }) + const rest = createRestManager({ token }); expect( rest.simplifyUrl('/channels/555555555555555555/messages/555555555555555555/reactions/wdiubaibfwuabfobaowbfoibnion/@me', 'PUT'), - ).to.be.equal('PUT:/channels/555555555555555555/messages/x/reactions/x/@me') - }) - }) + ).to.be.equal('PUT:/channels/555555555555555555/messages/x/reactions/x/@me'); + }); + }); describe('/messages', () => { it('Will add method in front route', () => { - const rest = createRestManager({ token }) + const rest = createRestManager({ token }); expect(rest.simplifyUrl('/channels/555555555555555555/messages/555555555555555555', 'POST')).to.be.equal( 'POST:/channels/555555555555555555/messages/x', - ) + ); expect(rest.simplifyUrl('/channels/555555555555555555/messages/555555555555555555', 'GET')).to.be.equal( 'GET:/channels/555555555555555555/messages/x', - ) + ); expect(rest.simplifyUrl('/channels/555555555555555555/messages/555555555555555555', 'PUT')).to.be.equal( 'PUT:/channels/555555555555555555/messages/x', - ) - }) - }) + ); + }); + }); describe('/webhook/id/token', () => { it('Will not change to x major params', () => { - const rest = createRestManager({ token }) + const rest = createRestManager({ token }); expect(rest.simplifyUrl('/webhooks/555555555555555555/abcdefg1234567', 'POST')).to.be.equal( 'POST:/webhooks/555555555555555555/abcdefg1234567', - ) - }) + ); + }); it('Will change to x minor params', () => { - const rest = createRestManager({ token }) + const rest = createRestManager({ token }); expect(rest.simplifyUrl('/webhooks/555555555555555555/abcdefg1234567/messages/2222222222222222222', 'POST')).to.be.equal( 'POST:/webhooks/555555555555555555/abcdefg1234567/messages/x', - ) - }) - }) - }) - }) + ); + }); + }); + }); + }); describe('rest.checkRateLimits', () => { - let rest: RestManager - let clock: sinon.SinonFakeTimers + let rest: RestManager; + let clock: sinon.SinonFakeTimers; beforeEach(() => { - rest = createRestManager({ token }) - clock = sinon.useFakeTimers() - }) + rest = createRestManager({ token }); + clock = sinon.useFakeTimers(); + }); afterEach(() => { - clock.restore() - }) + clock.restore(); + }); it('will return false for path without rate limited', () => { - expect(rest.checkRateLimits('/channel/555555555555555555', `Bot ${token}`)).to.be.equal(false) - }) + expect(rest.checkRateLimits('/channel/555555555555555555', `Bot ${token}`)).to.be.equal(false); + }); describe('With per URL rateLimitedPath', () => { it('Will return time until reset if before resetTimestamp', () => { rest.rateLimitedPaths.set(`Bot ${token}/channel/555555555555555555`, { url: '/channel/555555555555555555', resetTimestamp: Date.now() + 6541, - }) - expect(rest.checkRateLimits('/channel/555555555555555555', `Bot ${token}`)).to.be.equal(6541) - }) + }); + expect(rest.checkRateLimits('/channel/555555555555555555', `Bot ${token}`)).to.be.equal(6541); + }); it('Will return false if before resetTimestamp', () => { rest.rateLimitedPaths.set(`Bot ${token}/channel/555555555555555555`, { url: '/channel/555555555555555555', resetTimestamp: Date.now(), - }) - expect(rest.checkRateLimits('/channel/555555555555555555', `Bot ${token}`)).to.be.equal(false) - }) - }) + }); + expect(rest.checkRateLimits('/channel/555555555555555555', `Bot ${token}`)).to.be.equal(false); + }); + }); describe('With global rateLimitedPath', () => { it('Will return time until reset if before resetTimestamp', () => { rest.rateLimitedPaths.set('global', { url: '/channel/555555555555555555', resetTimestamp: Date.now() + 9849, - }) - expect(rest.checkRateLimits('/channel/555555555555555555', `Bot ${token}`)).to.be.equal(9849) - }) + }); + expect(rest.checkRateLimits('/channel/555555555555555555', `Bot ${token}`)).to.be.equal(9849); + }); it('Will return false if before resetTimestamp', () => { rest.rateLimitedPaths.set('global', { url: '/channel/555555555555555555', resetTimestamp: Date.now(), - }) - expect(rest.checkRateLimits('/channel/555555555555555555', `Bot ${token}`)).to.be.equal(false) - }) - }) + }); + expect(rest.checkRateLimits('/channel/555555555555555555', `Bot ${token}`)).to.be.equal(false); + }); + }); describe('With both URL and Global rateLimitedPath', () => { it('Will return URL time first if before resetTimestamp', () => { rest.rateLimitedPaths.set(`Bot ${token}/channel/555555555555555555`, { url: '/channel/555555555555555555', resetTimestamp: Date.now() + 6541, - }) + }); rest.rateLimitedPaths.set('global', { url: '/channel/555555555555555555', resetTimestamp: Date.now() + 9849, - }) - expect(rest.checkRateLimits('/channel/555555555555555555', `Bot ${token}`)).to.be.equal(6541) - }) - }) - }) + }); + expect(rest.checkRateLimits('/channel/555555555555555555', `Bot ${token}`)).to.be.equal(6541); + }); + }); + }); describe('rest.processRateLimitedPaths', () => { - let rest: RestManager - let time: sinon.SinonFakeTimers + let rest: RestManager; + let time: sinon.SinonFakeTimers; beforeEach(() => { - rest = createRestManager({ token: '1', applicationId: 1n }) - time = sinon.useFakeTimers() - }) + rest = createRestManager({ token: '1', applicationId: 1n }); + time = sinon.useFakeTimers(); + }); afterEach(() => { - time.restore() - }) + time.restore(); + }); describe('rateLimitedPaths', () => { it('Will not delete path from rateLimitedPaths before resetTimestamp', () => { rest.rateLimitedPaths.set('', { resetTimestamp: Date.now() + 1, url: '', - }) - rest.processRateLimitedPaths() - expect(rest.rateLimitedPaths.size).to.be.equal(1) - }) + }); + rest.processRateLimitedPaths(); + expect(rest.rateLimitedPaths.size).to.be.equal(1); + }); it('Will delete path from rateLimitedPaths after resetTimestamp', () => { - rest.rateLimitedPaths.set('', { resetTimestamp: Date.now(), url: '' }) - rest.processRateLimitedPaths() - expect(rest.rateLimitedPaths.size).to.be.equal(0) - }) + rest.rateLimitedPaths.set('', { resetTimestamp: Date.now(), url: '' }); + rest.processRateLimitedPaths(); + expect(rest.rateLimitedPaths.size).to.be.equal(0); + }); it('Will mark globallyRateLimited false if key is global', () => { rest.rateLimitedPaths.set('global', { resetTimestamp: Date.now(), url: '', - }) - rest.globallyRateLimited = true - rest.processRateLimitedPaths() - expect(rest.rateLimitedPaths.size).to.be.equal(0) - expect(rest.globallyRateLimited).to.be.equal(false) - }) + }); + rest.globallyRateLimited = true; + rest.processRateLimitedPaths(); + expect(rest.rateLimitedPaths.size).to.be.equal(0); + expect(rest.globallyRateLimited).to.be.equal(false); + }); it('Will not mark globallyRateLimited false if key is not global', () => { - rest.rateLimitedPaths.set('', { resetTimestamp: Date.now(), url: '' }) - rest.globallyRateLimited = true - rest.processRateLimitedPaths() - expect(rest.rateLimitedPaths.size).to.be.equal(0) - expect(rest.globallyRateLimited).to.be.equal(true) - }) - }) - }) -}) + rest.rateLimitedPaths.set('', { resetTimestamp: Date.now(), url: '' }); + rest.globallyRateLimited = true; + rest.processRateLimitedPaths(); + expect(rest.rateLimitedPaths.size).to.be.equal(0); + expect(rest.globallyRateLimited).to.be.equal(true); + }); + }); + }); +}); diff --git a/packages/types/src/discord/application.ts b/packages/types/src/discord/application.ts index fb18f864f..2d157803d 100644 --- a/packages/types/src/discord/application.ts +++ b/packages/types/src/discord/application.ts @@ -1,77 +1,77 @@ /** Types for: https://discord.com/developers/docs/resources/application */ -import type { DiscordGuild } from './guild.js' -import type { OAuth2Scope } from './oauth2.js' -import type { DiscordTeam } from './teams.js' -import type { DiscordUser } from './user.js' -import type { DiscordWebhookEventType } from './webhookEvents.js' +import type { DiscordGuild } from './guild.js'; +import type { OAuth2Scope } from './oauth2.js'; +import type { DiscordTeam } from './teams.js'; +import type { DiscordUser } from './user.js'; +import type { DiscordWebhookEventType } from './webhookEvents.js'; /** https://discord.com/developers/docs/resources/application#application-object-application-structure */ export interface DiscordApplication { /** ID of the app */ - id: string + id: string; /** The name of the app */ - name: string + name: string; /** The icon hash of the app */ - icon: string | null + icon: string | null; /** The description of the app */ - description: string + description: string; /** An array of rpc origin urls, if rpc is enabled */ - rpc_origins?: string[] + rpc_origins?: string[]; /** When false only app owner can join the app's bot to guilds */ - bot_public: boolean + bot_public: boolean; /** When true the app's bot will only join upon completion of the full oauth2 code grant flow */ - bot_require_code_grant: boolean + bot_require_code_grant: boolean; /** Partial user object for the bot user associated with the app */ - bot?: Partial + bot?: Partial; /** The url of the app's terms of service */ - terms_of_service_url?: string + terms_of_service_url?: string; /** The url of the app's privacy policy */ - privacy_policy_url?: string + privacy_policy_url?: string; /** Partial user object containing info on the owner of the application */ - owner?: Partial + owner?: Partial; /** The hex encoded key for verification in interactions and the GameSDK's GetTicket */ - verify_key: string + verify_key: string; /** If the application belongs to a team, this will be a list of the members of that team */ - team: DiscordTeam | null + team: DiscordTeam | null; /** Guild associated with the app. For example, a developer support server. */ - guild_id?: string + guild_id?: string; /** A partial object of the associated guild */ - guild?: Partial + guild?: Partial; /** If this application is a game sold on Discord, this field will be the id of the "Game SKU" that is created, if exists */ - primary_sku_id?: string + primary_sku_id?: string; /** If this application is a game sold on Discord, this field will be the URL slug that links to the store page */ - slug?: string + slug?: string; /** If this application is a game sold on Discord, this field will be the hash of the image on store embeds */ - cover_image?: string + cover_image?: string; /** The application's public flags */ - flags?: ApplicationFlags + flags?: ApplicationFlags; /** An approximate count of the app's guild membership. */ - approximate_guild_count?: number + approximate_guild_count?: number; /** Approximate count of users that have installed the app. (authorized with `application.commands` as a scope) */ - approximate_user_install_count?: number + approximate_user_install_count?: number; /** Approximate count of users that have OAuth2 authorizations for the app */ - approximate_user_authorization_count?: number + approximate_user_authorization_count?: number; /** Array of redirect URIs for the app */ - redirect_uris?: string[] + redirect_uris?: string[]; /** Interactions endpoint URL for the app */ - interactions_endpoint_url?: string | null + interactions_endpoint_url?: string | null; /** the application's role connection verification entry point, which when configured will render the app as a verification method in the guild role verification configuration */ - role_connections_verification_url?: string | null + role_connections_verification_url?: string | null; /** Event webhook URL for the app to receive webhook events */ - event_webhooks_url?: string | null + event_webhooks_url?: string | null; /** If webhook events are enabled for the app. 1 to disable, and 2 to enable. */ - event_webhooks_status: DiscordApplicationEventWebhookStatus + event_webhooks_status: DiscordApplicationEventWebhookStatus; /** List of Webhook event types the app subscribes to */ - event_webhooks_types?: DiscordWebhookEventType[] + event_webhooks_types?: DiscordWebhookEventType[]; /** up to 5 tags describing the content and functionality of the application */ - tags?: string[] + tags?: string[]; /** settings for the application's default in-app authorization link, if enabled */ - install_params?: DiscordInstallParams + install_params?: DiscordInstallParams; /** Default scopes and permissions for each supported installation context. */ - integration_types_config?: Partial> + integration_types_config?: Partial>; /** the application's default custom authorization link, if enabled */ - custom_install_url?: string + custom_install_url?: string; } /** https://discord.com/developers/docs/resources/application#application-object-application-integration-types */ @@ -85,7 +85,7 @@ export enum DiscordApplicationIntegrationType { /** https://discord.com/developers/docs/resources/application#application-object-application-integration-type-configuration-object */ export interface DiscordApplicationIntegrationTypeConfiguration { /** Install params for each installation context's default in-app authorization link */ - oauth2_install_params?: DiscordInstallParams + oauth2_install_params?: DiscordInstallParams; } /** https://discord.com/developers/docs/resources/application#application-object-application-event-webhook-status */ @@ -125,35 +125,35 @@ export enum ApplicationFlags { /** https://discord.com/developers/docs/resources/application#install-params-object-install-params-structure */ export interface DiscordInstallParams { /** Scopes to add the application to the server with */ - scopes: OAuth2Scope[] + scopes: OAuth2Scope[]; /** Permissions to request for the bot role */ - permissions: string + permissions: string; } /** https://discord.com/developers/docs/resources/application#get-application-activity-instance-activity-instance-object */ export interface DiscordActivityInstance { /** Application ID */ - application_id: string + application_id: string; /** Activity Instance ID */ - instance_id: string + instance_id: string; /** Unique identifier for the launch */ - launch_id: string + launch_id: string; /** The Location the instance is running in */ - location: DiscordActivityLocation + location: DiscordActivityLocation; /** The IDs of the Users currently connected to the instance */ - users: string[] + users: string[]; } /** https://discord.com/developers/docs/resources/application#get-application-activity-instance-activity-location-object */ export interface DiscordActivityLocation { /** The unique identifier for the location */ - id: string + id: string; /** Enum describing kind of location */ - kind: DiscordActivityLocationKind + kind: DiscordActivityLocationKind; /** The id of the Channel */ - channel_id: string + channel_id: string; /** The id of the Guild */ - guild_id?: string | null + guild_id?: string | null; } /** https://discord.com/developers/docs/resources/application#get-application-activity-instance-activity-location-kind-enum */ diff --git a/packages/types/src/discord/applicationRoleConnectionMetadata.ts b/packages/types/src/discord/applicationRoleConnectionMetadata.ts index 62d2f3567..05dbb57ce 100644 --- a/packages/types/src/discord/applicationRoleConnectionMetadata.ts +++ b/packages/types/src/discord/applicationRoleConnectionMetadata.ts @@ -1,36 +1,36 @@ /** Types for: https://discord.com/developers/docs/resources/application-role-connection-metadata */ -import type { Localization } from './reference.js' +import type { Localization } from './reference.js'; /** https://discord.com/developers/docs/resources/application-role-connection-metadata#application-role-connection-metadata-object-application-role-connection-metadata-structure */ export interface DiscordApplicationRoleConnectionMetadata { /** Type of metadata value */ - type: DiscordApplicationRoleConnectionMetadataType + type: DiscordApplicationRoleConnectionMetadataType; /** * Dictionary key for the metadata field * * @remarks * Must be a-z, 0-9, or _ characters; 1-50 characters */ - key: string + key: string; /** * Name of the metadata field * * @remarks * 1-100 characters */ - name: string + name: string; /** Translations of the name */ - name_localizations?: Localization + name_localizations?: Localization; /** * Description of the metadata field * * @remarks * 1-200 characters */ - description: string + description: string; /** Translations of the description */ - description_localizations: Localization + description_localizations: Localization; } /** https://discord.com/developers/docs/resources/application-role-connection-metadata#application-role-connection-metadata-object-application-role-connection-metadata-type */ diff --git a/packages/types/src/discord/auditLog.ts b/packages/types/src/discord/auditLog.ts index bb54075a5..9c90d5b8b 100644 --- a/packages/types/src/discord/auditLog.ts +++ b/packages/types/src/discord/auditLog.ts @@ -1,60 +1,60 @@ /** Types for: https://discord.com/developers/docs/resources/audit-log */ -import type { DiscordAutoModerationRule } from './autoModeration.js' -import type { DiscordChannel, DiscordOverwrite, DiscordThreadMetadata } from './channel.js' -import type { DiscordEmoji } from './emoji.js' -import type { DiscordGuild, DiscordGuildOnboarding, DiscordGuildOnboardingPrompt, DiscordIntegration, DiscordMember } from './guild.js' -import type { DiscordScheduledEvent } from './guildScheduledEvent.js' -import type { DiscordApplicationCommand, DiscordApplicationCommandPermissions } from './interactions.js' -import type { DiscordInvite, DiscordInviteMetadata } from './invite.js' -import type { DiscordRole } from './permissions.js' -import type { DiscordSoundboardSound } from './soundboard.js' -import type { DiscordStageInstance } from './stageInstance.js' -import type { DiscordSticker } from './sticker.js' -import type { DiscordUser } from './user.js' -import type { DiscordWebhook } from './webhook.js' +import type { DiscordAutoModerationRule } from './autoModeration.js'; +import type { DiscordChannel, DiscordOverwrite, DiscordThreadMetadata } from './channel.js'; +import type { DiscordEmoji } from './emoji.js'; +import type { DiscordGuild, DiscordGuildOnboarding, DiscordGuildOnboardingPrompt, DiscordIntegration, DiscordMember } from './guild.js'; +import type { DiscordScheduledEvent } from './guildScheduledEvent.js'; +import type { DiscordApplicationCommand, DiscordApplicationCommandPermissions } from './interactions.js'; +import type { DiscordInvite, DiscordInviteMetadata } from './invite.js'; +import type { DiscordRole } from './permissions.js'; +import type { DiscordSoundboardSound } from './soundboard.js'; +import type { DiscordStageInstance } from './stageInstance.js'; +import type { DiscordSticker } from './sticker.js'; +import type { DiscordUser } from './user.js'; +import type { DiscordWebhook } from './webhook.js'; /** https://discord.com/developers/docs/resources/audit-log#audit-log-object-audit-log-structure */ export interface DiscordAuditLog { /** List of application commands referenced in the audit log */ - application_commands: DiscordApplicationCommand[] + application_commands: DiscordApplicationCommand[]; /** List of audit log entries, sorted from most to least recent */ - audit_log_entries: DiscordAuditLogEntry[] + audit_log_entries: DiscordAuditLogEntry[]; /** List of auto moderation rules referenced in the audit log */ - auto_moderation_rules: DiscordAutoModerationRule[] + auto_moderation_rules: DiscordAutoModerationRule[]; /** List of guild scheduled events found in the audit log */ - guild_scheduled_events: DiscordScheduledEvent[] + guild_scheduled_events: DiscordScheduledEvent[]; /** List of partial integration objects */ - integrations: Partial[] + integrations: Partial[]; /** * List of threads found in the audit log. * * @remarks * Threads referenced in `THREAD_CREATE` and `THREAD_UPDATE` events are included in the threads map since archived threads might not be kept in memory by clients. */ - threads: DiscordChannel[] + threads: DiscordChannel[]; /** List of users found in the audit log */ - users: DiscordUser[] + users: DiscordUser[]; /** List of webhooks found in the audit log */ - webhooks: DiscordWebhook[] + webhooks: DiscordWebhook[]; } /** https://discord.com/developers/docs/resources/audit-log#audit-log-entry-object-audit-log-entry-structure */ export interface DiscordAuditLogEntry { /** ID of the affected entity (webhook, user, role, etc.) */ - target_id: string | null + target_id: string | null; /** Changes made to the `target_id` */ - changes?: DiscordAuditLogChange[] + changes?: DiscordAuditLogChange[]; /** User or app that made the changes */ - user_id: string | null + user_id: string | null; /** ID of the entry */ - id: string + id: string; /** Type of action that occurred */ - action_type: AuditLogEvents + action_type: AuditLogEvents; /** Additional info for certain event types */ - options?: DiscordOptionalAuditEntryInfo + options?: DiscordOptionalAuditEntryInfo; /** Reason for the change (1-512 characters) */ - reason?: string + reason?: string; } /** https://discord.com/developers/docs/resources/audit-log#audit-log-entry-object-audit-log-events */ @@ -216,7 +216,7 @@ export type DiscordAuditLogChange = | DiscordAuditLogChangeObject | DiscordAuditLogChangeObject | DiscordAuditLogChangeObject - | DiscordAuditLogChangeObject + | DiscordAuditLogChangeObject; /** https://discord.com/developers/docs/resources/audit-log#audit-log-entry-object-optional-audit-entry-info */ export interface DiscordOptionalAuditEntryInfo { @@ -226,100 +226,100 @@ export interface DiscordOptionalAuditEntryInfo { * @remarks * Oly present on event of type: `APPLICATION_COMMAND_PERMISSION_UPDATE` */ - application_id?: string + application_id?: string; /** * Name of the Auto Moderation rule that was triggered. * * @remarks * Only present on event of types: `AUTO_MODERATION_BLOCK_MESSAGE`, `AUTO_MODERATION_FLAG_TO_CHANNEL`, `AUTO_MODERATION_USER_COMMUNICATION_DISABLED`, `AUTO_MODERATION_QUARANTINE_USER` */ - auto_moderation_rule_name?: string + auto_moderation_rule_name?: string; /** * Trigger type of the Auto Moderation rule that was triggered. * * @remarks * Only present on event of types: `AUTO_MODERATION_BLOCK_MESSAGE`, `AUTO_MODERATION_FLAG_TO_CHANNEL`, `AUTO_MODERATION_USER_COMMUNICATION_DISABLED`, `AUTO_MODERATION_QUARANTINE_USER` */ - auto_moderation_rule_trigger_type?: string + auto_moderation_rule_trigger_type?: string; /** * Channel in which the entities were targeted. * * @remarks * Only present on event of types: `MEMBER_MOVE`, `MESSAGE_PIN`, `MESSAGE_UNPIN`, `MESSAGE_DELETE`, `STAGE_INSTANCE_CREATE`, `STAGE_INSTANCE_UPDATE`, `STAGE_INSTANCE_DELETE`, `AUTO_MODERATION_BLOCK_MESSAGE`, `AUTO_MODERATION_FLAG_TO_CHANNEL`, `AUTO_MODERATION_USER_COMMUNICATION_DISABLED`, `AUTO_MODERATION_QUARANTINE_USER` */ - channel_id?: string + channel_id?: string; /** * Number of entities that were targeted. * * @remarks * Only present on event of types: `MESSAGE_DELETE`, `MESSAGE_BULK_DELETE`, `MEMBER_DISCONNECT`, `MEMBER_MOVE` */ - count?: string + count?: string; /** * Number of days after which inactive members were kicked. * * @remarks * Only present on event of type: `MEMBER_PRUNE` */ - delete_member_days?: string + delete_member_days?: string; /** * ID of the overwritten entity. * * @remarks * Only present on event of types: `CHANNEL_OVERWRITE_CREATE`, `CHANNEL_OVERWRITE_UPDATE`, `CHANNEL_OVERWRITE_DELETE` */ - id?: string + id?: string; /** * Number of members removed by the prune. * * @remarks * Only present on event of types: `MEMBER_PRUNE` */ - members_removed?: string + members_removed?: string; /** * ID of the message that was targeted. * * @remarks * Only present on event of types: `MESSAGE_PIN`, `MESSAGE_UNPIN`, `STAGE_INSTANCE_CREATE`, `STAGE_INSTANCE_UPDATE`, `STAGE_INSTANCE_DELETE` */ - message_id?: string + message_id?: string; /** * Name of the role if type is "0" (not present if type is "1"). * * @remarks * Only present on event of types: `CHANNEL_OVERWRITE_CREATE`, `CHANNEL_OVERWRITE_UPDATE`, `CHANNEL_OVERWRITE_DELETE` */ - role_name?: string + role_name?: string; /** * Type of overwritten entity - "0", for "role", or "1" for "member". * * @remarks * Only present on event of types: `CHANNEL_OVERWRITE_CREATE`, `CHANNEL_OVERWRITE_UPDATE`, `CHANNEL_OVERWRITE_DELETE` */ - type?: string + type?: string; /** * The type of integration which performed the action * * @remarks * Only present on event of types: `MEMBER_KICK`, `MEMBER_ROLE_UPDATE` */ - integration_type?: string + integration_type?: string; } /** https://discord.com/developers/docs/resources/audit-log#audit-log-change-object-audit-log-change-structure */ export type DiscordAuditLogChangeObject = NonNullable< { [K in keyof T]: { - new_value?: T[K] - old_value?: T[K] - key: K - } + new_value?: T[K]; + old_value?: T[K]; + key: K; + }; }[keyof T] -> +>; // Done manually as it is clearer in this way /** Partial role audit log entry change exception */ -export type DiscordAuditLogChangePartialRole = { new_value: { id: string; name: string }[]; key: '$add' | '$remove' } +export type DiscordAuditLogChangePartialRole = { new_value: { id: string; name: string }[]; key: '$add' | '$remove' }; /** * Invite audit log entry change exception @@ -327,7 +327,7 @@ export type DiscordAuditLogChangePartialRole = { new_value: { id: string; name: * @remarks * While the docs say that 'channel.id' will never exist, we keep it as it is very complex to remove, the user should not use it and use the provided 'channel_id' value instead */ -export type DiscordAuditLogChangeInvite = DiscordAuditLogChangeObject | DiscordAuditLogChangeObject<{ channel_id: string }> +export type DiscordAuditLogChangeInvite = DiscordAuditLogChangeObject | DiscordAuditLogChangeObject<{ channel_id: string }>; /** * Invite Metadata audit log entry change exception @@ -337,17 +337,17 @@ export type DiscordAuditLogChangeInvite = DiscordAuditLogChangeObject - | DiscordAuditLogChangeObject<{ channel_id: string }> + | DiscordAuditLogChangeObject<{ channel_id: string }>; /** Webhook audit log entry change exception */ export type DiscordAuditLogChangeWebhook = | DiscordAuditLogChangeObject> - | DiscordAuditLogChangeObject<{ avatar_hash: DiscordWebhook['avatar'] }> + | DiscordAuditLogChangeObject<{ avatar_hash: DiscordWebhook['avatar'] }>; // Done manually as it is clearer in this way /** Command Permission audit log entry change exception */ export type DiscordAuditLogChangeApplicationCommandPermissions = { - new_value?: DiscordApplicationCommandPermissions - old_value?: DiscordApplicationCommandPermissions - key: `${number}` -} + new_value?: DiscordApplicationCommandPermissions; + old_value?: DiscordApplicationCommandPermissions; + key: `${number}`; +}; diff --git a/packages/types/src/discord/autoModeration.ts b/packages/types/src/discord/autoModeration.ts index b5ab270d8..710def488 100644 --- a/packages/types/src/discord/autoModeration.ts +++ b/packages/types/src/discord/autoModeration.ts @@ -3,27 +3,27 @@ /** https://discord.com/developers/docs/resources/auto-moderation#auto-moderation-rule-object-auto-moderation-rule-structure */ export interface DiscordAutoModerationRule { /** The id of this rule */ - id: string + id: string; /** The guild id of the rule */ - guild_id: string + guild_id: string; /** The name of the rule */ - name: string + name: string; /** The id of the user who created this rule. */ - creator_id: string + creator_id: string; /** Indicates in what event context a rule should be checked. */ - event_type: AutoModerationEventTypes + event_type: AutoModerationEventTypes; /** The type of trigger for this rule */ - trigger_type: AutoModerationTriggerTypes + trigger_type: AutoModerationTriggerTypes; /** The metadata used to determine whether a rule should be triggered. */ - trigger_metadata: DiscordAutoModerationRuleTriggerMetadata + trigger_metadata: DiscordAutoModerationRuleTriggerMetadata; /** Actions which will execute whenever a rule is triggered. */ - actions: DiscordAutoModerationAction[] + actions: DiscordAutoModerationAction[]; /** Whether the rule is enabled. */ - enabled: boolean + enabled: boolean; /** The role ids that are whitelisted. Max 20. */ - exempt_roles: string[] + exempt_roles: string[]; /** The channel ids that are whitelisted. Max 50. */ - exempt_channels: string[] + exempt_channels: string[]; } /** https://discord.com/developers/docs/resources/auto-moderation#auto-moderation-rule-object-trigger-types */ @@ -50,7 +50,7 @@ export interface DiscordAutoModerationRuleTriggerMetadata { * * Can have up to 1000 elements in the array and each string can have up to 60 characters. */ - keyword_filter?: string[] + keyword_filter?: string[]; /** * Regular expression patterns which will be matched against content. * @@ -59,14 +59,14 @@ export interface DiscordAutoModerationRuleTriggerMetadata { * * Only Rust flavored regex is currently supported. Can have up to 10 elements in the array and each string can have up to 260 characters. */ - regex_patterns?: string[] + regex_patterns?: string[]; /** * The Discord pre-defined wordsets which will be searched for in content. * * @remarks * Only present with {@link AutoModerationTriggerTypes.KeywordPreset}. */ - presets?: DiscordAutoModerationRuleTriggerMetadataPresets[] + presets?: DiscordAutoModerationRuleTriggerMetadataPresets[]; /** * The substrings which should not trigger the rule. * @@ -76,7 +76,7 @@ export interface DiscordAutoModerationRuleTriggerMetadata { * When used with {@link AutoModerationTriggerTypes.Keyword} and {@link AutoModerationTriggerTypes.MemberProfile}, there can be up to 100 elements in the array and each string can have up to 60 characters. * When used with {@link AutoModerationTriggerTypes.KeywordPreset}, there can be up to 1000 elements in the array and each string can have up to 60 characters. */ - allow_list?: string[] + allow_list?: string[]; /** * Total number of unique role and user mentions allowed per message. * @@ -85,14 +85,14 @@ export interface DiscordAutoModerationRuleTriggerMetadata { * * Maximum of 50 */ - mention_total_limit?: number + mention_total_limit?: number; /** * Whether to automatically detect mention raids. * * @remarks * Only present with {@link AutoModerationTriggerTypes.MentionSpam}. */ - mention_raid_protection_enabled?: boolean + mention_raid_protection_enabled?: boolean; } /** https://discord.com/developers/docs/resources/auto-moderation#auto-moderation-rule-object-keyword-preset-types */ @@ -116,9 +116,9 @@ export enum AutoModerationEventTypes { /** https://discord.com/developers/docs/resources/auto-moderation#auto-moderation-action-object-auto-moderation-action-structure */ export interface DiscordAutoModerationAction { /** The type of action to take when a rule is triggered */ - type: AutoModerationActionType + type: AutoModerationActionType; /** additional metadata needed during execution for this specific action type */ - metadata?: DiscordAutoModerationActionMetadata + metadata?: DiscordAutoModerationActionMetadata; } /** https://discord.com/developers/docs/resources/auto-moderation#auto-moderation-action-object-action-types */ @@ -148,7 +148,7 @@ export interface DiscordAutoModerationActionMetadata { * @remarks * Only for actions of type {@link AutoModerationActionType.SendAlertMessage}. */ - channel_id?: string + channel_id?: string; /** * Timeout duration in seconds. * @@ -157,7 +157,7 @@ export interface DiscordAutoModerationActionMetadata { * * Maximum of 2419200 seconds (4 weeks). */ - duration_seconds?: number + duration_seconds?: number; /** * Additional explanation that will be shown to members whenever their message is blocked. * @@ -168,5 +168,5 @@ export interface DiscordAutoModerationActionMetadata { * * Maximum of 150 characters. */ - custom_message?: string + custom_message?: string; } diff --git a/packages/types/src/discord/channel.ts b/packages/types/src/discord/channel.ts index 698a9a1cb..ac0ba2c43 100644 --- a/packages/types/src/discord/channel.ts +++ b/packages/types/src/discord/channel.ts @@ -1,48 +1,48 @@ /** Types for: https://discord.com/developers/docs/resources/channel */ -import type { DiscordThreadCreateExtra } from './gateway.js' -import type { DiscordMember } from './guild.js' -import type { DiscordUser } from './user.js' +import type { DiscordThreadCreateExtra } from './gateway.js'; +import type { DiscordMember } from './guild.js'; +import type { DiscordUser } from './user.js'; /** https://discord.com/developers/docs/resources/channel#channel-object-channel-structure */ export interface DiscordChannel extends Partial { /** The id of the channel */ - id: string + id: string; /** The type of channel */ - type: ChannelTypes + type: ChannelTypes; /** * The id of the guild * * @remarks * May be missing for some channel object received over gateway guild dispatches */ - guild_id?: string + guild_id?: string; /** * Sorting position of the channel * * @remarks * Channels with the same position are sorted by id */ - position?: number + position?: number; /** Explicit permission overwrites for members and roles */ - permission_overwrites?: DiscordOverwrite[] + permission_overwrites?: DiscordOverwrite[]; /** The name of the channel (1-100 characters) */ - name?: string + name?: string; /** * The channel topic * * @remarks * The limit is max of 4096 characters for GUILD_FORUM channels and a max of 1024 characters for all others channel types */ - topic?: string | null + topic?: string | null; /** Whether the channel is nsfw */ - nsfw?: boolean + nsfw?: boolean; /** The id of the last message sent in this channel (may not point to an existing or valid message or thread) */ - last_message_id?: string | null + last_message_id?: string | null; /** The bitrate (in bits) of the voice or stage channel */ - bitrate?: number + bitrate?: number; /** The user limit of the voice or stage channel */ - user_limit?: number + user_limit?: number; /** * Amount of seconds a user has to wait before sending another message (0-21600) * @@ -50,17 +50,17 @@ export interface DiscordChannel extends Partial { * Bots, as well as users with the permission `manage_messages` or `manage_channel`, are unaffected * `rate_limit_per_user` also applies to thread creation. Users can send one message and create one thread during each `rate_limit_per_user` interval. */ - rate_limit_per_user?: number + rate_limit_per_user?: number; /** the recipients of the DM */ - recipients?: DiscordUser[] + recipients?: DiscordUser[]; /** icon hash of the group DM */ - icon?: string + icon?: string; /** Id of the creator of the group DM or the thread */ - owner_id?: string + owner_id?: string; /** Application id of the group DM creator if it is bot-created */ - application_id?: string + application_id?: string; /** For group DM channels: whether the channel is managed by an application via the `gdm.join` OAuth2 scope. */ - managed?: boolean + managed?: boolean; /** * Id of the parent channel. * @@ -69,18 +69,18 @@ export interface DiscordChannel extends Partial { * * For threads this will reference the text channel the thread was created in. */ - parent_id?: string | null + parent_id?: string | null; /** * When the last pinned message was pinned. * * @remarks * This may be null in events such as GUILD_CREATE when a message is not pinned. */ - last_pin_timestamp?: string | null + last_pin_timestamp?: string | null; /** Voice region id for the voice or stage channel, automatic when set to null */ - rtc_region?: string | null + rtc_region?: string | null; /** The camera video quality mode of the voice channel, 1 when not present */ - video_quality_mode?: VideoQualityModes + video_quality_mode?: VideoQualityModes; /** * An approximate count of messages in a thread, does not include deleted messages or the initial message @@ -88,20 +88,20 @@ export interface DiscordChannel extends Partial { * @remarks * For threads created before July 1, 2022, the message count is inaccurate when it's greater than 50. */ - message_count?: number + message_count?: number; /** An approximate count of users in a thread, stops counting at 50 */ - member_count?: number + member_count?: number; /** Thread-specific fields not needed by other channels */ - thread_metadata?: DiscordThreadMetadata + thread_metadata?: DiscordThreadMetadata; /** Thread member object for the current user, if they have joined the thread, only included on certain API endpoints */ - member?: DiscordThreadMember + member?: DiscordThreadMember; /** * Default duration for newly created threads, in minutes, to automatically archive the thread after recent activity. * * @remarks * Can be set to: 60, 1440, 4320, 10080 */ - default_auto_archive_duration?: number + default_auto_archive_duration?: number; /** * Computed permissions for the invoking user in the channel. * @@ -110,28 +110,28 @@ export interface DiscordChannel extends Partial { * * Only presented when part of `resolved` data received on an interaction. */ - permissions?: string + permissions?: string; /** The flags of the channel */ - flags?: ChannelFlags + flags?: ChannelFlags; /** number of messages ever sent in a thread, it's similar to `message_count` on message creation, but will not decrement the number when a message is deleted */ - total_message_sent?: number + total_message_sent?: number; /** The set of tags that can be used in a GUILD_FORUM or GUILD_MEDIA channel */ - available_tags?: DiscordForumTag[] + available_tags?: DiscordForumTag[]; /** The IDs of the set of tags that have been applied to a thread in a GUILD_FORUM or GUILD_MEDIA channel */ - applied_tags?: string[] + applied_tags?: string[]; /** the emoji to show in the add reaction button on a thread in a GUILD_FORUM or GUILD_MEDIA channel */ - default_reaction_emoji?: DiscordDefaultReactionEmoji | null + default_reaction_emoji?: DiscordDefaultReactionEmoji | null; /** * The initial `rate_limit_per_user` to set on newly created threads in a channel. * * @remarks * This field is copied to the thread at creation time and does not live update. */ - default_thread_rate_limit_per_user?: number + default_thread_rate_limit_per_user?: number; /** the default sort order type used to order posts in GUILD_FORUM channels. Defaults to null, which indicates a preferred sort order hasn't been set by a channel admin */ - default_sort_order?: SortOrderTypes | null + default_sort_order?: SortOrderTypes | null; /** the default forum layout view used to display posts in `GUILD_FORUM` channels. Defaults to `0`, which indicates a layout view has not been set by a channel admin */ - default_forum_layout?: ForumLayout + default_forum_layout?: ForumLayout; } /** https://discord.com/developers/docs/resources/channel#channel-object-channel-types */ @@ -204,9 +204,9 @@ export enum ForumLayout { /** https://discord.com/developers/docs/resources/channel#followed-channel-object-followed-channel-structure */ export interface DiscordFollowedChannel { /** Source message id */ - channel_id: string + channel_id: string; /** Created target webhook id */ - webhook_id: string + webhook_id: string; } /** https://discord.com/developers/docs/resources/channel#overwrite-object-overwrite-structure */ @@ -218,29 +218,29 @@ export enum OverwriteTypes { /** https://discord.com/developers/docs/resources/channel#overwrite-object-overwrite-structure */ export interface DiscordOverwrite { /** Either 0 (role) or 1 (member) */ - type: OverwriteTypes + type: OverwriteTypes; /** Role or user id */ - id: string + id: string; /** Permission bit set */ - allow?: string + allow?: string; /** Permission bit set */ - deny?: string + deny?: string; } /** https://discord.com/developers/docs/resources/channel#thread-metadata-object-thread-metadata-structure */ export interface DiscordThreadMetadata { /** Whether the thread is archived */ - archived: boolean + archived: boolean; /** Duration in minutes to automatically archive the thread after recent activity */ - auto_archive_duration: 60 | 1440 | 4320 | 10080 + auto_archive_duration: 60 | 1440 | 4320 | 10080; /** Timestamp when the thread's archive status was last changed, used for calculating recent activity */ - archive_timestamp: string + archive_timestamp: string; /** When a thread is locked, only users with `MANAGE_THREADS` can unarchive it */ - locked: boolean + locked: boolean; /** whether non-moderators can add other non-moderators to a thread; only available on private threads */ - invitable?: boolean + invitable?: boolean; /** Timestamp when the thread was created; only populated for threads created after 2022-01-09 */ - create_timestamp?: string | null + create_timestamp?: string | null; } /** https://discord.com/developers/docs/resources/channel#thread-member-object-thread-member-structure */ @@ -251,18 +251,18 @@ export interface DiscordThreadMember { * @remarks * This value is omtted when sent from a `GUILD_CREATE` event */ - id: string + id: string; /** * The id of the user * * @remarks * This value is omtted when sent from a `GUILD_CREATE` event */ - user_id: string + user_id: string; /** The time the current user last joined the thread */ - join_timestamp: string + join_timestamp: string; /** Any user-thread settings, currently only used for notifications */ - flags: number + flags: number; /** * The member object of the user * @@ -271,7 +271,7 @@ export interface DiscordThreadMember { * * Only present when `with_member` is true when calling the List Thread Members and Get Thread Member endpoints, */ - member?: DiscordMember + member?: DiscordMember; } /** https://discord.com/developers/docs/resources/channel#thread-member-object-thread-member-structure, the first asterisk */ @@ -280,23 +280,23 @@ export interface DiscordThreadMemberGuildCreate extends Omit + emoji?: Pick; /** * A dev-defined unique string sent on click (max 100 characters). * * @remarks * A button of style {@link ButtonStyles.Link | Link} or {@link ButtonStyles.Premium | Premium} cannot have a custom_id */ - custom_id?: string + custom_id?: string; /** * Identifier for a purchasable SKU * * @remarks * Buttons of style {@link ButtonStyles.Premium | Premium} must have a sku_id, any other button with a different style can not have a a sku_id */ - sku_id?: string + sku_id?: string; /** * Url for {@link ButtonStyles.Link | link} buttons that can navigate a user to the web. * @@ -138,9 +138,9 @@ export interface DiscordButtonComponent extends DiscordBaseComponent { * * Maximum 512 characters. */ - url?: string + url?: string; /** Whether or not this button is disabled */ - disabled?: boolean + disabled?: boolean; } /** https://discord.com/developers/docs/components/reference#button-button-styles */ @@ -172,18 +172,18 @@ export interface DiscordSelectMenuComponent extends DiscordBaseComponent { | MessageComponentTypes.UserSelect | MessageComponentTypes.RoleSelect | MessageComponentTypes.MentionableSelect - | MessageComponentTypes.ChannelSelect + | MessageComponentTypes.ChannelSelect; /** A custom identifier for this component. Maximum 100 characters. */ - custom_id: string + custom_id: string; /** Specified choices in a select menu; Maximum of 25 items. */ - options?: DiscordSelectOption[] + options?: DiscordSelectOption[]; /** A custom placeholder text if nothing is selected. Maximum 150 characters. */ - placeholder?: string + placeholder?: string; /** The minimum number of items that must be selected. Default 1. Between 0-25. */ - min_values?: number + min_values?: number; /** The maximum number of items that can be selected. Default 1. Max 25. */ - max_values?: number + max_values?: number; /** * Whether this component is required to be filled * @@ -192,7 +192,7 @@ export interface DiscordSelectMenuComponent extends DiscordBaseComponent { * * @default true */ - required?: boolean + required?: boolean; /** * Whether select menu is disabled * @@ -201,30 +201,30 @@ export interface DiscordSelectMenuComponent extends DiscordBaseComponent { * * @default false */ - disabled?: boolean + disabled?: boolean; /** * List of default values for auto-populated select menu components * * @remarks * The number of default values must be in the range defined by min_values and max_values */ - default_values?: DiscordSelectMenuDefaultValue[] + default_values?: DiscordSelectMenuDefaultValue[]; /** List of channel types to include in a channel select menu options list */ - channel_types?: ChannelTypes[] + channel_types?: ChannelTypes[]; } /** https://discord.com/developers/docs/components/reference#string-select-select-option-structure */ export interface DiscordSelectOption { /** The user-facing name of the option. Maximum 25 characters. */ - label: string + label: string; /** The dev-defined value of the option. Maximum 100 characters. */ - value: string + value: string; /** An additional description of the option. Maximum 50 characters. */ - description?: string + description?: string; /** The id, name, and animated properties of an emoji. */ - emoji?: Pick + emoji?: Pick; /** Will render this option as already-selected by default. */ - default?: boolean + default?: boolean; } /** https://discord.com/developers/docs/components/reference#string-select-strings-select-interaction-response-structure */ @@ -233,36 +233,36 @@ export interface DiscordStringSelectInteractionResponse { * @remarks * This is only returned for interaction responses from modals */ - type?: MessageComponentTypes.StringSelect + type?: MessageComponentTypes.StringSelect; /** * @remarks * This is only returned for interaction responses from message interactions */ - component_type?: MessageComponentTypes.StringSelect + component_type?: MessageComponentTypes.StringSelect; /** 32 bit integer used as an optional identifier for component */ - id: number + id: number; /** The custom id for the string select menu */ - custom_id: string + custom_id: string; /** The text of the selected options */ - values: string[] + values: string[]; } /** https://discord.com/developers/docs/components/reference#string-select-string-select-interaction-response-structure */ -export type DiscordStringSelectInteractionResponseFromModal = Require, 'type'> +export type DiscordStringSelectInteractionResponseFromModal = Require, 'type'>; /** https://discord.com/developers/docs/components/reference#string-select-string-select-interaction-response-structure */ export type DiscordStringSelectInteractionResponseFromMessageComponent = Require< Omit, 'component_type' -> +>; /** https://discord.com/developers/docs/components/reference#text-input-text-input-structure */ export interface DiscordTextInputComponent extends DiscordBaseComponent { - type: MessageComponentTypes.TextInput + type: MessageComponentTypes.TextInput; /** The customId of the InputText */ - custom_id: string + custom_id: string; /** The style of the InputText */ - style: TextStyles + style: TextStyles; /** * The label of the InputText. * @@ -271,17 +271,17 @@ export interface DiscordTextInputComponent extends DiscordBaseComponent { * * @deprecated Use the `label` and `description` from the {@link DiscordLabelComponent} */ - label?: string + label?: string; /** The minimum length of the text the user has to provide */ - min_length?: number + min_length?: number; /** The maximum length of the text the user has to provide */ - max_length?: number + max_length?: number; /** whether this component is required to be filled, default true */ - required?: boolean + required?: boolean; /** Pre-filled value for input text. */ - value?: string + value?: string; /** The placeholder of the InputText */ - placeholder?: string + placeholder?: string; } /** https://discord.com/developers/docs/components/reference#text-input-text-input-styles */ @@ -294,21 +294,21 @@ export enum TextStyles { /** https://discord.com/developers/docs/components/reference#text-input-text-input-interaction-response-structure */ export interface DiscordTextInputInteractionResponse { - type: MessageComponentTypes.TextInput + type: MessageComponentTypes.TextInput; /** 32 bit integer used as an optional identifier for component */ - id: number + id: number; /** The custom id for the text input */ - custom_id: string + custom_id: string; /** The user's input text */ - value: string + value: string; } /** https://discord.com/developers/docs/components/reference#user-select-select-default-value-structure */ export interface DiscordSelectMenuDefaultValue { /** ID of a user, role, or channel */ - id: string + id: string; /** Type of value that id represents. */ - type: 'user' | 'role' | 'channel' + type: 'user' | 'role' | 'channel'; } /** https://discord.com/developers/docs/components/reference#user-select-user-select-interaction-response-structure */ @@ -317,26 +317,26 @@ export interface DiscordUserSelectInteractionResponse { * @remarks * This is only returned for interaction responses from modals */ - type?: MessageComponentTypes.UserSelect + type?: MessageComponentTypes.UserSelect; /** * @remarks * This is only returned for interaction responses from message interactions */ - component_type?: MessageComponentTypes.UserSelect + component_type?: MessageComponentTypes.UserSelect; /** 32 bit integer used as an optional identifier for component */ - id: number + id: number; /** The custom id for the user select */ - custom_id: string + custom_id: string; /** Resolved entities from selected options */ - resolved: DiscordInteractionDataResolved + resolved: DiscordInteractionDataResolved; /** IDs of the selected users */ - values: string[] + values: string[]; } /** https://discord.com/developers/docs/components/reference#user-select-user-select-interaction-response-structure */ -export type DiscordUserSelectInteractionResponseFromModal = Require, 'type'> +export type DiscordUserSelectInteractionResponseFromModal = Require, 'type'>; /** https://discord.com/developers/docs/components/reference#user-select-user-select-interaction-response-structure */ -export type DiscordUserSelectInteractionResponseFromMessageComponent = Require, 'component_type'> +export type DiscordUserSelectInteractionResponseFromMessageComponent = Require, 'component_type'>; /** https://discord.com/developers/docs/components/reference#role-select-role-select-interaction-response-structure */ export interface DiscordRoleSelectInteractionResponse { @@ -344,26 +344,26 @@ export interface DiscordRoleSelectInteractionResponse { * @remarks * This is only returned for interaction responses from modals */ - type?: MessageComponentTypes.RoleSelect + type?: MessageComponentTypes.RoleSelect; /** * @remarks * This is only returned for interaction responses from message interactions */ - component_type?: MessageComponentTypes.RoleSelect + component_type?: MessageComponentTypes.RoleSelect; /** 32 bit integer used as an optional identifier for component */ - id: number + id: number; /** The custom id for the role select */ - custom_id: string + custom_id: string; /** Resolved entities from selected options */ - resolved: DiscordInteractionDataResolved + resolved: DiscordInteractionDataResolved; /** IDs of the selected roles */ - values: string[] + values: string[]; } /** https://discord.com/developers/docs/components/reference#role-select-role-select-interaction-response-structure */ -export type DiscordRoleSelectInteractionResponseFromModal = Require, 'type'> +export type DiscordRoleSelectInteractionResponseFromModal = Require, 'type'>; /** https://discord.com/developers/docs/components/reference#role-select-role-select-interaction-response-structure */ -export type DiscordRoleSelectInteractionResponseFromMessageComponent = Require, 'component_type'> +export type DiscordRoleSelectInteractionResponseFromMessageComponent = Require, 'component_type'>; /** https://discord.com/developers/docs/components/reference#mentionable-select-mentionable-select-interaction-response-structure */ export interface DiscordMentionableSelectInteractionResponse { @@ -371,32 +371,32 @@ export interface DiscordMentionableSelectInteractionResponse { * @remarks * This is only returned for interaction responses from modals */ - type?: MessageComponentTypes.MentionableSelect + type?: MessageComponentTypes.MentionableSelect; /** * @remarks * This is only returned for interaction responses from message interactions */ - component_type?: MessageComponentTypes.MentionableSelect + component_type?: MessageComponentTypes.MentionableSelect; /** 32 bit integer used as an optional identifier for component */ - id: number + id: number; /** The custom id for the mentionable select */ - custom_id: string + custom_id: string; /** Resolved entities from selected options */ - resolved: DiscordInteractionDataResolved + resolved: DiscordInteractionDataResolved; /** IDs of the selected mentionables */ - values: string[] + values: string[]; } /** https://discord.com/developers/docs/components/reference#mentionable-select-mentionable-select-interaction-response-structure */ export type DiscordMentionableSelectInteractionResponseFromModal = Require< Omit, 'type' -> +>; /** https://discord.com/developers/docs/components/reference#mentionable-select-mentionable-select-interaction-response-structure */ export type DiscordMentionableSelectInteractionResponseFromMessageComponent = Require< Omit, 'component_type' -> +>; /** https://discord.com/developers/docs/components/reference#channel-select-channel-select-interaction-response-structure */ export interface DiscordChannelSelectInteractionResponse { @@ -404,106 +404,106 @@ export interface DiscordChannelSelectInteractionResponse { * @remarks * This is only returned for interaction responses from modals */ - type?: MessageComponentTypes.ChannelSelect + type?: MessageComponentTypes.ChannelSelect; /** * @remarks * This is only returned for interaction responses from message interactions */ - component_type?: MessageComponentTypes.ChannelSelect + component_type?: MessageComponentTypes.ChannelSelect; /** 32 bit integer used as an optional identifier for component */ - id: number + id: number; /** The custom id for the channel select */ - custom_id: string + custom_id: string; /** Resolved entities from selected options */ - resolved: DiscordInteractionDataResolved + resolved: DiscordInteractionDataResolved; /** IDs of the selected channels */ - values: string[] + values: string[]; } /** https://discord.com/developers/docs/components/reference#channel-select-channel-select-interaction-response-structure */ -export type DiscordChannelSelectInteractionResponseFromModal = Require, 'type'> +export type DiscordChannelSelectInteractionResponseFromModal = Require, 'type'>; /** https://discord.com/developers/docs/components/reference#channel-select-channel-select-interaction-response-structure */ export type DiscordChannelSelectInteractionResponseFromMessageComponent = Require< Omit, 'component_type' -> +>; /** https://discord.com/developers/docs/components/reference#section-section-structure */ export interface DiscordSectionComponent extends DiscordBaseComponent { - type: MessageComponentTypes.Section + type: MessageComponentTypes.Section; /** One to three text components */ - components: DiscordTextDisplayComponent[] + components: DiscordTextDisplayComponent[]; /** A thumbnail or a button component, with a future possibility of adding more compatible components */ - accessory: DiscordButtonComponent | DiscordThumbnailComponent + accessory: DiscordButtonComponent | DiscordThumbnailComponent; } /** https://discord.com/developers/docs/components/reference#text-display-text-display-structure */ export interface DiscordTextDisplayComponent extends DiscordBaseComponent { - type: MessageComponentTypes.TextDisplay + type: MessageComponentTypes.TextDisplay; /** Text that will be displayed similar to a message */ - content: string + content: string; } /** https://discord.com/developers/docs/components/reference#text-display-text-display-interaction-response-structure */ export interface DiscordTextDisplayInteractionResponse { - type: MessageComponentTypes.TextDisplay + type: MessageComponentTypes.TextDisplay; /** 32 bit integer used as an optional identifier for component */ - id: number + id: number; } export interface DiscordThumbnailComponent extends DiscordBaseComponent { - type: MessageComponentTypes.Thumbnail + type: MessageComponentTypes.Thumbnail; /** A url or attachment */ - media: DiscordUnfurledMediaItem + media: DiscordUnfurledMediaItem; /** Alt text for the media, max 1024 characters */ - description?: string + description?: string; /** Whether the thumbnail should be a spoiler (or blurred out). Defaults to `false` */ - spoiler?: boolean + spoiler?: boolean; } /** https://discord.com/developers/docs/components/reference#media-gallery-media-gallery-structure */ export interface DiscordMediaGalleryComponent extends DiscordBaseComponent { - type: MessageComponentTypes.MediaGallery + type: MessageComponentTypes.MediaGallery; /** 1 to 10 media gallery items */ - items: DiscordMediaGalleryItem[] + items: DiscordMediaGalleryItem[]; } /** https://discord.com/developers/docs/components/reference#media-gallery-media-gallery-item-structure */ export interface DiscordMediaGalleryItem { /** A url or attachment */ - media: DiscordUnfurledMediaItem + media: DiscordUnfurledMediaItem; /** Alt text for the media, max 1024 characters */ - description?: string + description?: string; /** Whether the media should be a spoiler (or blurred out). Defaults to `false` */ - spoiler?: boolean + spoiler?: boolean; } /** https://discord.com/developers/docs/components/reference#file-file-structure */ export interface DiscordFileComponent extends DiscordBaseComponent { - type: MessageComponentTypes.File + type: MessageComponentTypes.File; /** This unfurled media item is unique in that it only supports attachment references using the attachment:// syntax */ - file: DiscordUnfurledMediaItem + file: DiscordUnfurledMediaItem; /** Whether the media should be a spoiler (or blurred out). Defaults to `false` */ - spoiler?: boolean + spoiler?: boolean; /** The name of the file. This field is ignored and provided by the API as part of the response */ - name: string + name: string; /** The size of the file in bytes. This field is ignored and provided by the API as part of the response */ - size: number + size: number; } /** https://discord.com/developers/docs/components/reference#separator-separator-structure */ export interface DiscordSeparatorComponent extends DiscordBaseComponent { - type: MessageComponentTypes.Separator + type: MessageComponentTypes.Separator; /** Whether a visual divider should be displayed in the component. Defaults to `true` */ - divider?: boolean + divider?: boolean; /** Size of separator padding — `1` for small padding, `2` for large padding. Defaults to `1` */ - spacing?: SeparatorSpacingSize + spacing?: SeparatorSpacingSize; } /** https://discord.com/developers/docs/components/reference#separator-separator-structure, spacing description */ @@ -514,7 +514,7 @@ export enum SeparatorSpacingSize { /** https://discord.com/developers/docs/components/reference#container-container-structure */ export interface DiscordContainerComponent extends DiscordBaseComponent { - type: MessageComponentTypes.Container + type: MessageComponentTypes.Container; /** Components of the type action row, text display, section, media gallery, separator, or file */ components: Array< @@ -524,16 +524,16 @@ export interface DiscordContainerComponent extends DiscordBaseComponent { | DiscordMediaGalleryComponent | DiscordSeparatorComponent | DiscordFileComponent - > + >; /** Color for the accent on the container as RGB from 0x000000 to 0xFFFFFF */ - accent_color?: number | null + accent_color?: number | null; /** Whether the container should be a spoiler (or blurred out). Defaults to `false` */ - spoiler?: boolean + spoiler?: boolean; } /** https://discord.com/developers/docs/components/reference#label-label-structure */ export interface DiscordLabelComponent extends DiscordBaseComponent { - type: MessageComponentTypes.Label + type: MessageComponentTypes.Label; /** * The label text @@ -541,23 +541,23 @@ export interface DiscordLabelComponent extends DiscordBaseComponent { * @remarks * Max 45 characters. */ - label: string + label: string; /** * An optional description text for the label * * @remarks * Max 100 characters. */ - description?: string + description?: string; /** The component within the label */ - component: DiscordTextInputComponent | DiscordSelectMenuComponent | DiscordFileUploadComponent + component: DiscordTextInputComponent | DiscordSelectMenuComponent | DiscordFileUploadComponent; } /** https://discord.com/developers/docs/components/reference#label-label-interaction-response-structure */ export interface DiscordLabelInteractionResponse { - type: MessageComponentTypes.Label + type: MessageComponentTypes.Label; /** 32 bit integer used as an optional identifier for component */ - id: number + id: number; /** The component within the label */ component: | DiscordTextInputInteractionResponse @@ -566,15 +566,15 @@ export interface DiscordLabelInteractionResponse { | DiscordRoleSelectInteractionResponseFromModal | DiscordMentionableSelectInteractionResponseFromModal | DiscordChannelSelectInteractionResponseFromModal - | DiscordFileUploadInteractionResponse + | DiscordFileUploadInteractionResponse; } /** https://discord.com/developers/docs/components/reference#file-upload-file-upload-structure */ export interface DiscordFileUploadComponent extends DiscordBaseComponent { - type: MessageComponentTypes.FileUpload + type: MessageComponentTypes.FileUpload; /** The custom id for the file upload */ - custom_id: string + custom_id: string; /** * The minimum number of files that must be uploaded * @@ -583,7 +583,7 @@ export interface DiscordFileUploadComponent extends DiscordBaseComponent { * * @default 1 */ - min_values?: number + min_values?: number; /** The maximum number of files that can be uploaded * * @remarks @@ -591,39 +591,39 @@ export interface DiscordFileUploadComponent extends DiscordBaseComponent { * * @default 1 */ - max_values?: number + max_values?: number; /** * Whether this component is required to be filled * * @default true */ - required?: boolean + required?: boolean; } /** https://discord.com/developers/docs/components/reference#file-upload-file-upload-interaction-response-structure */ export interface DiscordFileUploadInteractionResponse { - type: MessageComponentTypes.FileUpload + type: MessageComponentTypes.FileUpload; /** Unique identifier for the component */ - id: number + id: number; /** The custom id for the file upload */ - custom_id: string + custom_id: string; /** IDs of the uploaded files found in the resolved data */ - values: string[] + values: string[]; } /** https://discord.com/developers/docs/components/reference#unfurled-media-item-structure */ export interface DiscordUnfurledMediaItem { /** Supports arbitrary urls and attachment:// references */ - url: string + url: string; /** The proxied url of the media item. This field is ignored and provided by the API as part of the response */ - proxy_url?: string + proxy_url?: string; /** The height of the media item. This field is ignored and provided by the API as part of the response */ - height?: number | null + height?: number | null; /** The width of the media item. This field is ignored and provided by the API as part of the response */ - width?: number | null + width?: number | null; /** The media type of the content. This field is ignored and provided by the API as part of the response */ - content_type?: string + content_type?: string; /** The id of the uploaded attachment. Only present if the media was uploaded as an attachment. This field is ignored and provided by the API as part of the response */ - attachment_id?: string | null + attachment_id?: string | null; } diff --git a/packages/types/src/discord/emoji.ts b/packages/types/src/discord/emoji.ts index 0ed72b1bd..73b239ccb 100644 --- a/packages/types/src/discord/emoji.ts +++ b/packages/types/src/discord/emoji.ts @@ -1,28 +1,28 @@ /** Types for: https://discord.com/developers/docs/resources/emoji */ -import type { DiscordUser } from './user.js' +import type { DiscordUser } from './user.js'; /** https://discord.com/developers/docs/resources/emoji#emoji-object-emoji-structure */ export interface DiscordEmoji { /** Emoji id */ - id: string | null + id: string | null; /** * Emoji name * * @remarks * Can be null only in reaction emoji objects */ - name: string | null + name: string | null; /** Roles allowed to use this emoji */ - roles?: string[] + roles?: string[]; /** User that created this emoji */ - user?: DiscordUser + user?: DiscordUser; /** Whether this emoji must be wrapped in colons */ - require_colons?: boolean + require_colons?: boolean; /** Whether this emoji is managed */ - managed?: boolean + managed?: boolean; /** Whether this emoji is animated */ - animated?: boolean + animated?: boolean; /** Whether this emoji can be used, may be false due to loss of Server Boosts */ - available?: boolean + available?: boolean; } diff --git a/packages/types/src/discord/entitlement.ts b/packages/types/src/discord/entitlement.ts index a28813c84..0344d24f3 100644 --- a/packages/types/src/discord/entitlement.ts +++ b/packages/types/src/discord/entitlement.ts @@ -3,25 +3,25 @@ /** https://discord.com/developers/docs/resources/entitlement#entitlement-object-entitlement-structure */ export interface DiscordEntitlement { /** ID of the entitlement */ - id: string + id: string; /** ID of the SKU */ - sku_id: string + sku_id: string; /** ID of the parent application */ - application_id: string + application_id: string; /** ID of the user that is granted access to the entitlement's sku */ - user_id?: string + user_id?: string; /** Type of entitlement */ - type: DiscordEntitlementType + type: DiscordEntitlementType; /** Entitlement was deleted */ - deleted: boolean + deleted: boolean; /** Start date at which the entitlement is valid. */ - starts_at: string | null + starts_at: string | null; /** Date at which the entitlement is no longer valid. */ - ends_at: string | null + ends_at: string | null; /** ID of the guild that is granted access to the entitlement's sku */ - guild_id?: string + guild_id?: string; /** For consumable items, whether or not the entitlement has been consumed */ - consumed?: boolean + consumed?: boolean; } /** https://discord.com/developers/docs/resources/entitlement#entitlement-object-entitlement-types */ diff --git a/packages/types/src/discord/gateway.ts b/packages/types/src/discord/gateway.ts index d25feffe0..d9e897e4e 100644 --- a/packages/types/src/discord/gateway.ts +++ b/packages/types/src/discord/gateway.ts @@ -4,21 +4,21 @@ * - https://discord.com/developers/docs/events/gateway-events */ -import type { DiscordApplication } from './application.js' -import type { AutoModerationTriggerTypes, DiscordAutoModerationAction } from './autoModeration.js' -import type { DiscordChannel, DiscordThreadMember } from './channel.js' -import type { DiscordEmoji } from './emoji.js' -import type { DiscordIntegration, DiscordMember, DiscordMemberWithUser, DiscordUnavailableGuild } from './guild.js' -import type { DiscordScheduledEvent } from './guildScheduledEvent.js' -import type { TargetTypes } from './invite.js' -import type { DiscordReactionType } from './message.js' -import type { GatewayOpcodes } from './opcodes.js' -import type { DiscordRole } from './permissions.js' -import type { DiscordSoundboardSound } from './soundboard.js' -import type { DiscordStageInstance } from './stageInstance.js' -import type { DiscordSticker } from './sticker.js' -import type { DiscordAvatarDecorationData, DiscordUser } from './user.js' -import type { DiscordVoiceState } from './voice.js' +import type { DiscordApplication } from './application.js'; +import type { AutoModerationTriggerTypes, DiscordAutoModerationAction } from './autoModeration.js'; +import type { DiscordChannel, DiscordThreadMember } from './channel.js'; +import type { DiscordEmoji } from './emoji.js'; +import type { DiscordIntegration, DiscordMember, DiscordMemberWithUser, DiscordUnavailableGuild } from './guild.js'; +import type { DiscordScheduledEvent } from './guildScheduledEvent.js'; +import type { TargetTypes } from './invite.js'; +import type { DiscordReactionType } from './message.js'; +import type { GatewayOpcodes } from './opcodes.js'; +import type { DiscordRole } from './permissions.js'; +import type { DiscordSoundboardSound } from './soundboard.js'; +import type { DiscordStageInstance } from './stageInstance.js'; +import type { DiscordSticker } from './sticker.js'; +import type { DiscordAvatarDecorationData, DiscordUser } from './user.js'; +import type { DiscordVoiceState } from './voice.js'; /** https://discord.com/developers/docs/events/gateway#list-of-intents */ export enum GatewayIntents { @@ -170,30 +170,30 @@ export enum GatewayIntents { DirectMessagePolls = 1 << 25, } -export { GatewayIntents as Intents } +export { GatewayIntents as Intents }; // TODO: Add TransportCompression: https://discord.com/developers/docs/events/gateway#transport-compression /** https://discord.com/developers/docs/events/gateway#get-gateway-bot */ export interface DiscordGetGatewayBot { /** The WSS URL that can be used for connecting to the gateway */ - url: string + url: string; /** The recommended number of shards to use when connecting */ - shards: number + shards: number; /** Information on the current session start limit */ - session_start_limit: DiscordSessionStartLimit + session_start_limit: DiscordSessionStartLimit; } /** https://discord.com/developers/docs/events/gateway#session-start-limit-object */ export interface DiscordSessionStartLimit { /** The total number of session starts the current user is allowed */ - total: number + total: number; /** The remaining number of session starts the current user is allowed */ - remaining: number + remaining: number; /** The number of milliseconds after which the limit resets */ - reset_after: number + reset_after: number; /** The number of identify requests allowed per 5 seconds */ - max_concurrency: number + max_concurrency: number; } /** https://discord.com/developers/docs/events/gateway-events#receive-events */ @@ -273,21 +273,21 @@ export type GatewayDispatchEventNames = | 'SUBSCRIPTION_UPDATE' | 'SUBSCRIPTION_DELETE' | 'MESSAGE_POLL_VOTE_ADD' - | 'MESSAGE_POLL_VOTE_REMOVE' + | 'MESSAGE_POLL_VOTE_REMOVE'; /** https://discord.com/developers/docs/events/gateway-events#receive-events */ -export type GatewayEventNames = GatewayDispatchEventNames +export type GatewayEventNames = GatewayDispatchEventNames; /** https://discord.com/developers/docs/events/gateway-events#payload-structure */ export interface DiscordGatewayPayload { /** opcode for the payload */ - op: number + op: number; /** Event data */ - d: unknown | null + d: unknown | null; /** Sequence number, used for resuming sessions and heartbeats */ - s: number | null + s: number | null; /** The event name for this payload */ - t: GatewayEventNames | null + t: GatewayEventNames | null; } // TODO: Add Identify: https://discord.com/developers/docs/events/gateway-events#identify-identify-structure @@ -300,13 +300,13 @@ export interface DiscordGatewayPayload { /** https://discord.com/developers/docs/events/gateway-events#update-presence-gateway-presence-update-structure */ export interface DiscordUpdatePresence { /** Unix time (in milliseconds) of when the client went idle, or null if the client is not idle */ - since: number | null + since: number | null; /** The user's activities */ - activities: DiscordBotActivity[] + activities: DiscordBotActivity[]; /** The user's new status */ - status: Exclude + status: Exclude; /** Whether or not the client is afk */ - afk: boolean + afk: boolean; } /** https://discord.com/developers/docs/events/gateway-events#update-presence-status-types */ @@ -321,51 +321,51 @@ export enum PresenceStatus { /** https://discord.com/developers/docs/events/gateway-events#hello-hello-structure */ export interface DiscordHello { /** The interval (in milliseconds) the client should heartbeat with */ - heartbeat_interval: number + heartbeat_interval: number; } /** https://discord.com/developers/docs/events/gateway-events#ready-ready-event-fields */ export interface DiscordReady { /** Gateway version */ - v: number + v: number; /** Information about the user including email */ - user: DiscordUser + user: DiscordUser; /** The guilds the user is in */ - guilds: DiscordUnavailableGuild[] + guilds: DiscordUnavailableGuild[]; /** Used for resuming connections */ - session_id: string + session_id: string; /** Gateway url for resuming connections */ - resume_gateway_url: string + resume_gateway_url: string; /** The shard information associated with this session, if sent when identifying */ - shard?: [number, number] + shard?: [number, number]; /** Contains id and flags */ - application: Partial & Pick + application: Partial & Pick; } /** https://discord.com/developers/docs/events/gateway-events#auto-moderation-action-execution-auto-moderation-action-execution-event-fields */ export interface DiscordAutoModerationActionExecution { /** The id of the guild */ - guild_id: string + guild_id: string; /** Action which was executed */ - action: DiscordAutoModerationAction + action: DiscordAutoModerationAction; /** The id of the rule that was executed */ - rule_id: string + rule_id: string; /** The trigger type of the rule that was executed. */ - rule_trigger_type: AutoModerationTriggerTypes + rule_trigger_type: AutoModerationTriggerTypes; /** The id of the user which generated the content which triggered the rule */ - user_id: string + user_id: string; /** The id of the channel in which user content was posted */ - channel_id?: string + channel_id?: string; /** The id of the message. Will not exist if message was blocked by automod or content was not part of any message */ - message_id?: string + message_id?: string; /** The id of any system auto moderation messages posted as a result of this action */ - alert_system_message_id?: string + alert_system_message_id?: string; /** The content from the user */ - content: string + content: string; /** The word or phrase that triggerred the rule. */ - matched_keyword: string | null + matched_keyword: string | null; /** The substring in content that triggered the rule */ - matched_content: string | null + matched_content: string | null; } /** https://discord.com/developers/docs/events/gateway-events#thread-create */ @@ -376,25 +376,25 @@ export interface DiscordThreadCreateExtra { * @remarks * The Thread Create event may fire for a few reasons, however this fields only exists when it is fired because a thread was created. */ - newly_created?: boolean + newly_created?: boolean; } /** https://discord.com/developers/docs/events/gateway-events#thread-list-sync-thread-list-sync-event-fields */ export interface DiscordThreadListSync { /** The id of the guild */ - guild_id: string + guild_id: string; /** The parent channel ids whose threads are being synced. If omitted, then threads were synced for the entire guild. This array may contain channelIds that have no active threads as well, so you know to clear that data */ - channel_ids?: string[] + channel_ids?: string[]; /** All active threads in the given channels that the current user can access */ - threads: DiscordChannel[] + threads: DiscordChannel[]; /** All thread member objects from the synced threads for the current user, indicating which threads the current user has been added to */ - members: DiscordThreadMember[] + members: DiscordThreadMember[]; } /** https://discord.com/developers/docs/events/gateway-events#thread-member-update-thread-member-update-event-extra-fields */ export interface DiscordThreadMemberUpdateExtra { /** Id of the guild */ - guild_id: string + guild_id: string; } /** https://discord.com/developers/docs/events/gateway-events#thread-member-update-thread-member-update-event-extra-fields */ @@ -403,85 +403,85 @@ export interface DiscordThreadMemberUpdate extends DiscordThreadMember, DiscordT /** https://discord.com/developers/docs/events/gateway-events#thread-members-update-thread-members-update-event-fields */ export interface DiscordThreadMembersUpdate { /** The id of the thread */ - id: string + id: string; /** The id of the guild */ - guild_id: string + guild_id: string; /** the approximate number of members in the thread, capped at 50 */ - member_count: number + member_count: number; /** The users who were added to the thread */ - added_members?: DiscordThreadMember[] + added_members?: DiscordThreadMember[]; /** The id of the users who were removed from the thread */ - removed_member_ids?: string[] + removed_member_ids?: string[]; } /** https://discord.com/developers/docs/events/gateway#channel-pins-update */ export interface DiscordChannelPinsUpdate { /** The id of the guild */ - guild_id?: string + guild_id?: string; /** The id of the channel */ - channel_id: string + channel_id: string; /** The time at which the most recent pinned message was pinned */ - last_pin_timestamp?: string | null + last_pin_timestamp?: string | null; } /** https://discord.com/developers/docs/events/gateway-events#guild-create-guild-create-extra-fields */ export interface DiscordGuildCreateExtra { /** When this guild was joined at */ - joined_at: string + joined_at: string; /** If this is considered a large guild */ - large: boolean + large: boolean; /** If the guild is unavailable due to an outage */ - unavailable?: boolean + unavailable?: boolean; /** Total number of member in this guild */ - member_count: number + member_count: number; /** * States of members currently in voice channels * * @remarks * Lacks the `guild_id` key */ - voice_states: Omit[] + voice_states: Omit[]; /** Users in the guild */ - members: DiscordMemberWithUser[] + members: DiscordMemberWithUser[]; /** Channels in the guild */ - channels: DiscordChannel[] + channels: DiscordChannel[]; /** All active threads in the guild that the current user has permission to view */ - threads: DiscordChannel[] + threads: DiscordChannel[]; /** * Presences of the members in the guild * * @remarks * Will only include non-offline members if the size is greater than the large threshold. */ - presences: Partial[] + presences: Partial[]; /** Stage instances in the guild */ - stage_instances: DiscordStageInstance[] + stage_instances: DiscordStageInstance[]; /** Scheduled events in the guild */ - guild_scheduled_events: DiscordScheduledEvent[] + guild_scheduled_events: DiscordScheduledEvent[]; /** Soundboard sounds in the guild */ - soundboard_sounds: DiscordSoundboardSound[] + soundboard_sounds: DiscordSoundboardSound[]; } /** https://discord.com/developers/docs/events/gateway-events#guild-audit-log-entry-create-guild-audit-log-entry-create-event-extra-fields */ export interface DiscordGuildAuditLogEntryCreateExtra { /** The id of the guild */ - guild_id: string + guild_id: string; } /** https://discord.com/developers/docs/events/gateway-events#guild-ban-add-guild-ban-add-event-fields */ export interface DiscordGuildBanAdd { /** id of the guild */ - guild_id: string + guild_id: string; /** The banned user */ - user: DiscordUser + user: DiscordUser; } /** https://discord.com/developers/docs/events/gateway-events#guild-ban-remove-guild-ban-remove-event-fields */ export interface DiscordGuildBanRemove { /** id of the guild */ - guild_id: string + guild_id: string; /** The banned user */ - user: DiscordUser + user: DiscordUser; } /** @@ -496,29 +496,29 @@ export interface DiscordGuildBanAddRemove extends DiscordGuildBanAdd {} /** https://discord.com/developers/docs/events/gateway-events#guild-emojis-update-guild-emojis-update-event-fields */ export interface DiscordGuildEmojisUpdate { /** id of the guild */ - guild_id: string + guild_id: string; /** Array of emojis */ - emojis: DiscordEmoji[] + emojis: DiscordEmoji[]; } /** https://discord.com/developers/docs/events/gateway-events#guild-stickers-update-guild-stickers-update-event-fields */ export interface DiscordGuildStickersUpdate { /** id of the guild */ - guild_id: string + guild_id: string; /** Array of sticker */ - stickers: DiscordSticker[] + stickers: DiscordSticker[]; } /** https://discord.com/developers/docs/events/gateway-events#guild-integrations-update-guild-integrations-update-event-fields */ export interface DiscordGuildIntegrationsUpdate { /** id of the guild whose integrations were updated */ - guild_id: string + guild_id: string; } /** https://discord.com/developers/docs/events/gateway-events#guild-member-add-guild-member-add-extra-fields */ export interface DiscordGuildMemberAddExtra { /** id of the guild */ - guild_id: string + guild_id: string; } /** https://discord.com/developers/docs/events/gateway-events#guild-member-add-guild-member-add-extra-fields */ @@ -527,139 +527,139 @@ export interface DiscordGuildMemberAdd extends DiscordMemberWithUser, DiscordGui /** https://discord.com/developers/docs/events/gateway-events#guild-member-remove-guild-member-remove-event-fields */ export interface DiscordGuildMemberRemove { /** The id of the guild */ - guild_id: string + guild_id: string; /** The user who was removed */ - user: DiscordUser + user: DiscordUser; } /** https://discord.com/developers/docs/events/gateway-events#guild-member-update-guild-member-update-event-fields */ export interface DiscordGuildMemberUpdate { /** The id of the guild */ - guild_id: string + guild_id: string; /** User role ids */ - roles: string[] + roles: string[]; /** The user */ - user: DiscordUser + user: DiscordUser; /** Nickname of the user in the guild */ - nick?: string | null + nick?: string | null; /** the member's [guild avatar hash](https://discord.com/developers/docs/reference#image-formatting) */ - avatar: string | null + avatar: string | null; /** the member's guild banner hash */ - banner: string | null + banner: string | null; /** When the user joined the guild */ - joined_at: string | null + joined_at: string | null; /** When the user starting boosting the guild */ - premium_since?: string | null + premium_since?: string | null; /** whether the user is deafened in voice channels */ - deaf?: boolean + deaf?: boolean; /** whether the user is muted in voice channels */ - mute?: boolean + mute?: boolean; /** Whether the user has not yet passed the guild's Membership Screening requirements */ - pending?: boolean + pending?: boolean; /** when the user's [timeout](https://support.discord.com/hc/en-us/articles/4413305239191-Time-Out-FAQ) will expire and the user will be able to communicate in the guild again, null or a time in the past if the user is not timed out. Will throw a 403 error if the user has the ADMINISTRATOR permission or is the owner of the guild */ - communication_disabled_until?: string | null + communication_disabled_until?: string | null; /** Guild member flags */ - flags?: number + flags?: number; /** Data for the member's guild avatar decoration */ - avatar_decoration_data?: DiscordAvatarDecorationData | null + avatar_decoration_data?: DiscordAvatarDecorationData | null; } /** https://discord.com/developers/docs/events/gateway-events#guild-members-chunk-guild-members-chunk-event-fields */ export interface DiscordGuildMembersChunk { /** The id of the guild */ - guild_id: string + guild_id: string; /** Set of guild members */ - members: DiscordMemberWithUser[] + members: DiscordMemberWithUser[]; /** The chunk index in the expected chunks for this response (0 <= chunk_index < chunk_count) */ - chunk_index: number + chunk_index: number; /** The total number of expected chunks for this response */ - chunk_count: number + chunk_count: number; /** If passing an invalid id to `REQUEST_GUILD_MEMBERS`, it will be returned here */ - not_found?: string[] + not_found?: string[]; /** If passing true to `REQUEST_GUILD_MEMBERS`, presences of the returned members will be here */ - presences?: DiscordPresenceUpdate[] + presences?: DiscordPresenceUpdate[]; /** The nonce used in the Guild Members Request */ - nonce?: string + nonce?: string; } /** https://discord.com/developers/docs/events/gateway-events#guild-role-create-guild-role-create-event-fields */ export interface DiscordGuildRoleCreate { /** The id of the guild */ - guild_id: string + guild_id: string; /** The role created */ - role: DiscordRole + role: DiscordRole; } /** https://discord.com/developers/docs/events/gateway-events#guild-role-update-guild-role-update-event-fields */ export interface DiscordGuildRoleUpdate { /** The id of the guild */ - guild_id: string + guild_id: string; /** The role updated */ - role: DiscordRole + role: DiscordRole; } /** https://discord.com/developers/docs/events/gateway-events#guild-role-delete-guild-role-delete-event-fields */ export interface DiscordGuildRoleDelete { /** id of the guild */ - guild_id: string + guild_id: string; /** id of the role */ - role_id: string + role_id: string; } /** https://discord.com/developers/docs/events/gateway-events#guild-scheduled-event-user-add-guild-scheduled-event-user-add-event-fields */ export interface DiscordScheduledEventUserAdd { /** id of the guild scheduled event */ - guild_scheduled_event_id: string + guild_scheduled_event_id: string; /** id of the user */ - user_id: string + user_id: string; /** id of the guild */ - guild_id: string + guild_id: string; } /** https://discord.com/developers/docs/events/gateway-events#guild-scheduled-event-user-remove-guild-scheduled-event-user-remove-event-fields */ export interface DiscordScheduledEventUserRemove { /** id of the guild scheduled event */ - guild_scheduled_event_id: string + guild_scheduled_event_id: string; /** id of the user */ - user_id: string + user_id: string; /** id of the guild */ - guild_id: string + guild_id: string; } /** https://discord.com/developers/docs/topics/gateway-events#guild-soundboard-sound-delete-guild-soundboard-sound-delete-event-fields */ export interface DiscordSoundboardSoundDelete { /** ID of the sound that was deleted */ - sound_id: string + sound_id: string; /** ID of the guild the sound was in */ - guild_id: string + guild_id: string; } /** https://discord.com/developers/docs/topics/gateway-events#guild-soundboard-sounds-update-guild-soundboard-sounds-update-event-fields */ export interface DiscordSoundboardSoundsUpdate { /** The guild's soundboard sounds */ - soundboard_sounds: DiscordSoundboardSound[] + soundboard_sounds: DiscordSoundboardSound[]; /** ID of the guild the sound was in */ - guild_id: string + guild_id: string; } /** https://discord.com/developers/docs/events/gateway-events#soundboard-sounds-soundboard-sounds-event-fields */ export interface DiscordSoundboardSounds { /** The guild's soundboard sounds */ - soundboard_sounds: DiscordSoundboardSound[] + soundboard_sounds: DiscordSoundboardSound[]; /** ID of the guild the sound was in */ - guild_id: string + guild_id: string; } /** https://discord.com/developers/docs/events/gateway-events#integration-create-integration-create-event-additional-fields */ export interface DiscordIntegrationCreateExtra { /** Id of the guild */ - guild_id: string + guild_id: string; } /** https://discord.com/developers/docs/events/gateway-events#integration-update-integration-update-event-additional-fields */ export interface DiscordIntegrationUpdateExtra { /** Id of the guild */ - guild_id: string + guild_id: string; } /** @@ -668,222 +668,222 @@ export interface DiscordIntegrationUpdateExtra { */ export interface DiscordIntegrationCreateUpdate extends DiscordIntegration { /** Id of the guild */ - guild_id: string + guild_id: string; } /** https://discord.com/developers/docs/events/gateway-events#integration-delete-integration-delete-event-fields */ export interface DiscordIntegrationDelete { /** Integration id */ - id: string + id: string; /** Id of the guild */ - guild_id: string + guild_id: string; /** Id of the bot/OAuth2 application for this discord integration */ - application_id?: string + application_id?: string; } /** https://discord.com/developers/docs/events/gateway-events#invite-create-invite-create-event-fields */ export interface DiscordInviteCreate { /** The channel the invite is for */ - channel_id: string + channel_id: string; /** The unique invite code */ - code: string + code: string; /** The time at which the invite was created */ - created_at: string + created_at: string; /** The guild of the invite */ - guild_id?: string + guild_id?: string; /** The user that created the invite */ - inviter?: DiscordUser + inviter?: DiscordUser; /** How long the invite is valid for (in seconds) */ - max_age: number + max_age: number; /** The maximum number of times the invite can be used */ - max_uses: number + max_uses: number; /** The type of target for this voice channel invite */ - target_type: TargetTypes + target_type: TargetTypes; /** The target user for this invite */ - target_user?: DiscordUser + target_user?: DiscordUser; /** The embedded application to open for this voice channel embedded application invite */ - target_application?: Partial + target_application?: Partial; /** Whether or not the invite is temporary (invited users will be kicked on disconnect unless they're assigned a role) */ - temporary: boolean + temporary: boolean; /** How many times the invite has been used (always will be 0) */ - uses: number + uses: number; /** The expiration date of this invite. */ - expires_at: string + expires_at: string; } /** https://discord.com/developers/docs/events/gateway-events#invite-delete-invite-delete-event-fields */ export interface DiscordInviteDelete { /** The channel of the invite */ - channel_id: string + channel_id: string; /** The guild of the invite */ - guild_id?: string + guild_id?: string; /** The unique invite code */ - code: string + code: string; } /** https://discord.com/developers/docs/events/gateway-events#message-create-message-create-extra-fields */ export interface DiscordMessageCreateExtra { /** ID of the guild the message was sent in - unless it is an ephemeral message */ - guild_id?: string + guild_id?: string; /** Member properties for this message's author. Missing for ephemeral messages and messages from webhooks */ - member?: Partial + member?: Partial; /** Users specifically mentioned in the message */ - mentions: Array }> + mentions: Array }>; } /** https://discord.com/developers/docs/events/gateway-events#message-update */ -export type DiscordMessageUpdateExtra = DiscordMessageCreateExtra +export type DiscordMessageUpdateExtra = DiscordMessageCreateExtra; /** https://discord.com/developers/docs/events/gateway-events#message-delete-message-delete-event-fields */ export interface DiscordMessageDelete { /** The id of the message */ - id: string + id: string; /** The id of the channel */ - channel_id: string + channel_id: string; /** The id of the guild */ - guild_id?: string + guild_id?: string; } /** https://discord.com/developers/docs/events/gateway-events#message-delete-bulk-message-delete-bulk-event-fields */ export interface DiscordMessageDeleteBulk { /** The ids of the messages */ - ids: string[] + ids: string[]; /** The id of the channel */ - channel_id: string + channel_id: string; /** The id of the guild */ - guild_id?: string + guild_id?: string; } /** https://discord.com/developers/docs/events/gateway-events#message-reaction-add-message-reaction-add-event-fields */ export interface DiscordMessageReactionAdd { /** The id of the user */ - user_id: string + user_id: string; /** The id of the channel */ - channel_id: string + channel_id: string; /** The id of the message */ - message_id: string + message_id: string; /** The id of the guild */ - guild_id?: string + guild_id?: string; /** The member who reacted if this happened in a guild */ - member?: DiscordMemberWithUser + member?: DiscordMemberWithUser; /** The emoji used to react */ - emoji: Partial + emoji: Partial; /** The id of the author of this message */ - message_author_id?: string + message_author_id?: string; /** true if this is a super-reaction */ - burst: boolean + burst: boolean; /** Colors used for super-reaction animation in "#rrggbb" format */ - burst_colors?: string[] + burst_colors?: string[]; /** The type of reaction */ - type: DiscordReactionType + type: DiscordReactionType; } /** https://discord.com/developers/docs/events/gateway-events#message-reaction-remove-message-reaction-remove-event-fields */ export interface DiscordMessageReactionRemove { /** The id of the user */ - user_id: string + user_id: string; /** The id of the channel */ - channel_id: string + channel_id: string; /** The id of the message */ - message_id: string + message_id: string; /** The id of the guild */ - guild_id?: string + guild_id?: string; /** The emoji used to react */ - emoji: Partial + emoji: Partial; /** true if this is a super-reaction */ - burst: boolean + burst: boolean; /** The type of reaction */ - type: DiscordReactionType + type: DiscordReactionType; } /** https://discord.com/developers/docs/events/gateway-events#message-reaction-remove-all-message-reaction-remove-all-event-fields */ export interface DiscordMessageReactionRemoveAll { /** The id of the channel */ - channel_id: string + channel_id: string; /** The id of the message */ - message_id: string + message_id: string; /** The id of the guild */ - guild_id?: string + guild_id?: string; } /** https://discord.com/developers/docs/events/gateway-events#message-reaction-remove-emoji-message-reaction-remove-emoji-event-fields */ export interface DiscordMessageReactionRemoveEmoji { /** The id of the channel */ - channel_id: string + channel_id: string; /** The id of the guild */ - guild_id?: string + guild_id?: string; /** The id of the message */ - message_id: string + message_id: string; /** The emoji used to react */ - emoji: Partial + emoji: Partial; } /** https://discord.com/developers/docs/events/gateway-events#presence-update-presence-update-event-fields */ export interface DiscordPresenceUpdate { /** The user presence is being updated for */ - user: DiscordUser + user: DiscordUser; /** id of the guild */ - guild_id: string + guild_id: string; /** Either "idle", "dnd", "online", or "offline" */ - status: 'idle' | 'dnd' | 'online' | 'offline' + status: 'idle' | 'dnd' | 'online' | 'offline'; /** User's current activities */ - activities: DiscordActivity[] + activities: DiscordActivity[]; /** User's platform-dependent status */ - client_status: DiscordClientStatus + client_status: DiscordClientStatus; } /** https://discord.com/developers/docs/events/gateway-events#client-status-object */ export interface DiscordClientStatus { /** The user's status set for an active desktop (Windows, Linux, Mac) application session */ - desktop?: string + desktop?: string; /** The user's status set for an active mobile (iOS, Android) application session */ - mobile?: string + mobile?: string; /** The user's status set for an active web (browser, bot account) application session */ - web?: string + web?: string; } /** https://discord.com/developers/docs/events/gateway-events#activity-object */ export interface DiscordActivity { /** The activity's name */ - name: string + name: string; /** Activity type */ - type: ActivityTypes + type: ActivityTypes; /** Stream url, is validated when type is 1 */ - url?: string | null + url?: string | null; /** Unix timestamp of when the activity was added to the user's session */ - created_at: number + created_at: number; /** Unix timestamps for start and/or end of the game */ - timestamps?: DiscordActivityTimestamps + timestamps?: DiscordActivityTimestamps; /** Application id for the game */ - application_id?: string + application_id?: string; /** Controls which field is displayed in the user's status text in the member list */ - status_display_type?: DiscordStatusDisplayType | null + status_display_type?: DiscordStatusDisplayType | null; /** What the player is currently doing */ - details?: string | null + details?: string | null; /** URL that is linked when clicking on the details text */ - details_url?: string | null + details_url?: string | null; /** The user's current party status */ - state?: string | null + state?: string | null; /** URL that is linked when clicking on the state text */ - state_url?: string | null + state_url?: string | null; /** The emoji used for a custom status */ - emoji?: DiscordActivityEmoji | null + emoji?: DiscordActivityEmoji | null; /** Information for the current party of the player */ - party?: DiscordActivityParty + party?: DiscordActivityParty; /** Images for the presence and their hover texts */ - assets?: DiscordActivityAssets + assets?: DiscordActivityAssets; /** Secrets for Rich Presence joining and spectating */ - secrets?: DiscordActivitySecrets + secrets?: DiscordActivitySecrets; /** Whether or not the activity is an instanced game session */ - instance?: boolean + instance?: boolean; /** Activity flags `OR`d together, describes what the payload includes */ - flags?: number + flags?: number; /** The custom buttons shown in the Rich Presence (max 2) */ - buttons?: DiscordActivityButton[] + buttons?: DiscordActivityButton[]; } /** https://discord.com/developers/docs/events/gateway-events#activity-object - Note at the bottom */ -export type DiscordBotActivity = Pick +export type DiscordBotActivity = Pick; /** https://discord.com/developers/docs/events/gateway-events#activity-object-activity-types */ export enum ActivityTypes { @@ -908,55 +908,55 @@ export enum DiscordStatusDisplayType { /** https://discord.com/developers/docs/events/gateway-events#activity-object-activity-timestamps */ export interface DiscordActivityTimestamps { /** Unix time (in milliseconds) of when the activity started */ - start?: number + start?: number; /** Unix time (in milliseconds) of when the activity ends */ - end?: number + end?: number; } /** https://discord.com/developers/docs/events/gateway-events#activity-object-activity-emoji */ export interface DiscordActivityEmoji { /** The name of the emoji */ - name: string + name: string; /** Whether this emoji is animated */ - animated?: boolean + animated?: boolean; /** The id of the emoji */ - id?: string + id?: string; } /** https://discord.com/developers/docs/events/gateway-events#activity-object-activity-party */ export interface DiscordActivityParty { /** Used to show the party's current and maximum size */ - size?: [currentSize: number, maxSize: number] + size?: [currentSize: number, maxSize: number]; /** The id of the party */ - id?: string + id?: string; } /** https://discord.com/developers/docs/events/gateway-events#activity-object-activity-assets */ export interface DiscordActivityAssets { /** The id for a large asset of the activity, usually a snowflake */ - large_image?: string + large_image?: string; /** Text displayed when hovering over the large image of the activity */ - large_text?: string + large_text?: string; /** URL that is opened when clicking on the large image */ - large_url?: string + large_url?: string; /** The id for a small asset of the activity, usually a snowflake */ - small_image?: string + small_image?: string; /** Text displayed when hovering over the small image of the activity */ - small_text?: string + small_text?: string; /** URL that is opened when clicking on the small image */ - small_url?: string + small_url?: string; /** See Activity Asset Image. Displayed as a banner on a Game Invite. */ - invite_cover_image?: string + invite_cover_image?: string; } /** https://discord.com/developers/docs/events/gateway-events#activity-object-activity-secrets */ export interface DiscordActivitySecrets { /** The secret for joining a party */ - join?: string + join?: string; /** The secret for spectating a game */ - spectate?: string + spectate?: string; /** The secret for a specific instanced match */ - match?: string + match?: string; } /** https://discord.com/developers/docs/events/gateway-events#activity-object-activity-flags */ @@ -975,43 +975,43 @@ export enum ActivityFlags { /** https://discord.com/developers/docs/events/gateway#activity-object-activity-buttons */ export interface DiscordActivityButton { /** The text shown on the button (1-32 characters) */ - label: string + label: string; /** The url opened when clicking the button (1-512 characters) */ - url: string + url: string; } /** https://discord.com/developers/docs/events/gateway-events#typing-start-typing-start-event-fields */ export interface DiscordTypingStart { /** id of the channel */ - channel_id: string + channel_id: string; /** id of the guild */ - guild_id?: string + guild_id?: string; /** id of the user */ - user_id: string + user_id: string; /** Unix time (in seconds) of when the user started typing */ - timestamp: number + timestamp: number; /** The member who started typing if this happened in a guild */ - member?: DiscordMember + member?: DiscordMember; } /** https://discord.com/developers/docs/events/gateway-events#voice-channel-effect-send-voice-channel-effect-send-event-fields */ export interface DiscordVoiceChannelEffectSend { /** ID of the channel the effect was sent in */ - channel_id: string + channel_id: string; /** ID of the guild the effect was sent in */ - guild_id: string + guild_id: string; /** ID of the user who sent the effect */ - user_id: string + user_id: string; /** The emoji sent, for emoji reaction and soundboard effects */ - emoji?: DiscordEmoji | null + emoji?: DiscordEmoji | null; /** The type of emoji animation, for emoji reaction and soundboard effects */ - animation_type?: DiscordVoiceChannelEffectAnimationType | null + animation_type?: DiscordVoiceChannelEffectAnimationType | null; /** The ID of the emoji animation, for emoji reaction and soundboard effects */ - animation_id?: number + animation_id?: number; /** The ID of the soundboard sound, for soundboard effects */ - sound_id?: string | number + sound_id?: string | number; /** The volume of the soundboard sound, from 0 to 1, for soundboard effects */ - sound_volume?: number + sound_volume?: number; } /** https://discord.com/developers/docs/events/gateway-events#voice-channel-effect-send-animation-types */ @@ -1025,68 +1025,68 @@ export enum DiscordVoiceChannelEffectAnimationType { /** https://discord.com/developers/docs/events/gateway-events#voice-server-update-voice-server-update-event-fields */ export interface DiscordVoiceServerUpdate { /** Voice connection token */ - token: string + token: string; /** The guild this voice server update is for */ - guild_id: string + guild_id: string; /** The voice server host */ - endpoint: string | null + endpoint: string | null; } /** https://discord.com/developers/docs/events/gateway-events#webhooks-update-webhooks-update-event-fields */ export interface DiscordWebhookUpdate { /** id of the guild */ - guild_id: string + guild_id: string; /** id of the channel */ - channel_id: string + channel_id: string; } /** https://discord.com/developers/docs/events/gateway-events#message-poll-vote-add-message-poll-vote-add-fields */ export interface DiscordPollVoteAdd { /** ID of the user. Usually a snowflake */ - user_id: string + user_id: string; /** ID of the channel. Usually a snowflake */ - channel_id: string + channel_id: string; /** ID of the message. Usually a snowflake */ - message_id: string + message_id: string; /** ID of the guild. Usually a snowflake */ - guild_id?: string + guild_id?: string; /** ID of the answer. */ - answer_id: number + answer_id: number; } /** https://discord.com/developers/docs/events/gateway-events#message-poll-vote-remove-message-poll-vote-remove-fields */ export interface DiscordPollVoteRemove { /** ID of the user. Usually a snowflake */ - user_id: string + user_id: string; /** ID of the channel. Usually a snowflake */ - channel_id: string + channel_id: string; /** ID of the message. Usually a snowflake */ - message_id: string + message_id: string; /** ID of the guild. Usually a snowflake */ - guild_id?: string + guild_id?: string; /** ID of the answer. */ - answer_id: number + answer_id: number; } /** https://discord.com/developers/docs/events/gateway-events#rate-limited-rate-limited-fields */ export interface DiscordRateLimited { /** Gateway opcode of the event that was rate limited */ - opcode: GatewayOpcodes + opcode: GatewayOpcodes; /** The number of seconds to wait before submitting another request */ - retry_after: number + retry_after: number; /** * Metadata for the event that was rate limited * * @remarks * This is dependent on the {@link opcode} field in this object */ - meta: DiscordRequestGuildMemberRateLimitMetadata + meta: DiscordRequestGuildMemberRateLimitMetadata; } /** https://discord.com/developers/docs/events/gateway-events#rate-limited-request-guild-member-rate-limit-metadata-structure */ export interface DiscordRequestGuildMemberRateLimitMetadata { /** ID of the guild to get members for */ - guild_id: string + guild_id: string; /** nonce to identify the Guild Members Chunk response */ - nonce?: string + nonce?: string; } diff --git a/packages/types/src/discord/guild.ts b/packages/types/src/discord/guild.ts index 8db7ae6ea..c41de0603 100644 --- a/packages/types/src/discord/guild.ts +++ b/packages/types/src/discord/guild.ts @@ -1,119 +1,119 @@ /** Types for: https://discord.com/developers/docs/resources/guild */ -import type { DiscordChannel, DiscordThreadMember } from './channel.js' -import type { DiscordEmoji } from './emoji.js' -import type { DiscordGuildCreateExtra } from './gateway.js' -import type { DiscordInvite } from './invite.js' -import type { OAuth2Scope } from './oauth2.js' -import type { DiscordRole } from './permissions.js' -import type { DiscordSticker } from './sticker.js' -import type { DiscordAvatarDecorationData, DiscordUser } from './user.js' +import type { DiscordChannel, DiscordThreadMember } from './channel.js'; +import type { DiscordEmoji } from './emoji.js'; +import type { DiscordGuildCreateExtra } from './gateway.js'; +import type { DiscordInvite } from './invite.js'; +import type { OAuth2Scope } from './oauth2.js'; +import type { DiscordRole } from './permissions.js'; +import type { DiscordSticker } from './sticker.js'; +import type { DiscordAvatarDecorationData, DiscordUser } from './user.js'; /** https://discord.com/developers/docs/resources/guild#guild-object-guild-structure */ export interface DiscordGuild extends Partial { /** Guild id */ - id: string + id: string; /** Guild name (2-100 characters, excluding trailing and leading whitespace) */ - name: string + name: string; /** Icon hash */ - icon: string | null + icon: string | null; /** Icon hash, returned when in the template object */ - icon_hash?: string | null + icon_hash?: string | null; /** Splash hash */ - splash: string | null + splash: string | null; /** Discovery splash hash; only present for guilds with the "DISCOVERABLE" feature */ - discovery_splash: string | null + discovery_splash: string | null; /** * True if the user is the owner of the guild * * @remarks * This field is only sent when using the `Get Guilds` endpoint */ - owner?: boolean + owner?: boolean; /** Id of the owner */ - owner_id: string + owner_id: string; /** * Total permissions for the user in the guild (excludes overwrites and implicit permissions) * * @remarks * This field is only sent when using the `Get Guilds` endpoint */ - permissions?: string + permissions?: string; /** * Voice region id for the guild * * @deprecated * This field is deprecated and is replaced by {@link DiscordChannel.rtc_region | Channel.rtc_region} */ - region?: string | null + region?: string | null; /** Id of afk channel */ - afk_channel_id: string | null + afk_channel_id: string | null; /** Afk timeout in seconds */ - afk_timeout: number + afk_timeout: number; /** True if the server widget is enabled */ - widget_enabled?: boolean + widget_enabled?: boolean; /** The channel id that the widget will generate an invite to, or null if set to no invite */ - widget_channel_id?: string | null + widget_channel_id?: string | null; /** Verification level required for the guild */ - verification_level: VerificationLevels + verification_level: VerificationLevels; /** Default message notifications level */ - default_message_notifications: DefaultMessageNotificationLevels + default_message_notifications: DefaultMessageNotificationLevels; /** Explicit content filter level */ - explicit_content_filter: ExplicitContentFilterLevels + explicit_content_filter: ExplicitContentFilterLevels; /** Roles in the guild */ - roles: DiscordRole[] + roles: DiscordRole[]; /** Custom guild emojis */ - emojis: DiscordEmoji[] + emojis: DiscordEmoji[]; /** Enabled guild features */ - features: GuildFeatures[] + features: GuildFeatures[]; /** Required MFA level for the guild */ - mfa_level: MfaLevels + mfa_level: MfaLevels; /** Application id of the guild creator if it is bot-created */ - application_id: string | null + application_id: string | null; /** The id of the channel where guild notices such as welcome messages and boost events are posted */ - system_channel_id: string | null + system_channel_id: string | null; /** System channel flags */ - system_channel_flags: SystemChannelFlags + system_channel_flags: SystemChannelFlags; /** The id of the channel where community guilds can display rules and/or guidelines */ - rules_channel_id: string | null + rules_channel_id: string | null; /** The maximum number of presences for the guild (the default value, currently 25000, is in effect when null is returned) */ - max_presences?: number | null + max_presences?: number | null; /** The maximum number of members for the guild */ - max_members?: number + max_members?: number; /** The vanity url code for the guild */ - vanity_url_code: string | null + vanity_url_code: string | null; /** The description of a guild */ - description: string | null + description: string | null; /** Banner hash */ - banner: string | null + banner: string | null; /** Premium tier (Server Boost level) */ - premium_tier: PremiumTiers + premium_tier: PremiumTiers; /** The number of boosts this guild currently has */ - premium_subscription_count?: number + premium_subscription_count?: number; /** The preferred locale of a Community guild; used in server discovery and notices from Discord; defaults to "en-US" */ - preferred_locale: string + preferred_locale: string; /** The id of the channel where admins and moderators of Community guilds receive notices from Discord */ - public_updates_channel_id: string | null + public_updates_channel_id: string | null; /** The maximum amount of users in a video channel */ - max_video_channel_users?: number + max_video_channel_users?: number; /** Maximum amount of users in a stage video channel */ - max_stage_video_channel_users?: number + max_stage_video_channel_users?: number; /** Approximate number of members in this guild, returned from the GET /guilds/id endpoint when with_counts is true */ - approximate_member_count?: number + approximate_member_count?: number; /** Approximate number of non-offline members in this guild, returned from the GET /guilds/id endpoint when with_counts is true */ - approximate_presence_count?: number + approximate_presence_count?: number; /** The welcome screen of a Community guild, shown to new members, returned in an Invite's guild object */ - welcome_screen?: DiscordWelcomeScreen + welcome_screen?: DiscordWelcomeScreen; /** Guild NSFW level */ - nsfw_level: GuildNsfwLevel + nsfw_level: GuildNsfwLevel; /** Custom guild stickers */ - stickers?: DiscordSticker[] + stickers?: DiscordSticker[]; /** Whether the guild has the boost progress bar enabled */ - premium_progress_bar_enabled: boolean + premium_progress_bar_enabled: boolean; /** The id of the channel where admins and moderators of Community guilds receive safety alerts from Discord */ - safety_alerts_channel_id: string | null + safety_alerts_channel_id: string | null; /** The incidents data for this guild */ - incidents_data: DiscordIncidentsData | null + incidents_data: DiscordIncidentsData | null; } /** https://discord.com/developers/docs/resources/guild#guild-object-default-message-notification-level */ @@ -286,87 +286,87 @@ export interface DiscordUnavailableGuild extends Pick[] - members: Partial[] - presence_count: number + id: string; + name: string; + instant_invite: string | null; + channels: Partial[]; + members: Partial[]; + presence_count: number; } /** https://discord.com/developers/docs/resources/guild#guild-member-object-guild-member-structure */ export interface DiscordMember { /** The user this guild member represents */ - user?: DiscordUser + user?: DiscordUser; /** This user's guild nickname */ - nick?: string | null + nick?: string | null; /** The member's custom avatar for this server. */ - avatar?: string | null + avatar?: string | null; /** The member's guild banner */ - banner?: string | null + banner?: string | null; /** Array of role object ids */ - roles: string[] + roles: string[]; /** * When the user joined the guild * * @remarks Member objects retrieved from `VOICE_STATE_UPDATE` events will have `joined_at` set as `null` if the member was invited as a guest. */ - joined_at: string | null + joined_at: string | null; /** When the user started boosting the guild */ - premium_since?: string | null + premium_since?: string | null; /** Whether the user is deafened in voice channels */ - deaf: boolean + deaf: boolean; /** Whether the user is muted in voice channels */ - mute: boolean + mute: boolean; /** Guild member flags */ - flags: number + flags: number; /** Whether the user has not yet passed the guild's Membership Screening requirements */ - pending?: boolean + pending?: boolean; /** The permissions this member has in the guild. Only present on interaction events and OAuth2 current member fetch. */ - permissions?: string + permissions?: string; /** when the user's timeout will expire and the user will be able to communicate in the guild again (set null to remove timeout), null or a time in the past if the user is not timed out */ - communication_disabled_until?: string | null + communication_disabled_until?: string | null; /** data for the member's guild avatar decoration */ - avatar_decoration_data?: DiscordAvatarDecorationData | null + avatar_decoration_data?: DiscordAvatarDecorationData | null; } /** https://discord.com/developers/docs/resources/guild#guild-member-object-guild-member-structure */ export interface DiscordMemberWithUser extends DiscordMember { /** The user object for this member */ - user: DiscordUser + user: DiscordUser; } /** https://discord.com/developers/docs/resources/guild#guild-member-object-guild-member-flags */ @@ -441,37 +441,37 @@ export enum MemberFlags { /** https://discord.com/developers/docs/resources/guild#integration-object-integration-structure */ export interface DiscordIntegration { /** Integration Id */ - id: string + id: string; /** Integration name */ - name: string + name: string; /** Integration type (twitch, youtube, discord, or guild_subscription). */ - type: 'twitch' | 'youtube' | 'discord' | 'guild_subscription' + type: 'twitch' | 'youtube' | 'discord' | 'guild_subscription'; /** Is this integration enabled */ - enabled: boolean + enabled: boolean; /** Is this integration syncing */ - syncing?: boolean + syncing?: boolean; /** Role Id that this integration uses for "subscribers" */ - role_id?: string + role_id?: string; /** Whether emoticons should be synced for this integration (twitch only currently) */ - enable_emoticons?: boolean + enable_emoticons?: boolean; /** The behavior of expiring subscribers */ - expire_behavior?: IntegrationExpireBehaviors + expire_behavior?: IntegrationExpireBehaviors; /** The grace period (in days) before expiring subscribers */ - expire_grace_period?: number + expire_grace_period?: number; /** User for this integration */ - user?: DiscordUser + user?: DiscordUser; /** Integration account information */ - account: DiscordIntegrationAccount + account: DiscordIntegrationAccount; /** When this integration was last synced */ - synced_at?: string + synced_at?: string; /** How many subscribers this integration has */ - subscriber_count?: number + subscriber_count?: number; /** Has this integration been revoked */ - revoked?: boolean + revoked?: boolean; /** The bot/OAuth2 application for discord integrations */ - application?: DiscordIntegrationApplication + application?: DiscordIntegrationApplication; /** the scopes the application has been authorized for */ - scopes: OAuth2Scope[] + scopes: OAuth2Scope[]; } /** https://discord.com/developers/docs/resources/guild#integration-object-integration-expire-behaviors */ @@ -483,125 +483,125 @@ export enum IntegrationExpireBehaviors { /** https://discord.com/developers/docs/resources/guild#integration-account-object-integration-account-structure */ export interface DiscordIntegrationAccount { /** Id of the account */ - id: string + id: string; /** Name of the account */ - name: string + name: string; } /** https://discord.com/developers/docs/resources/guild#integration-application-object-integration-application-structure */ export interface DiscordIntegrationApplication { /** The id of the app */ - id: string + id: string; /** The name of the app */ - name: string + name: string; /** the icon hash of the app */ - icon: string | null + icon: string | null; /** The description of the app */ - description: string + description: string; /** The bot associated with this application */ - bot?: DiscordUser + bot?: DiscordUser; } /** https://discord.com/developers/docs/resources/guild#ban-object-ban-structure */ export interface DiscordBan { /** The reason for the ban */ - reason: string | null + reason: string | null; /** The banned user */ - user: DiscordUser + user: DiscordUser; } /** https://discord.com/developers/docs/resources/guild#welcome-screen-object-welcome-screen-structure */ export interface DiscordWelcomeScreen { /** The server description shown in the welcome screen */ - description: string | null + description: string | null; /** The channels shown in the welcome screen, up to 5 */ - welcome_channels: DiscordWelcomeScreenChannel[] + welcome_channels: DiscordWelcomeScreenChannel[]; } /** https://discord.com/developers/docs/resources/guild#welcome-screen-object-welcome-screen-channel-structure */ export interface DiscordWelcomeScreenChannel { /** The channel's id */ - channel_id: string + channel_id: string; /** The description shown for the channel */ - description: string + description: string; /** The emoji id, if the emoji is custom */ - emoji_id: string | null + emoji_id: string | null; /** The emoji name if custom, the unicode character if standard, or `null` if no emoji is set */ - emoji_name: string | null + emoji_name: string | null; } /** https://discord.com/developers/docs/resources/guild#guild-onboarding-object-guild-onboarding-structure */ export interface DiscordGuildOnboarding { /** ID of the guild this onboarding is part of */ - guild_id: string + guild_id: string; /** Prompts shown during onboarding and in customize community */ - prompts: DiscordGuildOnboardingPrompt[] + prompts: DiscordGuildOnboardingPrompt[]; /** Channel IDs that members get opted into automatically */ - default_channel_ids: string[] + default_channel_ids: string[]; /** Whether onboarding is enabled in the guild */ - enabled: boolean + enabled: boolean; /** Current mode of onboarding */ - mode: DiscordGuildOnboardingMode + mode: DiscordGuildOnboardingMode; } /** https://discord.com/developers/docs/resources/guild#guild-onboarding-object-onboarding-prompt-structure */ export interface DiscordGuildOnboardingPrompt { /** ID of the prompt */ - id: string + id: string; /** Type of prompt */ - type: DiscordGuildOnboardingPromptType + type: DiscordGuildOnboardingPromptType; /** Options available within the prompt */ - options: DiscordGuildOnboardingPromptOption[] + options: DiscordGuildOnboardingPromptOption[]; /** Title of the prompt */ - title: string + title: string; /** Indicates whether users are limited to selecting one option for the prompt */ - single_select: boolean + single_select: boolean; /** Indicates whether the prompt is required before a user completes the onboarding flow */ - required: boolean + required: boolean; /** Indicates whether the prompt is present in the onboarding flow. If `false`, the prompt will only appear in the Channels & Roles tab */ - in_onboarding: boolean + in_onboarding: boolean; } /** https://discord.com/developers/docs/resources/guild#guild-onboarding-object-prompt-option-structure */ export interface DiscordGuildOnboardingPromptOption { /** ID of the prompt option */ - id: string + id: string; /** IDs for channels a member is added to when the option is selected */ - channel_ids: string[] + channel_ids: string[]; /** IDs for roles assigned to a member when the option is selected */ - role_ids: string[] + role_ids: string[]; /** * Emoji of the option * * @remarks * When creating or updating a prompt option, the `emoji_id`, `emoji_name`, and `emoji_animated` fields must be used instead of the emoji object. */ - emoji?: DiscordEmoji + emoji?: DiscordEmoji; /** * Emoji ID of the option * * @remarks * When creating or updating a prompt option, the `emoji_id`, `emoji_name`, and `emoji_animated` fields must be used instead of the emoji object. */ - emoji_id?: string + emoji_id?: string; /** * Emoji name of the option * * @remarks * When creating or updating a prompt option, the `emoji_id`, `emoji_name`, and `emoji_animated` fields must be used instead of the emoji object. */ - emoji_name?: string + emoji_name?: string; /** * Whether the emoji is animated * * @remarks * When creating or updating a prompt option, the `emoji_id`, `emoji_name`, and `emoji_animated` fields must be used instead of the emoji object. */ - emoji_animated?: boolean + emoji_animated?: boolean; /** Title of the option */ - title: string + title: string; /** Description of the option */ - description: string | null + description: string | null; } /** https://discord.com/developers/docs/resources/guild#guild-onboarding-object-onboarding-mode */ @@ -621,39 +621,39 @@ export enum DiscordGuildOnboardingPromptType { /** https://discord.com/developers/docs/resources/guild#incidents-data-object-incidents-data-structure */ export interface DiscordIncidentsData { /** When invites get enabled again */ - invites_disabled_until: string | null + invites_disabled_until: string | null; /** When direct messages get enabled again */ - dms_disabled_until: string | null + dms_disabled_until: string | null; /** When the dm spam was detected */ - dm_spam_detected_at?: string | null + dm_spam_detected_at?: string | null; /** When the raid was detected */ - raid_detected_at?: string | null + raid_detected_at?: string | null; } /** https://discord.com/developers/docs/resources/guild#list-active-guild-threads-response-body */ export interface DiscordListActiveThreads { /** The active threads */ - threads: DiscordChannel[] + threads: DiscordChannel[]; /** A thread member object for each returned thread the current user has joined */ - members: DiscordThreadMember[] + members: DiscordThreadMember[]; } /** https://discord.com/developers/docs/resources/guild#bulk-guild-ban-bulk-ban-response */ export interface DiscordBulkBan { /** list of user ids, that were successfully banned */ - banned_users: string[] + banned_users: string[]; /** list of user ids, that were not banned */ - failed_users: string[] + failed_users: string[]; } /** https://discord.com/developers/docs/resources/guild#get-guild-prune-count */ export interface DiscordPrunedCount { - pruned: number + pruned: number; } /** https://discord.com/developers/docs/resources/guild#get-guild-vanity-url */ // TODO: This should provably have another name for clarity to what it really rappresent export interface DiscordVanityUrl extends Partial> { - code: string | null - uses: number + code: string | null; + uses: number; } diff --git a/packages/types/src/discord/guildScheduledEvent.ts b/packages/types/src/discord/guildScheduledEvent.ts index 71d9a4e71..300cd64df 100644 --- a/packages/types/src/discord/guildScheduledEvent.ts +++ b/packages/types/src/discord/guildScheduledEvent.ts @@ -1,44 +1,44 @@ /** Types for: https://discord.com/developers/docs/resources/guild-scheduled-event */ -import type { DiscordMember } from './guild.js' -import type { DiscordUser } from './user.js' +import type { DiscordMember } from './guild.js'; +import type { DiscordUser } from './user.js'; /** https://discord.com/developers/docs/resources/guild-scheduled-event#guild-scheduled-event-object-guild-scheduled-event-structure */ export interface DiscordScheduledEvent { /** the id of the scheduled event */ - id: string + id: string; /** the guild id which the scheduled event belongs to */ - guild_id: string + guild_id: string; /** the channel id in which the scheduled event will be hosted if specified */ - channel_id: string | null + channel_id: string | null; /** the id of the user that created the scheduled event */ - creator_id?: string | null + creator_id?: string | null; /** the name of the scheduled event */ - name: string + name: string; /** the description of the scheduled event */ - description?: string | null + description?: string | null; /** the time the scheduled event will start */ - scheduled_start_time: string + scheduled_start_time: string; /** the time the scheduled event will end if it does end. */ - scheduled_end_time: string | null + scheduled_end_time: string | null; /** the privacy level of the scheduled event */ - privacy_level: ScheduledEventPrivacyLevel + privacy_level: ScheduledEventPrivacyLevel; /** the status of the scheduled event */ - status: ScheduledEventStatus + status: ScheduledEventStatus; /** the type of hosting entity associated with a scheduled event */ - entity_type: ScheduledEventEntityType + entity_type: ScheduledEventEntityType; /** any additional id of the hosting entity associated with event */ - entity_id: string | null + entity_id: string | null; /** the entity metadata for the scheduled event */ - entity_metadata: DiscordScheduledEventEntityMetadata | null + entity_metadata: DiscordScheduledEventEntityMetadata | null; /** the user that created the scheduled event */ - creator?: DiscordUser + creator?: DiscordUser; /** the number of users subscribed to the scheduled event */ - user_count?: number + user_count?: number; /** the cover image hash of the scheduled event */ - image?: string | null + image?: string | null; /** the definition for how often this event should recur */ - recurrence_rule: DiscordScheduledEventRecurrenceRule | null + recurrence_rule: DiscordScheduledEventRecurrenceRule | null; } /** https://discord.com/developers/docs/resources/guild-scheduled-event#guild-scheduled-event-object-guild-scheduled-event-privacy-level */ @@ -65,41 +65,41 @@ export enum ScheduledEventStatus { /** https://discord.com/developers/docs/resources/guild-scheduled-event#guild-scheduled-event-object-guild-scheduled-event-entity-metadata */ export interface DiscordScheduledEventEntityMetadata { /** location of the event */ - location?: string + location?: string; } /** https://discord.com/developers/docs/resources/guild-scheduled-event#guild-scheduled-event-user-object-guild-scheduled-event-user-structure */ export interface DiscordScheduledEventUser { /** The scheduled event id which the user subscribed to */ - guild_scheduled_event_id: string + guild_scheduled_event_id: string; /** User which subscribed to an event */ - user: DiscordUser + user: DiscordUser; /** Guild member data for this user for the guild which this event belongs to, if any */ - member?: DiscordMember + member?: DiscordMember; } /** https://discord.com/developers/docs/resources/guild-scheduled-event#guild-scheduled-event-recurrence-rule-object-guild-scheduled-event-recurrence-rule-structure */ export interface DiscordScheduledEventRecurrenceRule { /** Starting time of the recurrence interval */ - start: string + start: string; /** Ending time of the recurrence interval */ - end: string | null + end: string | null; /** How often the event occurs */ - frequency: DiscordScheduledEventRecurrenceRuleFrequency + frequency: DiscordScheduledEventRecurrenceRuleFrequency; /** The spacing between the events, defined by `frequency`. For example, `frequency` of `Weekly` and an `interval` of `2` would be "every-other week" */ - interval: number + interval: number; /** Set of specific days within a week for the event to recur on */ - by_weekday: DiscordScheduledEventRecurrenceRuleWeekday[] | null + by_weekday: DiscordScheduledEventRecurrenceRuleWeekday[] | null; /** List of specific days within a specific week (1-5) to recur on */ - by_n_weekday: DiscordScheduledEventRecurrenceRuleNWeekday[] | null + by_n_weekday: DiscordScheduledEventRecurrenceRuleNWeekday[] | null; /** Set of specific months to recur on */ - by_month: DiscordScheduledEventRecurrenceRuleMonth[] | null + by_month: DiscordScheduledEventRecurrenceRuleMonth[] | null; /** Set of specific dates within a month to recur on */ - by_month_day: number[] | null + by_month_day: number[] | null; /** Set of days within a year to recur on (1-364) */ - by_year_day: number[] | null + by_year_day: number[] | null; /** The total amount of times that the event is allowed to recur before stopping */ - count: number | null + count: number | null; } /** https://discord.com/developers/docs/resources/guild-scheduled-event#guild-scheduled-event-recurrence-rule-object-guild-scheduled-event-recurrence-rule-frequency */ @@ -124,9 +124,9 @@ export enum DiscordScheduledEventRecurrenceRuleWeekday { /** https://discord.com/developers/docs/resources/guild-scheduled-event#guild-scheduled-event-recurrence-rule-object-guild-scheduled-event-recurrence-rule-nweekday-structure */ export interface DiscordScheduledEventRecurrenceRuleNWeekday { /** The week to reoccur on. 1 - 5 */ - n: number + n: number; /** The day within the week to reoccur on */ - day: DiscordScheduledEventRecurrenceRuleWeekday + day: DiscordScheduledEventRecurrenceRuleWeekday; } /** https://discord.com/developers/docs/resources/guild-scheduled-event#guild-scheduled-event-recurrence-rule-object-guild-scheduled-event-recurrence-rule-month */ diff --git a/packages/types/src/discord/guildTemplate.ts b/packages/types/src/discord/guildTemplate.ts index f4399ccfa..78ec16f45 100644 --- a/packages/types/src/discord/guildTemplate.ts +++ b/packages/types/src/discord/guildTemplate.ts @@ -1,34 +1,34 @@ /** Types for: https://discord.com/developers/docs/resources/guild-template */ -import type { PickPartial } from '../shared.js' -import type { DiscordChannel, DiscordOverwrite } from './channel.js' -import type { DiscordGuild } from './guild.js' -import type { DiscordRole } from './permissions.js' -import type { DiscordUser } from './user.js' +import type { PickPartial } from '../shared.js'; +import type { DiscordChannel, DiscordOverwrite } from './channel.js'; +import type { DiscordGuild } from './guild.js'; +import type { DiscordRole } from './permissions.js'; +import type { DiscordUser } from './user.js'; /** https://discord.com/developers/docs/resources/guild-template#guild-template-object-guild-template-structure */ export interface DiscordTemplate { /** The template code (unique Id) */ - code: string + code: string; /** Template name */ - name: string + name: string; /** The description for the template */ - description: string | null + description: string | null; /** Number of times this template has been used */ - usage_count: number + usage_count: number; /** The Id of the user who created the template */ - creator_id: string + creator_id: string; /** The user who created the template */ - creator: DiscordUser + creator: DiscordUser; /** When this template was created */ - created_at: string + created_at: string; /** When this template was last synced to the source guild */ - updated_at: string + updated_at: string; /** The Id of the guild this template is based on */ - source_guild_id: string + source_guild_id: string; /** The guild snapshot this template contains */ - serialized_source_guild: DiscordTemplateSerializedSourceGuild - is_dirty: boolean | null + serialized_source_guild: DiscordTemplateSerializedSourceGuild; + is_dirty: boolean | null; } /** https://discord.com/developers/docs/resources/guild-template#guild-template-object-guild-template-structure specificly the serialized_source_guild property */ @@ -46,13 +46,13 @@ export type DiscordTemplateSerializedSourceGuild = Omit< >, 'roles' | 'channels' | 'afk_channel_id' | 'system_channel_id' > & { - afk_channel_id: number | null - system_channel_id: number | null + afk_channel_id: number | null; + system_channel_id: number | null; roles: Array< Omit, 'id'> & { - id: number + id: number; } - > + >; channels: Array< Omit< PickPartial< @@ -74,9 +74,9 @@ export type DiscordTemplateSerializedSourceGuild = Omit< >, 'id' | 'permission_overwrites' | 'parent_id' > & { - id: number - permission_overwrites: DiscordOverwrite & { id: number } - parent_id: number | null + id: number; + permission_overwrites: DiscordOverwrite & { id: number }; + parent_id: number | null; } - > -} + >; +}; diff --git a/packages/types/src/discord/interactions.ts b/packages/types/src/discord/interactions.ts index 9d05bc310..018e109b7 100644 --- a/packages/types/src/discord/interactions.ts +++ b/packages/types/src/discord/interactions.ts @@ -4,75 +4,75 @@ * - https://discord.com/developers/docs/interactions/application-commands */ -import type { DiscordApplicationIntegrationType } from './application.js' -import type { ChannelTypes, DiscordChannel } from './channel.js' -import type { DiscordMessageComponentFromModalInteractionResponse, MessageComponentTypes } from './components.js' -import type { DiscordEntitlement } from './entitlement.js' -import type { DiscordGuild, DiscordMember, DiscordMemberWithUser } from './guild.js' -import type { DiscordAttachment, DiscordMessage } from './message.js' -import type { DiscordRole } from './permissions.js' -import type { Localization } from './reference.js' -import type { DiscordUser } from './user.js' +import type { DiscordApplicationIntegrationType } from './application.js'; +import type { ChannelTypes, DiscordChannel } from './channel.js'; +import type { DiscordMessageComponentFromModalInteractionResponse, MessageComponentTypes } from './components.js'; +import type { DiscordEntitlement } from './entitlement.js'; +import type { DiscordGuild, DiscordMember, DiscordMemberWithUser } from './guild.js'; +import type { DiscordAttachment, DiscordMessage } from './message.js'; +import type { DiscordRole } from './permissions.js'; +import type { Localization } from './reference.js'; +import type { DiscordUser } from './user.js'; /** https://discord.com/developers/docs/interactions/receiving-and-responding#interaction-object-interaction-structure */ export interface DiscordInteraction { /** Id of the interaction */ - id: string + id: string; /** Id of the application this interaction is for */ - application_id: string + application_id: string; /** The type of interaction */ - type: InteractionTypes + type: InteractionTypes; /** * The command data payload * @remarks This is always present on application command, message component, and modal submit interaction types. It is optional for future-proofing against new interaction types */ - data?: DiscordInteractionData + data?: DiscordInteractionData; /** Guild that the interaction was sent from */ - guild?: Partial + guild?: Partial; /** The guild it was sent from */ - guild_id?: string + guild_id?: string; /** The channel it was sent from */ - channel: Partial + channel: Partial; /** * The ID of channel it was sent from * * @remarks * It is recommended that you begin using this channel field to identify the source channel of the interaction as they may deprecate the existing channel_id field in the future. */ - channel_id?: string + channel_id?: string; /** Guild member data for the invoking user, including permissions */ - member?: DiscordInteractionMember + member?: DiscordInteractionMember; /** User object for the invoking user, if invoked in a DM */ - user?: DiscordUser + user?: DiscordUser; /** A continuation token for responding to the interaction */ - token: string + token: string; /** Read-only property, always `1` */ - version: 1 + version: 1; /** For components or modals triggered by components, the message they were attached to */ - message?: DiscordMessage + message?: DiscordMessage; /** * Bitwise set of permissions the app has in the source location of the interaction * @remarks app_permissions includes ATTACH_FILES | EMBED_LINKS | MENTION_EVERYONE permissions for (G)DMs with other users, and additionally includes USE_EXTERNAL_EMOJIS for DMs with the app's bot user */ - app_permissions: string + app_permissions: string; /** The selected language of the invoking user */ - locale?: string + locale?: string; /** The guild's preferred locale, if invoked in a guild */ - guild_locale?: string + guild_locale?: string; /** For monetized apps, any entitlements for the invoking user, representing access to premium SKUs */ - entitlements: DiscordEntitlement[] + entitlements: DiscordEntitlement[]; /** Mapping of installation contexts that the interaction was authorized for to related user or guild IDs. */ - authorizing_integration_owners: DiscordAuthorizingIntegrationOwners + authorizing_integration_owners: DiscordAuthorizingIntegrationOwners; /** Context where the interaction was triggered from */ - context?: DiscordInteractionContextType + context?: DiscordInteractionContextType; /** Attachment size limit in bytes */ - attachment_size_limit: number + attachment_size_limit: number; } /** https://discord.com/developers/docs/interactions/receiving-and-responding#interaction-object-interaction-structure (Specifically, the member propriety) */ export interface DiscordInteractionMember extends DiscordMemberWithUser { /** Total permissions of the member in the channel, including overwrites, returned when in the interaction object */ - permissions: string + permissions: string; } /** https://discord.com/developers/docs/interactions/receiving-and-responding#interaction-object-interaction-type */ @@ -95,7 +95,7 @@ export enum DiscordInteractionContextType { } /** https://discord.com/developers/docs/interactions/receiving-and-responding#interaction-object-authorizing-integration-owners-object */ -export type DiscordAuthorizingIntegrationOwners = Partial> +export type DiscordAuthorizingIntegrationOwners = Partial>; // Since this is a merge of 3 types, the properties appear in order of their first appearance in the 3 types /** @@ -106,42 +106,42 @@ export type DiscordAuthorizingIntegrationOwners = Partial + users?: Record; /** The Ids and partial Member objects */ - members?: Record> + members?: Record>; /** The Ids and Role objects */ - roles?: Record + roles?: Record; /** * The Ids and partial Channel objects * @@ -167,39 +167,39 @@ export interface DiscordInteractionDataResolved { | 'position' | 'thread_metadata' > - > + >; /** The Ids and Message objects */ - messages?: Record> + messages?: Record>; /** The ids and attachment objects */ - attachments: Record + attachments: Record; } /** https://discord.com/developers/docs/interactions/receiving-and-responding#interaction-object-application-command-interaction-data-option-structure */ export interface DiscordInteractionDataOption { /** Name of the parameter */ - name: string + name: string; /** Value of application command option type */ - type: ApplicationCommandOptionTypes + type: ApplicationCommandOptionTypes; /** Value of the option resulting from user input */ - value?: string | boolean | number + value?: string | boolean | number; /** Present if this option is a group or subcommand */ - options?: DiscordInteractionDataOption[] + options?: DiscordInteractionDataOption[]; /** `true` if this option is the currently focused option for autocomplete */ - focused?: boolean + focused?: boolean; } /** https://discord.com/developers/docs/interactions/receiving-and-responding#message-interaction-object-message-interaction-structure */ export interface DiscordMessageInteraction { /** Id of the interaction */ - id: string + id: string; /** The type of interaction */ - type: InteractionTypes + type: InteractionTypes; /** The name of the ApplicationCommand including the name of the subcommand/subcommand group */ - name: string + name: string; /** The user who invoked the interaction */ - user: DiscordUser + user: DiscordUser; /** The member who invoked the interaction in the guild */ - member?: Partial + member?: Partial; } /** https://discord.com/developers/docs/interactions/receiving-and-responding#interaction-response-object-interaction-callback-type */ @@ -236,62 +236,62 @@ export enum InteractionResponseTypes { /** https://discord.com/developers/docs/interactions/receiving-and-responding#interaction-callback-interaction-callback-response-object */ export interface DiscordInteractionCallbackResponse { /** The interaction object associated with the interaction response */ - interaction: DiscordInteractionCallback + interaction: DiscordInteractionCallback; /** The resource that was created by the interaction response. */ - resource?: DiscordInteractionResource + resource?: DiscordInteractionResource; } /** https://discord.com/developers/docs/interactions/receiving-and-responding#interaction-callback-interaction-callback-object */ export interface DiscordInteractionCallback { /** ID of the interaction */ - id: string + id: string; /** Interaction type */ - type: InteractionTypes + type: InteractionTypes; /** Instance ID of the Activity if one was launched or joined */ - activity_instance_id?: string + activity_instance_id?: string; /** ID of the message that was created by the interaction */ - response_message_id?: string + response_message_id?: string; /** Whether the message is in a loading state */ - response_message_loading?: boolean + response_message_loading?: boolean; /** Whether the response message is ephemeral */ - response_message_ephemeral?: boolean + response_message_ephemeral?: boolean; } /** https://discord.com/developers/docs/interactions/receiving-and-responding#interaction-callback-interaction-callback-resource-object */ export interface DiscordInteractionResource { - type: InteractionResponseTypes + type: InteractionResponseTypes; /** * Represents the Activity launched by this interaction. * * @remarks * Only present if type is `LAUNCH_ACTIVITY`. */ - activity_instance?: DiscordActivityInstanceResource + activity_instance?: DiscordActivityInstanceResource; /** * Message created by the interaction. * * @remarks * Only present if type is either `CHANNEL_MESSAGE_WITH_SOURCE` or `UPDATE_MESSAGE`. */ - message?: DiscordMessage + message?: DiscordMessage; } /** https://discord.com/developers/docs/interactions/receiving-and-responding#interaction-callback-interaction-callback-activity-instance-resource */ export interface DiscordActivityInstanceResource { /** Instance ID of the Activity if one was launched or joined. */ - id: string + id: string; } /** https://discord.com/developers/docs/interactions/application-commands#application-command-object-application-command-structure */ export interface DiscordApplicationCommand { /** Unique ID of command */ - id: string + id: string; /** Type of command, defaults to `ApplicationCommandTypes.ChatInput` */ - type?: ApplicationCommandTypes + type?: ApplicationCommandTypes; /** ID of the parent application */ - application_id: string + application_id: string; /** Guild id of the command, if not global */ - guild_id?: string + guild_id?: string; /** * Name of command, 1-32 characters. * `ApplicationCommandTypes.ChatInput` command names must match the following regex `^[-_ʼ\p{L}\p{N}\p{sc=Deva}\p{sc=Thai}]{1,32}$` with the unicode flag set. @@ -299,23 +299,23 @@ export interface DiscordApplicationCommand { * Characters with no lowercase variants and/or uncased letters are still allowed. * ApplicationCommandTypes.User` and `ApplicationCommandTypes.Message` commands may be mixed case and can include spaces. */ - name: string + name: string; /** Localization object for `name` field. Values follow the same restrictions as `name` */ - name_localizations?: Localization | null + name_localizations?: Localization | null; /** Description for `ApplicationCommandTypes.ChatInput` commands, 1-100 characters. */ - description: string + description: string; /** Localization object for `description` field. Values follow the same restrictions as `description` */ - description_localizations?: Localization | null + description_localizations?: Localization | null; /** Parameters for the command, max of 25 */ - options?: DiscordApplicationCommandOption[] + options?: DiscordApplicationCommandOption[]; /** Set of permissions represented as a bit set */ - default_member_permissions: string | null + default_member_permissions: string | null; /** * Indicates whether the command is available in DMs with the app, only for globally-scoped commands. By default, commands are visible. * * @deprecated use {@link contexts} instead */ - dm_permission?: boolean + dm_permission?: boolean; /** * Indicates whether the command is enabled by default when the app is added to a guild * @@ -324,9 +324,9 @@ export interface DiscordApplicationCommand { * * @default true */ - default_permission?: boolean + default_permission?: boolean; /** Indicates whether the command is age-restricted, defaults to false */ - nsfw?: boolean + nsfw?: boolean; /** * Installation contexts where the command is available * @@ -334,23 +334,23 @@ export interface DiscordApplicationCommand { * This value is available only for globally-scoped commands * Defaults to the application configured contexts */ - integration_types?: DiscordApplicationIntegrationType[] + integration_types?: DiscordApplicationIntegrationType[]; /** * Interaction context(s) where the command can be used * * @remarks * This value is available only for globally-scoped commands. */ - contexts?: DiscordInteractionContextType[] | null + contexts?: DiscordInteractionContextType[] | null; /** Auto incrementing version identifier updated during substantial record changes */ - version: string + version: string; /** * Determines whether the interaction is handled by the app's interactions handler or by Discord * * @remarks * This can only be set for application commands of type `PRIMARY_ENTRY_POINT` for applications with the `EMBEDDED` flag (i.e. applications that have an Activity). */ - handler?: DiscordInteractionEntryPointCommandHandlerType + handler?: DiscordInteractionEntryPointCommandHandlerType; } /** https://discord.com/developers/docs/interactions/application-commands#application-command-object-application-command-types */ @@ -368,7 +368,7 @@ export enum ApplicationCommandTypes { /** https://discord.com/developers/docs/interactions/application-commands#application-command-object-application-command-option-structure */ export interface DiscordApplicationCommandOption { /** Type of option */ - type: ApplicationCommandOptionTypes + type: ApplicationCommandOptionTypes; /** * Name of command, 1-32 characters. * @@ -381,20 +381,20 @@ export interface DiscordApplicationCommandOption { * * {@link ApplicationCommandTypes.User | User} and {@link ApplicationCommandTypes.Message | Message} commands may be mixed case and can include spaces. */ - name: string + name: string; /** Localization object for the `name` field. Values follow the same restrictions as `name` */ - name_localizations?: Localization | null + name_localizations?: Localization | null; /** 1-100 character description */ - description: string + description: string; /** Localization object for the `description` field. Values follow the same restrictions as `description` */ - description_localizations?: Localization | null + description_localizations?: Localization | null; /** * If the parameter is required or optional. default `false` * * @remarks * Valid in all option types except {@link ApplicationCommandOptionTypes.SubCommand | SubCommand} and {@link ApplicationCommandOptionTypes.SubCommandGroup | SubCommandGroup} */ - required?: boolean + required?: boolean; /** * Choices for the option from which the user can choose, max 25 * @@ -403,49 +403,49 @@ export interface DiscordApplicationCommandOption { * * If you provide an array of choices, they will be the ONLY accepted values for this option */ - choices?: DiscordApplicationCommandOptionChoice[] + choices?: DiscordApplicationCommandOptionChoice[]; /** * If the option is a subcommand or subcommand group type, these nested options will be the parameters * * @remarks * Only valid in option of type {@link ApplicationCommandOptionTypes.SubCommand | SubCommand} or {@link ApplicationCommandOptionTypes.SubCommandGroup | SubCommandGroup} */ - options?: DiscordApplicationCommandOption[] + options?: DiscordApplicationCommandOption[]; /** * The channels shown will be restricted to these types * * @remarks * Only valid in option of type {@link ApplicationCommandOptionTypes.Channel | Channel} */ - channel_types?: ChannelTypes[] + channel_types?: ChannelTypes[]; /** * The minimum permitted value * * @remarks * Only valid in options of type {@link ApplicationCommandOptionTypes.Integer | Integer} or {@link ApplicationCommandOptionTypes.Number | Number} */ - min_value?: number + min_value?: number; /** * The maximum permitted value * * @remarks * Only valid in options of type {@link ApplicationCommandOptionTypes.Integer | Integer} or {@link ApplicationCommandOptionTypes.Number | Number} */ - max_value?: number + max_value?: number; /** * The minimum permitted length, should be in the range of from 0 to 600 * * @remarks * Only valid in options of type {@link ApplicationCommandOptionTypes.String | String} */ - min_length?: number + min_length?: number; /** * The maximum permitted length, should be in the range of from 0 to 600 * * @remarks * Only valid in options of type {@link ApplicationCommandOptionTypes.String | String} */ - max_length?: number + max_length?: number; /** * If autocomplete interactions are enabled for this option. * @@ -454,7 +454,7 @@ export interface DiscordApplicationCommandOption { * * When {@link DiscordApplicationCommandOption.choices | choices} are provided, this may not be set to true */ - autocomplete?: boolean + autocomplete?: boolean; } /** https://discord.com/developers/docs/interactions/application-commands#application-command-object-application-command-option-type */ @@ -480,11 +480,11 @@ export enum ApplicationCommandOptionTypes { /** https://discord.com/developers/docs/interactions/application-commands#application-command-object-application-command-option-choice-structure */ export interface DiscordApplicationCommandOptionChoice { /** 1-100 character choice name */ - name: string + name: string; /** Localization object for the `name` field. Values follow the same restrictions as `name` */ - name_localizations?: Localization | null + name_localizations?: Localization | null; /** Value for the choice, up to 100 characters if string */ - value: string | number + value: string | number; } /** https://discord.com/developers/docs/interactions/application-commands#application-command-object-entry-point-command-handler-types */ @@ -498,23 +498,23 @@ export enum DiscordInteractionEntryPointCommandHandlerType { /** https://discord.com/developers/docs/interactions/application-commands#application-command-permissions-object-guild-application-command-permissions-structure */ export interface DiscordGuildApplicationCommandPermissions { /** ID of the command or the application ID. When the `id` field is the application ID instead of a command ID, the permissions apply to all commands that do not contain explicit overwrites. */ - id: string + id: string; /** ID of the application the command belongs to */ - application_id: string + application_id: string; /** ID of the guild */ - guild_id: string + guild_id: string; /** Permissions for the command in the guild, max of 100 */ - permissions: DiscordApplicationCommandPermissions[] + permissions: DiscordApplicationCommandPermissions[]; } /** https://discord.com/developers/docs/interactions/application-commands#application-command-permissions-object-application-command-permissions-structure */ export interface DiscordApplicationCommandPermissions { /** ID of the role, user, or channel. It can also be a permission constant */ - id: string + id: string; /** ApplicationCommandPermissionTypes.Role, ApplicationCommandPermissionTypes.User, or ApplicationCommandPermissionTypes.Channel */ - type: ApplicationCommandPermissionTypes + type: ApplicationCommandPermissionTypes; /** `true` to allow, `false`, to disallow */ - permission: boolean + permission: boolean; } /** https://discord.com/developers/docs/interactions/application-commands#application-command-permissions-object-application-command-permission-type */ diff --git a/packages/types/src/discord/invite.ts b/packages/types/src/discord/invite.ts index e9c8c1c58..c64a738dd 100644 --- a/packages/types/src/discord/invite.ts +++ b/packages/types/src/discord/invite.ts @@ -1,43 +1,43 @@ /** Types for: https://discord.com/developers/docs/resources/invite */ -import type { DiscordApplication } from './application.js' -import type { DiscordChannel } from './channel.js' -import type { DiscordGuild, DiscordMember } from './guild.js' -import type { DiscordScheduledEvent } from './guildScheduledEvent.js' -import type { DiscordUser } from './user.js' +import type { DiscordApplication } from './application.js'; +import type { DiscordChannel } from './channel.js'; +import type { DiscordGuild, DiscordMember } from './guild.js'; +import type { DiscordScheduledEvent } from './guildScheduledEvent.js'; +import type { DiscordUser } from './user.js'; /** https://discord.com/developers/docs/resources/invite#invite-object-invite-structure */ export interface DiscordInvite { /** The type of invite */ - type: DiscordInviteType + type: DiscordInviteType; /** The invite code (unique Id) */ - code: string + code: string; /** The guild this invite is for */ - guild?: Partial + guild?: Partial; /** The channel this invite is for */ - channel: Partial | null + channel: Partial | null; /** The user who created the invite */ - inviter?: DiscordUser + inviter?: DiscordUser; /** The type of target for this voice channel invite */ - target_type?: TargetTypes + target_type?: TargetTypes; /** The target user for this invite */ - target_user?: DiscordUser + target_user?: DiscordUser; /** The embedded application to open for this voice channel embedded application invite */ - target_application?: Partial + target_application?: Partial; /** Approximate count of online members (only present when target_user is set) */ - approximate_presence_count?: number + approximate_presence_count?: number; /** Approximate count of total members */ - approximate_member_count?: number + approximate_member_count?: number; /** The expiration date of this invite */ - expires_at: string | null + expires_at: string | null; /** guild scheduled event data */ - guild_scheduled_event?: DiscordScheduledEvent + guild_scheduled_event?: DiscordScheduledEvent; /** * Guild invite flags for guild invites. * * @see {@link DiscordGuildInviteFlags} */ - flags?: number + flags?: number; } /** https://discord.com/developers/docs/resources/invite#invite-object-invite-types */ @@ -62,15 +62,15 @@ export enum DiscordGuildInviteFlags { /** https://discord.com/developers/docs/resources/invite#invite-metadata-object-invite-metadata-structure */ export interface DiscordInviteMetadata extends DiscordInvite { /** Number of times this invite has been used */ - uses: number + uses: number; /** Max number of times this invite can be used */ - max_uses: number + max_uses: number; /** Duration (in seconds) after which the invite expires */ - max_age: number + max_age: number; /** Whether this invite only grants temporary membership */ - temporary: boolean + temporary: boolean; /** When this invite was created */ - created_at: string + created_at: string; } /** @@ -79,11 +79,11 @@ export interface DiscordInviteMetadata extends DiscordInvite { */ export interface DiscordInviteStageInstance { /** The members speaking in the Stage */ - members: Partial[] + members: Partial[]; /** The number of users in the Stage */ - participant_count: number + participant_count: number; /** The number of users speaking in the Stage */ - speaker_count: number + speaker_count: number; /** The topic of the Stage instance (1-120 characters) */ - topic: string + topic: string; } diff --git a/packages/types/src/discord/lobby.ts b/packages/types/src/discord/lobby.ts index b30637cce..e0926717b 100644 --- a/packages/types/src/discord/lobby.ts +++ b/packages/types/src/discord/lobby.ts @@ -1,29 +1,29 @@ /** Types for: https://discord.com/developers/docs/resources/lobby */ -import type { DiscordChannel } from './channel.js' +import type { DiscordChannel } from './channel.js'; /** https://discord.com/developers/docs/resources/lobby#lobby-object-lobby-structure */ export interface DiscordLobby { /** The id of this channel */ - id: string + id: string; /** application that created the lobby */ - application_id: string + application_id: string; /** dictionary of string key/value pairs. The max total length is 1000. */ - metadata: Record | null + metadata: Record | null; /** members of the lobby */ - members: DiscordLobbyMember[] + members: DiscordLobbyMember[]; /** the guild channel linked to the lobby */ - linked_channel?: DiscordChannel + linked_channel?: DiscordChannel; } /** https://discord.com/developers/docs/resources/lobby#lobby-member-object-lobby-member-structure */ export interface DiscordLobbyMember { /** The id of the user */ - id: string + id: string; /** dictionary of string key/value pairs. The max total length is 1000. */ - metadata?: Record | null + metadata?: Record | null; /** lobby member flags combined as as bitfield */ - flags?: number + flags?: number; } /** https://discord.com/developers/docs/resources/lobby#lobby-member-object-lobby-member-flags */ diff --git a/packages/types/src/discord/message.ts b/packages/types/src/discord/message.ts index d4f966e26..c423a7ad2 100644 --- a/packages/types/src/discord/message.ts +++ b/packages/types/src/discord/message.ts @@ -1,116 +1,116 @@ /** Types for: https://discord.com/developers/docs/resources/message */ -import type { DiscordApplication } from './application.js' -import type { DiscordChannel, DiscordThreadMember } from './channel.js' -import type { DiscordMessageComponents } from './components.js' -import type { DiscordEmoji } from './emoji.js' -import type { DiscordMessageCreateExtra } from './gateway.js' +import type { DiscordApplication } from './application.js'; +import type { DiscordChannel, DiscordThreadMember } from './channel.js'; +import type { DiscordMessageComponents } from './components.js'; +import type { DiscordEmoji } from './emoji.js'; +import type { DiscordMessageCreateExtra } from './gateway.js'; import type { DiscordAuthorizingIntegrationOwners, DiscordInteractionDataResolved, DiscordMessageInteraction, InteractionTypes, -} from './interactions.js' -import type { DiscordPoll } from './poll.js' -import type { DiscordSticker, DiscordStickerItem } from './sticker.js' -import type { DiscordUser } from './user.js' +} from './interactions.js'; +import type { DiscordPoll } from './poll.js'; +import type { DiscordSticker, DiscordStickerItem } from './sticker.js'; +import type { DiscordUser } from './user.js'; /** https://discord.com/developers/docs/resources/message#message-object-message-structure */ export interface DiscordMessage extends Partial { /** id of the message */ - id: string + id: string; /** id of the channel the message was sent in */ - channel_id: string + channel_id: string; /** * The author of this message (not guaranteed to be a valid user) * * @remarks * The author object follows the structure of the user object, but is only a valid user in the case where the message is generated by a user or bot user. If the message is generated by a webhook, the author object corresponds to the webhook's id, username, and avatar. You can tell if a message is generated by a webhook by checking for the webhook_id on the message object. */ - author: DiscordUser + author: DiscordUser; /** Contents of the message */ - content: string + content: string; /** When this message was sent */ - timestamp: string + timestamp: string; /** When this message was edited (or null if never) */ - edited_timestamp: string | null + edited_timestamp: string | null; /** Whether this was a TTS message */ - tts: boolean + tts: boolean; /** Whether this message mentions everyone */ - mention_everyone: boolean + mention_everyone: boolean; // TODO: When we separate the types between with extra fields from gateway and non, we should add back the mentions field below // For now it can remain from the gateway extra fields to avoid breaking changes for now. // /** Users specifically mentioned in the message */ // mentions: DiscordUser[] /** Roles specifically mentioned in this message */ - mention_roles: string[] + mention_roles: string[]; /** * Channels specifically mentioned in this message * Note: Not all channel mentions in a message will appear in `mention_channels`. Only textual channels that are visible to everyone in a discoverable guild will ever be included. Only crossposted messages (via Channel Following) currently include `mention_channels` at all. If no mentions in the message meet these requirements, this field will not be sent. */ - mention_channels?: DiscordChannelMention[] + mention_channels?: DiscordChannelMention[]; /** Any attached files */ - attachments: DiscordAttachment[] + attachments: DiscordAttachment[]; /** Any embedded content */ - embeds: DiscordEmbed[] + embeds: DiscordEmbed[]; /** Reactions to the message */ - reactions?: DiscordReaction[] + reactions?: DiscordReaction[]; /** Used for validating a message was sent */ - nonce?: number | string + nonce?: number | string; /** Whether this message is pinned */ - pinned: boolean + pinned: boolean; /** If the message is generated by a webhook, this is the webhook's id */ - webhook_id?: string + webhook_id?: string; /** Type of message */ - type: MessageTypes + type: MessageTypes; /** Sent with Rich Presence-related chat embeds */ - activity?: DiscordMessageActivity + activity?: DiscordMessageActivity; /** Sent with Rich Presence-related chat embeds */ - application?: Partial + application?: Partial; /** if the message is an Interaction or application-owned webhook, this is the id of the application */ - application_id?: string + application_id?: string; /** Message flags combined as a bitfield */ - flags?: MessageFlags + flags?: MessageFlags; /** Data showing the source of a crosspost, channel follow add, pin, or reply message */ - message_reference?: Omit + message_reference?: Omit; /** The message associated with the `message_reference`. This is a minimal subset of fields in a message (e.g. `author` is excluded.) */ - message_snapshots?: DiscordMessageSnapshot[] + message_snapshots?: DiscordMessageSnapshot[]; /** * The message associated with the 'message_reference' * * @remarks * This field is only returned for messages with a 'type' of '19', '21', or '23'. If the message is one of these but the 'referenced_message' field is not present, the backend did not attempt to fetch the message that was being replied to, so its state is unknown. If the field exists but is null, the referenced message was deleted. */ - referenced_message?: DiscordMessage | null + referenced_message?: DiscordMessage | null; /** sent if the message is sent as a result of an interaction */ - interaction_metadata?: DiscordMessageInteractionMetadata + interaction_metadata?: DiscordMessageInteractionMetadata; /** * Sent if the message is a response to an Interaction * * @deprecated Deprecated in favor of {@link interaction_metadata} */ - interaction?: DiscordMessageInteraction + interaction?: DiscordMessageInteraction; /** The thread that was started from this message, includes thread member object */ - thread?: Omit & { member: DiscordThreadMember } + thread?: Omit & { member: DiscordThreadMember }; /** The components related to this message */ - components?: DiscordMessageComponents + components?: DiscordMessageComponents; /** Sent if the message contains stickers */ - sticker_items?: DiscordStickerItem[] + sticker_items?: DiscordStickerItem[]; /** * The stickers sent with the message (bots currently can only receive messages with stickers, not send) * @deprecated */ - stickers?: DiscordSticker[] + stickers?: DiscordSticker[]; /** A generally increasing integer (there may be gaps or duplicates) that represents the approximate position of the message in a thread, it can be used to estimate the relative position of the message in a thread in company with `total_message_sent` on parent thread */ - position?: number + position?: number; /** data of the role subscription purchase or renewal that prompted this ROLE_SUBSCRIPTION_PURCHASE message */ - role_subscription_data?: DiscordRoleSubscriptionData + role_subscription_data?: DiscordRoleSubscriptionData; /** data for users, members, channels, and roles referenced in this message */ - resolved?: DiscordInteractionDataResolved + resolved?: DiscordInteractionDataResolved; /** The poll object */ - poll?: DiscordPoll + poll?: DiscordPoll; /** The call associated with the message */ - call?: DiscordMessageCall + call?: DiscordMessageCall; } /** https://discord.com/developers/docs/resources/message#message-object-message-types */ @@ -157,9 +157,9 @@ export enum MessageTypes { /** https://discord.com/developers/docs/resources/message#message-object-message-activity-structure */ export interface DiscordMessageActivity { /** Type of message activity */ - type: MessageActivityTypes + type: MessageActivityTypes; /** `party_id` from a Rich Presence event */ - party_id?: string + party_id?: string; } /** https://discord.com/developers/docs/resources/message#message-object-message-activity-types */ @@ -209,81 +209,81 @@ export enum MessageFlags { export type DiscordMessageInteractionMetadata = | DiscordApplicationCommandInteractionMetadata | DiscordMessageComponentInteractionMetadata - | DiscordModalSubmitInteractionMetadata + | DiscordModalSubmitInteractionMetadata; /** https://discord.com/developers/docs/resources/message#message-interaction-metadata-object-application-command-interaction-metadata-structure */ export interface DiscordApplicationCommandInteractionMetadata { /** Id of the interaction */ - id: string + id: string; /** The type of interaction */ - type: InteractionTypes + type: InteractionTypes; /** User who triggered the interaction */ - user: DiscordUser + user: DiscordUser; /** IDs for installation context(s) related to an interaction */ - authorizing_integration_owners: DiscordAuthorizingIntegrationOwners + authorizing_integration_owners: DiscordAuthorizingIntegrationOwners; /** ID of the original response message, present only on follow-up messages */ - original_response_message_id?: string + original_response_message_id?: string; /** The user the command was run on, present only on user command interactions */ - target_user?: DiscordUser + target_user?: DiscordUser; /** The ID of the message the command was run on, present only on message command interactions. The original response message will also have message_reference and referenced_message pointing to this message. */ - target_message_id?: string + target_message_id?: string; } /** https://discord.com/developers/docs/resources/message#message-interaction-metadata-object-message-component-interaction-metadata-structure */ export interface DiscordMessageComponentInteractionMetadata { /** Id of the interaction */ - id: string + id: string; /** The type of interaction */ - type: InteractionTypes + type: InteractionTypes; /** User who triggered the interaction */ - user: DiscordUser + user: DiscordUser; /** IDs for installation context(s) related to an interaction */ - authorizing_integration_owners: DiscordAuthorizingIntegrationOwners + authorizing_integration_owners: DiscordAuthorizingIntegrationOwners; /** ID of the original response message, present only on follow-up messages */ - original_response_message_id?: string + original_response_message_id?: string; /** ID of the message that contained interactive component, present only on messages created from component interactions */ - interacted_message_id: string + interacted_message_id: string; } /** https://discord.com/developers/docs/resources/message#message-interaction-metadata-object-modal-submit-interaction-metadata-structure */ export interface DiscordModalSubmitInteractionMetadata { /** Id of the interaction */ - id: string + id: string; /** The type of interaction */ - type: InteractionTypes + type: InteractionTypes; /** User who triggered the interaction */ - user: DiscordUser + user: DiscordUser; /** IDs for installation context(s) related to an interaction */ - authorizing_integration_owners: DiscordAuthorizingIntegrationOwners + authorizing_integration_owners: DiscordAuthorizingIntegrationOwners; /** ID of the original response message, present only on follow-up messages */ - original_response_message_id?: string + original_response_message_id?: string; /** Metadata for the interaction that was used to open the modal, present only on modal submit interactions */ - triggering_interaction_metadata: DiscordApplicationCommandInteractionMetadata | DiscordMessageComponentInteractionMetadata + triggering_interaction_metadata: DiscordApplicationCommandInteractionMetadata | DiscordMessageComponentInteractionMetadata; } /** https://discord.com/developers/docs/resources/message#message-call-object-message-call-object-structure */ export interface DiscordMessageCall { /** Array of user object ids that participated in the call */ - participants: string[] + participants: string[]; /** Time when call ended */ - ended_timestamp?: string | null + ended_timestamp?: string | null; } /** https://discord.com/developers/docs/resources/message#message-reference-structure */ export interface DiscordMessageReference { /** Type of reference */ - type?: DiscordMessageReferenceType + type?: DiscordMessageReferenceType; /** id of the originating message */ - message_id?: string + message_id?: string; /** * id of the originating message's channel * Note: `channel_id` is optional when creating a reply, but will always be present when receiving an event/response that includes this data model. */ - channel_id?: string + channel_id?: string; /** id of the originating message's guild */ - guild_id?: string + guild_id?: string; /** When sending, whether to error if the referenced message doesn't exist instead of sending as a normal (non-reply) message, default true */ - fail_if_not_exists?: boolean + fail_if_not_exists?: boolean; } /** https://discord.com/developers/docs/resources/message#message-reference-types */ @@ -325,172 +325,172 @@ export interface DiscordMessageSnapshot { | 'stickers' | 'sticker_items' | 'components' - > + >; } /** https://discord.com/developers/docs/resources/message#reaction-object-reaction-structure */ export interface DiscordReaction { /** Total number of times this emoji has been used to react (including super reacts) */ - count: number + count: number; /** Reaction count details object */ - count_details: DiscordReactionCountDetails + count_details: DiscordReactionCountDetails; /** Whether the current user reacted using this emoji */ - me: boolean + me: boolean; /** Whether the current user super-reacted using this emoji */ - me_burst: boolean + me_burst: boolean; /** Emoji information */ - emoji: Partial + emoji: Partial; /** HEX colors used for super reaction */ - burst_colors: string[] + burst_colors: string[]; } /** https://discord.com/developers/docs/resources/message#reaction-count-details-object-reaction-count-details-structure */ export interface DiscordReactionCountDetails { /** Count of super reactions */ - burst: number + burst: number; /** Count of normal reactions */ - normal: number + normal: number; } /** https://discord.com/developers/docs/resources/message#embed-object-embed-structure */ export interface DiscordEmbed { /** Title of embed */ - title?: string + title?: string; /** Type of embed (always "rich" for webhook embeds) */ - type?: EmbedTypes + type?: EmbedTypes; /** Description of embed */ - description?: string + description?: string; /** Url of embed */ - url?: string + url?: string; /** Timestamp of embed content */ - timestamp?: string + timestamp?: string; /** Color code of the embed */ - color?: number + color?: number; /** Footer information */ - footer?: DiscordEmbedFooter + footer?: DiscordEmbedFooter; /** Image information */ - image?: DiscordEmbedImage + image?: DiscordEmbedImage; /** Thumbnail information */ - thumbnail?: DiscordEmbedThumbnail + thumbnail?: DiscordEmbedThumbnail; /** Video information */ - video?: DiscordEmbedVideo + video?: DiscordEmbedVideo; /** Provider information */ - provider?: DiscordEmbedProvider + provider?: DiscordEmbedProvider; /** Author information */ - author?: DiscordEmbedAuthor + author?: DiscordEmbedAuthor; /** Fields information */ - fields?: DiscordEmbedField[] + fields?: DiscordEmbedField[]; } /** https://discord.com/developers/docs/resources/message#embed-object-embed-types */ -export type EmbedTypes = 'rich' | 'image' | 'video' | 'gifv' | 'article' | 'link' | 'poll_result' +export type EmbedTypes = 'rich' | 'image' | 'video' | 'gifv' | 'article' | 'link' | 'poll_result'; /** https://discord.com/developers/docs/resources/message#embed-object-embed-thumbnail-structure */ export interface DiscordEmbedThumbnail { /** Source url of thumbnail (only supports http(s) and attachments) */ - url: string + url: string; /** A proxied url of the thumbnail */ - proxy_url?: string + proxy_url?: string; /** Height of thumbnail */ - height?: number + height?: number; /** Width of thumbnail */ - width?: number + width?: number; } /** https://discord.com/developers/docs/resources/message#embed-object-embed-video-structure */ export interface DiscordEmbedVideo { /** Source url of video */ - url?: string + url?: string; /** A proxied url of the video */ - proxy_url?: string + proxy_url?: string; /** Height of video */ - height?: number + height?: number; /** Width of video */ - width?: number + width?: number; } /** https://discord.com/developers/docs/resources/message#embed-object-embed-image-structure */ export interface DiscordEmbedImage { /** Source url of image (only supports http(s) and attachments) */ - url: string + url: string; /** A proxied url of the image */ - proxy_url?: string + proxy_url?: string; /** Height of image */ - height?: number + height?: number; /** Width of image */ - width?: number + width?: number; } /** https://discord.com/developers/docs/resources/message#embed-object-embed-provider-structure */ export interface DiscordEmbedProvider { /** Name of provider */ - name?: string + name?: string; /** Url of provider */ - url?: string + url?: string; } /** https://discord.com/developers/docs/resources/message#embed-object-embed-author-structure */ export interface DiscordEmbedAuthor { /** Name of author */ - name: string + name: string; /** Url of author */ - url?: string + url?: string; /** Url of author icon (only supports http(s) and attachments) */ - icon_url?: string + icon_url?: string; /** A proxied url of author icon */ - proxy_icon_url?: string + proxy_icon_url?: string; } /** https://discord.com/developers/docs/resources/message#embed-object-embed-footer-structure */ export interface DiscordEmbedFooter { /** Footer text */ - text: string + text: string; /** Url of footer icon (only supports http(s) and attachments) */ - icon_url?: string + icon_url?: string; /** A proxied url of footer icon */ - proxy_icon_url?: string + proxy_icon_url?: string; } /** https://discord.com/developers/docs/resources/message#embed-object-embed-field-structure */ export interface DiscordEmbedField { /** Name of the field */ - name: string + name: string; /** Value of the field */ - value: string + value: string; /** Whether or not this field should display inline */ - inline?: boolean + inline?: boolean; } /** https://discord.com/developers/docs/resources/message#attachment-object-attachment-structure */ export interface DiscordAttachment { /** Attachment id */ - id: string + id: string; /** Name of file attached */ - filename: string + filename: string; /** The title of the file */ - title?: string + title?: string; /** description for the file (max 1024 characters) */ - description?: string + description?: string; /** The attachment's [media type](https://en.wikipedia.org/wiki/Media_type) */ - content_type?: string + content_type?: string; /** Size of file in bytes */ - size: number + size: number; /** Source url of file */ - url: string + url: string; /** A proxied url of file */ - proxy_url: string + proxy_url: string; /** Height of file (if image) */ - height?: number | null + height?: number | null; /** Width of file (if image) */ - width?: number | null + width?: number | null; /** whether this attachment is ephemeral. Ephemeral attachments will automatically be removed after a set period of time. Ephemeral attachments on messages are guaranteed to be available as long as the message itself exists. */ - ephemeral?: boolean + ephemeral?: boolean; /** The duration of the audio file for a voice message */ - duration_secs?: number + duration_secs?: number; /** A base64 encoded bytearray representing a sampled waveform for a voice message */ - waveform?: string + waveform?: string; /** Attachment flags combined as a bitfield */ - flags?: AttachmentFlags + flags?: AttachmentFlags; } /** https://discord.com/developers/docs/resources/message#attachment-object-attachment-flags */ @@ -503,13 +503,13 @@ export enum AttachmentFlags { /** https://discord.com/developers/docs/resources/message#channel-mention-object-channel-mention-structure */ export interface DiscordChannelMention { /** id of the channel */ - id: string + id: string; /** id of the guild containing the channel */ - guild_id: string + guild_id: string; /** The type of channel */ - type: number + type: number; /** The name of the channel */ - name: string + name: string; } /** https://discord.com/developers/docs/resources/message#allowed-mentions-object-allowed-mention-types */ @@ -525,33 +525,33 @@ export enum AllowedMentionsTypes { /** https://discord.com/developers/docs/resources/message#allowed-mentions-object-allowed-mentions-structure */ export interface DiscordAllowedMentions { /** An array of allowed mention types to parse from the content. */ - parse?: AllowedMentionsTypes[] + parse?: AllowedMentionsTypes[]; /** Array of role_ids to mention (Max size of 100) */ - roles?: string[] + roles?: string[]; /** Array of user_ids to mention (Max size of 100) */ - users?: string[] + users?: string[]; /** For replies, whether to mention the author of the message being replied to (default false) */ - replied_user?: boolean + replied_user?: boolean; } /** https://discord.com/developers/docs/resources/message#role-subscription-data-object-role-subscription-data-object-structure */ export interface DiscordRoleSubscriptionData { /** the id of the sku and listing that the user is subscribed to */ - role_subscription_listing_id: string + role_subscription_listing_id: string; /** the name of the tier that the user is subscribed to */ - tier_name: string + tier_name: string; /** the cumulative number of months that the user has been subscribed */ - total_months_subscribed: number + total_months_subscribed: number; /** whether this notification is for a renewal rather than a new purchase */ - is_renewal: boolean + is_renewal: boolean; } /** https://discord.com/developers/docs/resources/message#message-pin-object-message-pin-object-struture */ export interface DiscordMessagePin { /** the time the message was pinned */ - pinned_at: string + pinned_at: string; /** the pinned message */ - message: DiscordMessage + message: DiscordMessage; } /** https://discord.com/developers/docs/resources/message#get-reactions-reaction-types */ @@ -562,6 +562,6 @@ export enum DiscordReactionType { /** https://discord.com/developers/docs/resources/message#get-channel-pins-response-structure */ export interface DiscordGetChannelPins { - items: DiscordMessagePin[] - has_more: boolean + items: DiscordMessagePin[]; + has_more: boolean; } diff --git a/packages/types/src/discord/oauth2.ts b/packages/types/src/discord/oauth2.ts index 1dfa644f2..3e6042207 100644 --- a/packages/types/src/discord/oauth2.ts +++ b/packages/types/src/discord/oauth2.ts @@ -1,9 +1,9 @@ /** Types for: https://discord.com/developers/docs/topics/oauth2 */ -import type { DiscordApplication } from './application.js' -import type { DiscordGuild } from './guild.js' -import type { DiscordUser } from './user.js' -import type { DiscordWebhook } from './webhook.js' +import type { DiscordApplication } from './application.js'; +import type { DiscordGuild } from './guild.js'; +import type { DiscordUser } from './user.js'; +import type { DiscordWebhook } from './webhook.js'; /** https://discord.com/developers/docs/topics/oauth2#shared-resources-oauth2-scopes */ export enum OAuth2Scope { @@ -136,73 +136,73 @@ export enum OAuth2Scope { /** https://discord.com/developers/docs/topics/oauth2#authorization-code-grant-redirect-url-example */ export interface DiscordTokenExchangeAuthorizationCode { - grant_type: 'authorization_code' + grant_type: 'authorization_code'; /** The code for the token exchange */ - code: string + code: string; /** The redirect_uri associated with this authorization */ - redirect_uri: string + redirect_uri: string; /** The code verifier for the token exchange if one was sent during the authorization request */ - code_verifier?: string + code_verifier?: string; } /** https://discord.com/developers/docs/topics/oauth2#authorization-code-grant-access-token-response */ export interface DiscordAccessTokenResponse { /** The access token of the user */ - access_token: string + access_token: string; /** The type of token */ - token_type: string + token_type: string; /** The number of seconds after that the access token is expired */ - expires_in: number + expires_in: number; /** * The refresh token to refresh the access token * * @remarks * When the token exchange is a client credentials type grant this value is not defined. */ - refresh_token: string + refresh_token: string; /** The scopes for the access token */ - scope: string + scope: string; /** The webhook the user created for the application. Requires the `webhook.incoming` scope */ - webhook?: DiscordWebhook + webhook?: DiscordWebhook; /** The guild the bot has been added. Requires the `bot` scope */ - guild?: DiscordGuild + guild?: DiscordGuild; } /** * https://discord.com/developers/docs/topics/oauth2#authorization-code-grant * https://discord.com/developers/docs/topics/oauth2#client-credentials-grant */ -export type DiscordTokenExchange = DiscordTokenExchangeAuthorizationCode | DiscordTokenExchangeRefreshToken | DiscordTokenExchangeClientCredentials +export type DiscordTokenExchange = DiscordTokenExchangeAuthorizationCode | DiscordTokenExchangeRefreshToken | DiscordTokenExchangeClientCredentials; /** https://discord.com/developers/docs/topics/oauth2#authorization-code-grant-refresh-token-exchange-example */ export interface DiscordTokenExchangeRefreshToken { - grant_type: 'refresh_token' + grant_type: 'refresh_token'; /** the user's refresh token */ - refresh_token: string + refresh_token: string; } /** https://discord.com/developers/docs/topics/oauth2#authorization-code-grant-token-revocation-example */ export interface DiscordTokenRevocation { /** The access token to revoke */ - token: string + token: string; /** Optional, the type of token you are using for the revocation */ - token_type_hint?: 'access_token' | 'refresh_token' + token_type_hint?: 'access_token' | 'refresh_token'; } /** https://discord.com/developers/docs/topics/oauth2#client-credentials-grant */ export interface DiscordTokenExchangeClientCredentials { - grant_type: 'client_credentials' + grant_type: 'client_credentials'; /** The scope(s) for the access token */ - scope: OAuth2Scope[] + scope: OAuth2Scope[]; } /** https://discord.com/developers/docs/topics/oauth2#get-current-authorization-information-response-structure */ export interface DiscordCurrentAuthorization { - application: DiscordApplication + application: DiscordApplication; /** the scopes the user has authorized the application for */ - scopes: OAuth2Scope[] + scopes: OAuth2Scope[]; /** when the access token expires */ - expires: string + expires: string; /** the user who has authorized, if the user has authorized with the `identify` scope */ - user?: DiscordUser + user?: DiscordUser; } diff --git a/packages/types/src/discord/permissions.ts b/packages/types/src/discord/permissions.ts index bc6b8c8f0..8f14081ac 100644 --- a/packages/types/src/discord/permissions.ts +++ b/packages/types/src/discord/permissions.ts @@ -104,68 +104,68 @@ export const BitwisePermissionFlags = { PIN_MESSAGES: 1n << 51n, /** Allows bypassing slowmode restrictions */ BYPASS_SLOWMODE: 1n << 52n, -} as const +} as const; /** https://discord.com/developers/docs/topics/permissions#permissions-bitwise-permission-flags */ -export type PermissionStrings = keyof typeof BitwisePermissionFlags +export type PermissionStrings = keyof typeof BitwisePermissionFlags; /** https://discord.com/developers/docs/topics/permissions#role-object-role-structure */ export interface DiscordRole { /** Role id */ - id: string + id: string; /** Role name */ - name: string + name: string; /** * RGB color value, default: 0 * @deprecated the {@link colors} field is recommended for use instead of this field */ - color: number + color: number; /** The role's color */ - colors: DiscordRoleColors + colors: DiscordRoleColors; /** If this role is showed separately in the user listing */ - hoist: boolean + hoist: boolean; /** the role emoji hash */ - icon?: string + icon?: string; /** role unicode emoji */ - unicode_emoji?: string + unicode_emoji?: string; /** Position of this role (roles with the same position are sorted by id) */ - position: number + position: number; /** Permission bit set */ - permissions: string + permissions: string; /** Whether this role is managed by an integration */ - managed: boolean + managed: boolean; /** Whether this role is mentionable */ - mentionable: boolean + mentionable: boolean; /** The tags this role has */ - tags?: DiscordRoleTags + tags?: DiscordRoleTags; /** Role flags combined as a bitfield */ - flags: RoleFlags + flags: RoleFlags; } /** https://discord.com/developers/docs/topics/permissions#role-object-role-tags-structure */ export interface DiscordRoleTags { /** The id of the bot this role belongs to */ - bot_id?: string + bot_id?: string; /** The id of the integration this role belongs to */ - integration_id?: string + integration_id?: string; /** Whether this is the guild's premium subscriber role */ - premium_subscriber?: null + premium_subscriber?: null; /** Id of this role's subscription sku and listing. */ - subscription_listing_id?: string + subscription_listing_id?: string; /** Whether this role is available for purchase. */ - available_for_purchase?: null + available_for_purchase?: null; /** Whether this is a guild's linked role */ - guild_connections?: null + guild_connections?: null; } /** https://discord.com/developers/docs/topics/permissions#role-object-role-colors-object */ export interface DiscordRoleColors { /** The primary color for the role */ - primary_color: number + primary_color: number; /** The secondary color for the role, this will make the role a gradient between the other provided colors */ - secondary_color: number | null + secondary_color: number | null; /** The tertiary color for the role, this will turn the gradient into a holographic style */ - tertiary_color: number | null + tertiary_color: number | null; } /** https://discord.com/developers/docs/topics/permissions#role-object-role-flags */ diff --git a/packages/types/src/discord/poll.ts b/packages/types/src/discord/poll.ts index 67001b3e1..9e294201e 100644 --- a/packages/types/src/discord/poll.ts +++ b/packages/types/src/discord/poll.ts @@ -1,25 +1,25 @@ /** Types for: https://discord.com/developers/docs/resources/poll */ -import type { DiscordEmoji } from './emoji.js' -import type { DiscordUser } from './user.js' +import type { DiscordEmoji } from './emoji.js'; +import type { DiscordUser } from './user.js'; /** https://discord.com/developers/docs/resources/poll#poll-object-poll-object-structure */ export interface DiscordPoll { /** The question of the poll. Only `text` is supported. */ - question: DiscordPollMedia + question: DiscordPollMedia; /** Each of the answers available in the poll. There is a maximum of 10 answers per poll. */ - answers: DiscordPollAnswer[] + answers: DiscordPollAnswer[]; /** * The time when the poll ends. * * @remarks * `expiry` is marked as nullable to support non-expiring polls in the future, but all polls have an expiry currently. */ - expiry: string | null + expiry: string | null; /** Whether a user can select multiple answers */ - allow_multiselect: boolean + allow_multiselect: boolean; /** The layout type of the poll */ - layout_type: DiscordPollLayoutType + layout_type: DiscordPollLayoutType; /** * The results of the poll * @@ -27,7 +27,7 @@ export interface DiscordPoll { * This value will not be sent by discord under specific conditions where they don't fetch them on their backend. When this value is missing it should be interpreted as "Unknown results" and not as "No results" * The results may not be totally accurate while the poll has not ended. When it ends discord will re-calculate all the results and set {@link DiscordPollResult.is_finalized} to true */ - results?: DiscordPollResult + results?: DiscordPollResult; } /** https://discord.com/developers/docs/resources/poll#layout-type */ @@ -45,14 +45,14 @@ export interface DiscordPollMedia { * `text` should always be non-null for both questions and answers, but this is subject to changes. * The maximum length of `text` is 300 for the question, and 55 for any answer. */ - text?: string + text?: string; /** * The emoji of the field * * @remarks * When creating a poll answer with an emoji, one only needs to send either the `id` (custom emoji) or `name` (default emoji) as the only field. */ - emoji?: Partial + emoji?: Partial; } /** https://discord.com/developers/docs/resources/poll#poll-answer-object-poll-answer-object-structure */ @@ -63,31 +63,31 @@ export interface DiscordPollAnswer { * @remarks * This id labels each answer. It starts at 1 and goes up sequentially. Discord recommend against depending on this value as is a implementation detail. */ - answer_id: number + answer_id: number; /** The data of the answer */ - poll_media: DiscordPollMedia + poll_media: DiscordPollMedia; } /** https://discord.com/developers/docs/resources/poll#poll-results-object-poll-results-object-structure */ export interface DiscordPollResult { /** Whether the votes have been precisely counted */ - is_finalized: boolean + is_finalized: boolean; /** The counts for each answer */ - answer_counts: DiscordPollAnswerCount[] + answer_counts: DiscordPollAnswerCount[]; } /** https://discord.com/developers/docs/resources/poll#poll-results-object-poll-results-object-structure */ export interface DiscordPollAnswerCount { /** The {@link DiscordPollAnswer.answer_id | answer_id} */ - id: number + id: number; /** The number of votes for this answer */ - count: number + count: number; /** Whether the current user voted for this answer */ - me_voted: boolean + me_voted: boolean; } /** https://discord.com/developers/docs/resources/poll#get-answer-voters-response-body */ export interface DiscordGetAnswerVotesResponse { /** Users who voted for this answer */ - users: DiscordUser[] + users: DiscordUser[]; } diff --git a/packages/types/src/discord/reference.ts b/packages/types/src/discord/reference.ts index 02feb5154..cbe50f049 100644 --- a/packages/types/src/discord/reference.ts +++ b/packages/types/src/discord/reference.ts @@ -6,10 +6,10 @@ * @remarks * json is only for stickers */ -export type ImageFormat = 'jpg' | 'jpeg' | 'png' | 'webp' | 'gif' | 'avif' | 'json' +export type ImageFormat = 'jpg' | 'jpeg' | 'png' | 'webp' | 'gif' | 'avif' | 'json'; /** https://discord.com/developers/docs/reference#image-formatting */ -export type ImageSize = 16 | 32 | 64 | 128 | 256 | 512 | 1024 | 2048 | 4096 +export type ImageSize = 16 | 32 | 64 | 128 | 256 | 512 | 1024 | 2048 | 4096; /** https://discord.com/developers/docs/reference#locales */ export enum Locales { @@ -47,4 +47,4 @@ export enum Locales { Korean = 'ko', } -export type Localization = Partial> +export type Localization = Partial>; diff --git a/packages/types/src/discord/sku.ts b/packages/types/src/discord/sku.ts index 4fcb5a84b..0e90893db 100644 --- a/packages/types/src/discord/sku.ts +++ b/packages/types/src/discord/sku.ts @@ -3,17 +3,17 @@ /** https://discord.com/developers/docs/resources/sku#sku-object-sku-structure */ export interface DiscordSku { /** ID of SKU */ - id: string + id: string; /** Type of SKU */ - type: DiscordSkuType + type: DiscordSkuType; /** ID of the parent application */ - application_id: string + application_id: string; /** Customer-facing name of your premium offering */ - name: string + name: string; /** System-generated URL slug based on the SKU's name */ - slug: string + slug: string; /** SKU flags combined as a bitfield */ - flags: SkuFlags + flags: SkuFlags; } /** https://discord.com/developers/docs/resources/sku#sku-object-sku-types */ diff --git a/packages/types/src/discord/soundboard.ts b/packages/types/src/discord/soundboard.ts index 76d8e99f1..7029ca776 100644 --- a/packages/types/src/discord/soundboard.ts +++ b/packages/types/src/discord/soundboard.ts @@ -1,23 +1,23 @@ /** Types for: https://discord.com/developers/docs/resources/soundboard */ -import type { DiscordUser } from './user.js' +import type { DiscordUser } from './user.js'; /** https://discord.com/developers/docs/resources/soundboard#soundboard-sound-object-soundboard-sound-structure */ export interface DiscordSoundboardSound { /** The name of this sound */ - name: string + name: string; /** The id of this sound */ - sound_id: string + sound_id: string; /** The volume of this sound, from 0 to 1 */ - volume: number + volume: number; /** The id of this sound's custom emoji */ - emoji_id: string | null + emoji_id: string | null; /** The unicode character of this sound's standard emoji */ - emoji_name: string | null + emoji_name: string | null; /** The id of the guild this sound is in */ - guild_id?: string + guild_id?: string; /** Whether this sound can be used, may be false due to loss of Server Boosts */ - available: boolean + available: boolean; /** The user who created this sound */ - user?: DiscordUser + user?: DiscordUser; } diff --git a/packages/types/src/discord/stageInstance.ts b/packages/types/src/discord/stageInstance.ts index 99d76e02e..a37298569 100644 --- a/packages/types/src/discord/stageInstance.ts +++ b/packages/types/src/discord/stageInstance.ts @@ -3,22 +3,22 @@ /** https://discord.com/developers/docs/resources/stage-instance#stage-instance-object-stage-instance-structure */ export interface DiscordStageInstance { /** The id of this Stage instance */ - id: string + id: string; /** The guild id of the associated Stage channel */ - guild_id: string + guild_id: string; /** The id of the associated Stage channel */ - channel_id: string + channel_id: string; /** The topic of the Stage instance (1-120 characters) */ - topic: string + topic: string; /** The privacy level of the Stage instance */ - privacy_level: DiscordStageInstancePrivacyLevel + privacy_level: DiscordStageInstancePrivacyLevel; /** * Whether or not Stage Discovery is disabled * @deprecated */ - discoverable_disabled: boolean + discoverable_disabled: boolean; /** The id of the scheduled event for this Stage instance */ - guild_scheduled_event_id: string | null + guild_scheduled_event_id: string | null; } /** https://discord.com/developers/docs/resources/stage-instance#stage-instance-object-privacy-level */ diff --git a/packages/types/src/discord/sticker.ts b/packages/types/src/discord/sticker.ts index 3087cf1ad..059993284 100644 --- a/packages/types/src/discord/sticker.ts +++ b/packages/types/src/discord/sticker.ts @@ -1,36 +1,36 @@ /** Types for: https://discord.com/developers/docs/resources/sticker */ -import type { DiscordUser } from './user.js' +import type { DiscordUser } from './user.js'; /** https://discord.com/developers/docs/resources/sticker#sticker-object-sticker-structure */ export interface DiscordSticker { /** [Id of the sticker](https://discord.com/developers/docs/reference#image-formatting) */ - id: string + id: string; /** Id of the pack the sticker is from */ - pack_id?: string + pack_id?: string; /** Name of the sticker */ - name: string + name: string; /** Description of the sticker */ - description: string | null + description: string | null; /** * Autocomplete/suggestion tags for the sticker * @remarks * Max 200 characters * A comma separated list of keywords is the format used in this field by standard stickers, but this is just a convention. Incidentally the client will always use a name generated from an emoji as the value of this field when creating or modifying a guild sticker. */ - tags: string + tags: string; /** [type of sticker](https://discord.com/developers/docs/resources/sticker#sticker-object-sticker-types) */ - type: StickerTypes + type: StickerTypes; /** [Type of sticker format](https://discord.com/developers/docs/resources/sticker#sticker-object-sticker-format-types) */ - format_type: StickerFormatTypes + format_type: StickerFormatTypes; /** Whether or not the sticker is available */ - available?: boolean + available?: boolean; /** Id of the guild that owns this sticker */ - guild_id?: string + guild_id?: string; /** The user that uploaded the sticker */ - user?: DiscordUser + user?: DiscordUser; /** A sticker's sort order within a pack */ - sort_value?: number + sort_value?: number; } /** https://discord.com/developers/docs/resources/sticker#sticker-object-sticker-types */ @@ -52,27 +52,27 @@ export enum StickerFormatTypes { /** https://discord.com/developers/docs/resources/sticker#sticker-item-object-sticker-item-structure */ export interface DiscordStickerItem { /** Id of the sticker */ - id: string + id: string; /** Name of the sticker */ - name: string + name: string; /** [Type of sticker format](https://discord.com/developers/docs/resources/sticker#sticker-object-sticker-format-types) */ - format_type: StickerFormatTypes + format_type: StickerFormatTypes; } /** https://discord.com/developers/docs/resources/sticker#sticker-pack-object-sticker-pack-structure */ export interface DiscordStickerPack { /** id of the sticker pack */ - id: string + id: string; /** the stickers in the pack */ - stickers: DiscordSticker[] + stickers: DiscordSticker[]; /** name of the sticker pack */ - name: string + name: string; /** id of the pack's SKU */ - sku_id: string + sku_id: string; /** id of a sticker in the pack which is shown as the pack's icon */ - cover_sticker_id?: string + cover_sticker_id?: string; /** description of the sticker pack */ - description: string + description: string; /** id of the sticker pack's [banner image](https://discord.com/developers/docs/reference#image-formatting) */ - banner_asset_id?: string + banner_asset_id?: string; } diff --git a/packages/types/src/discord/subscription.ts b/packages/types/src/discord/subscription.ts index 1e4f89e41..4cf41b187 100644 --- a/packages/types/src/discord/subscription.ts +++ b/packages/types/src/discord/subscription.ts @@ -3,25 +3,25 @@ /** https://discord.com/developers/docs/resources/subscription#subscription-object */ export interface DiscordSubscription { /** ID of the subscription */ - id: string + id: string; /** ID of the user who is subscribed */ - user_id: string + user_id: string; /** List of SKUs subscribed to */ - sku_ids: string[] + sku_ids: string[]; /** List of entitlements granted for this subscription */ - entitlement_ids: string[] + entitlement_ids: string[]; /** List of SKUs that this user will be subscribed to at renewal */ - renewal_sku_ids: string[] | null + renewal_sku_ids: string[] | null; /** Start of the current subscription period */ - current_period_start: string + current_period_start: string; /** End of the current subscription period */ - current_period_end: string + current_period_end: string; /** Current status of the subscription */ - status: DiscordSubscriptionStatus + status: DiscordSubscriptionStatus; /** When the subscription was canceled */ - canceled_at: string | null + canceled_at: string | null; /** ISO3166-1 alpha-2 country code of the payment source used to purchase the subscription. Missing unless queried with a private OAuth scope. */ - country?: string + country?: string; } /** https://discord.com/developers/docs/resources/subscription#subscription-statuses */ diff --git a/packages/types/src/discord/teams.ts b/packages/types/src/discord/teams.ts index 54e21e539..1664bfaf1 100644 --- a/packages/types/src/discord/teams.ts +++ b/packages/types/src/discord/teams.ts @@ -1,6 +1,6 @@ /** Types for: https://discord.com/developers/docs/topics/teams */ -import type { DiscordUser } from './user.js' +import type { DiscordUser } from './user.js'; /* https://discord.com/developers/docs/topics/teams#team-member-roles-team-member-role-types */ export enum DiscordTeamMemberRole { @@ -28,27 +28,27 @@ export enum DiscordTeamMemberRole { /** https://discord.com/developers/docs/topics/teams#data-models-team-object */ export interface DiscordTeam { /** Hash of the image of the team's icon */ - icon: string | null + icon: string | null; /** Unique ID of the team */ - id: string + id: string; /** Members of the team */ - members: DiscordTeamMember[] + members: DiscordTeamMember[]; /** Name of the team */ - name: string + name: string; /** User ID of the current team owner */ - owner_user_id: string + owner_user_id: string; } /** https://discord.com/developers/docs/topics/teams#data-models-team-member-object */ export interface DiscordTeamMember { /** The user's membership state on the team */ - membership_state: TeamMembershipStates + membership_state: TeamMembershipStates; /** The id of the parent team of which they are a member */ - team_id: string + team_id: string; /** The avatar, discriminator, id, username, and global_name of the user */ - user: Partial & Pick + user: Partial & Pick; /** Role of the team member */ - role: DiscordTeamMemberRole + role: DiscordTeamMemberRole; } /** https://discord.com/developers/docs/topics/teams#data-models-membership-state-enum */ diff --git a/packages/types/src/discord/user.ts b/packages/types/src/discord/user.ts index 8204cd984..48202b15c 100644 --- a/packages/types/src/discord/user.ts +++ b/packages/types/src/discord/user.ts @@ -1,47 +1,47 @@ /** Types for: https://discord.com/developers/docs/resources/user */ -import type { DiscordIntegration } from './guild.js' +import type { DiscordIntegration } from './guild.js'; /** https://discord.com/developers/docs/resources/user#user-object-user-structure */ export interface DiscordUser { /** The user's id */ - id: string + id: string; /** The user's username, not unique across the platform */ - username: string + username: string; /** The user's discord-tag */ - discriminator: string + discriminator: string; /** The user's display name, if it is set. For bots, this is the application name */ - global_name: string | null + global_name: string | null; /** The user's avatar hash */ - avatar: string | null + avatar: string | null; /** Whether the user belongs to an OAuth2 application */ - bot?: boolean + bot?: boolean; /** Whether the user is an Official Discord System user (part of the urgent message system) */ - system?: boolean + system?: boolean; /** Whether the user has two factor enabled on their account */ - mfa_enabled?: boolean + mfa_enabled?: boolean; /** the user's banner, or null if unset */ - banner?: string | null + banner?: string | null; /** the user's banner color encoded as an integer representation of hexadecimal color code */ - accent_color?: number | null + accent_color?: number | null; /** The user's chosen language option */ - locale?: string + locale?: string; /** Whether the email on this account has been verified */ - verified?: boolean + verified?: boolean; /** The user's email */ - email?: string | null + email?: string | null; /** The flags on a user's account */ - flags?: number + flags?: number; /** The type of Nitro subscription on a user's account */ - premium_type?: PremiumTypes + premium_type?: PremiumTypes; /** The public flags on a user's account */ - public_flags?: number + public_flags?: number; /** data for the user's avatar decoration */ - avatar_decoration_data?: DiscordAvatarDecorationData | null + avatar_decoration_data?: DiscordAvatarDecorationData | null; /** data for the user's collectibles */ - collectibles?: DiscordCollectibles | null + collectibles?: DiscordCollectibles | null; /** The user's primary guild */ - primary_guild?: DiscordUserPrimaryGuild | null + primary_guild?: DiscordUserPrimaryGuild | null; } /** https://discord.com/developers/docs/resources/user#user-object-user-flags */ @@ -74,7 +74,7 @@ export enum PremiumTypes { /** https://discord.com/developers/docs/resources/user#user-object-user-primary-guild */ export interface DiscordUserPrimaryGuild { /** The id of the primary guild */ - identity_guild_id: string | null + identity_guild_id: string | null; /** * Whether the user is displaying the primary guild's server tag. * @@ -82,61 +82,61 @@ export interface DiscordUserPrimaryGuild { * This can be `null` if the system clears the identity, e.g. because the server no longer supports tags. * This will be `false` if the user manually removes their tag. */ - identity_enabled: boolean | null + identity_enabled: boolean | null; /** The text of the user's server tag. Limited to 4 characters */ - tag: string | null + tag: string | null; /** The server tag badge hash */ - badge: string | null + badge: string | null; } /** https://discord.com/developers/docs/resources/user#avatar-decoration-data-object-avatar-decoration-data-structure */ export interface DiscordAvatarDecorationData { /** the avatar decoration hash */ - asset: string + asset: string; /** id of the avatar decoration's SKU */ - sku_id: string + sku_id: string; } /** https://discord.com/developers/docs/resources/user#collectibles-collectible-structure */ export interface DiscordCollectibles { /** object mapping of nameplate data */ - nameplate?: DiscordNameplate + nameplate?: DiscordNameplate; } /** https://discord.com/developers/docs/resources/user#nameplate-nameplate-structure */ export interface DiscordNameplate { /** the nameplate's id */ - sku_id: string + sku_id: string; /** path to the nameplate asset */ - asset: string + asset: string; /** the label of this nameplate. Currently unused */ - label: string + label: string; /** background color of the nameplate, one of: `crimson`, `berry`, `sky`, `teal`, `forest`, `bubble_gum`, `violet`, `cobalt`, `clover`, `lemon`, `white` */ - palette: string + palette: string; } /** https://discord.com/developers/docs/resources/user#connection-object-connection-structure */ export interface DiscordConnection { /** id of the connection account */ - id: string + id: string; /** the username of the connection account */ - name: string + name: string; /** the service of this connection */ - type: DiscordConnectionServiceType + type: DiscordConnectionServiceType; /** whether the connection is revoked */ - revoked?: boolean + revoked?: boolean; /** an array of partial server integrations */ - integrations?: Partial[] + integrations?: Partial[]; /** whether the connection is verified */ - verified: boolean + verified: boolean; /** whether friend sync is enabled for this connection */ - friend_sync: boolean + friend_sync: boolean; /** whether activities related to this connection will be shown in presence updates */ - show_activity: boolean + show_activity: boolean; /** whether this connection has a corresponding third party OAuth2 token */ - two_way_link: boolean + two_way_link: boolean; /** visibility of this connection */ - visibility: DiscordConnectionVisibility + visibility: DiscordConnectionVisibility; } /** https://discord.com/developers/docs/resources/user#connection-object-services */ @@ -180,9 +180,9 @@ export enum DiscordConnectionVisibility { /** https://discord.com/developers/docs/resources/user#application-role-connection-object-application-role-connection-structure */ export interface DiscordApplicationRoleConnection { /** the vanity name of the platform a bot has connected (max 50 characters) */ - platform_name: string | null + platform_name: string | null; /** the username on the platform a bot has connected (max 100 characters) */ - platform_username: string | null + platform_username: string | null; /** object mapping application role connection metadata keys to their stringified value (max 100 characters) for the user on the platform a bot has connected */ - metadata: Record + metadata: Record; } diff --git a/packages/types/src/discord/voice.ts b/packages/types/src/discord/voice.ts index 5d419d40d..921bb6c92 100644 --- a/packages/types/src/discord/voice.ts +++ b/packages/types/src/discord/voice.ts @@ -1,47 +1,47 @@ /** Types for: https://discord.com/developers/docs/resources/voice */ -import type { DiscordMemberWithUser } from './guild.js' +import type { DiscordMemberWithUser } from './guild.js'; /** https://discord.com/developers/docs/resources/voice#voice-state-object-voice-state-structure */ export interface DiscordVoiceState { /** The guild id this voice state is for */ - guild_id?: string + guild_id?: string; /** The channel id this user is connected to */ - channel_id: string | null + channel_id: string | null; /** The user id this voice state is for */ - user_id: string + user_id: string; /** The guild member this voice state is for */ - member?: DiscordMemberWithUser + member?: DiscordMemberWithUser; /** The session id for this voice state */ - session_id: string + session_id: string; /** Whether this user is deafened by the server */ - deaf: boolean + deaf: boolean; /** Whether this user is muted by the server */ - mute: boolean + mute: boolean; /** Whether this user is locally deafened */ - self_deaf: boolean + self_deaf: boolean; /** Whether this user is locally muted */ - self_mute: boolean + self_mute: boolean; /** Whether this user is streaming using "Go Live" */ - self_stream?: boolean + self_stream?: boolean; /** Whether this user's camera is enabled */ - self_video: boolean + self_video: boolean; /** Whether this user is muted by the current user */ - suppress: boolean + suppress: boolean; /** The time at which the user requested to speak */ - request_to_speak_timestamp: string | null + request_to_speak_timestamp: string | null; } /** https://discord.com/developers/docs/resources/voice#voice-region-object-voice-region-structure */ export interface DiscordVoiceRegion { /** Unique Id for the region */ - id: string + id: string; /** Name of the region */ - name: string + name: string; /** true for a single server that is closest to the current user's client */ - optimal: boolean + optimal: boolean; /** Whether this is a deprecated voice region (avoid switching to these) */ - deprecated: boolean + deprecated: boolean; /** Whether this is a custom voice region (used for events/etc) */ - custom: boolean + custom: boolean; } diff --git a/packages/types/src/discord/webhook.ts b/packages/types/src/discord/webhook.ts index 793ae7242..be053aadf 100644 --- a/packages/types/src/discord/webhook.ts +++ b/packages/types/src/discord/webhook.ts @@ -1,35 +1,35 @@ /** Types for: https://discord.com/developers/docs/resources/webhook */ -import type { DiscordChannel } from './channel.js' -import type { DiscordGuild } from './guild.js' -import type { DiscordUser } from './user.js' +import type { DiscordChannel } from './channel.js'; +import type { DiscordGuild } from './guild.js'; +import type { DiscordUser } from './user.js'; /** https://discord.com/developers/docs/resources/webhook#webhook-object-webhook-structure */ export interface DiscordWebhook { /** The id of the webhook */ - id: string + id: string; /** The type of the webhook */ - type: WebhookTypes + type: WebhookTypes; /** The guild id this webhook is for */ - guild_id?: string | null + guild_id?: string | null; /** The channel id this webhook is for */ - channel_id: string | null + channel_id: string | null; /** The user this webhook was created by (not returned when getting a webhook with its token) */ - user?: DiscordUser + user?: DiscordUser; /** The default name of the webhook */ - name: string | null + name: string | null; /** The default user avatar hash of the webhook */ - avatar: string | null + avatar: string | null; /** The secure token of the webhook (returned for Incoming Webhooks) */ - token?: string + token?: string; /** The bot/OAuth2 application that created this webhook */ - application_id: string | null + application_id: string | null; /** The guild of the channel that this webhook is following (returned for Channel Follower Webhooks) */ - source_guild?: Partial + source_guild?: Partial; /** The channel that this webhook is following (returned for Channel Follower Webhooks) */ - source_channel?: Partial + source_channel?: Partial; /** The url used for executing the webhook (returned by the webhooks OAuth2 flow) */ - url?: string + url?: string; } /** https://discord.com/developers/docs/resources/webhook#webhook-object-webhook-types */ diff --git a/packages/types/src/discord/webhookEvents.ts b/packages/types/src/discord/webhookEvents.ts index 718a82037..7a102d0c9 100644 --- a/packages/types/src/discord/webhookEvents.ts +++ b/packages/types/src/discord/webhookEvents.ts @@ -1,23 +1,23 @@ /** Types for: https://discord.com/developers/docs/events/webhook-events */ -import type { DiscordApplicationIntegrationType } from './application.js' -import type { DiscordChannel } from './channel.js' -import type { DiscordEntitlement } from './entitlement.js' -import type { DiscordGuild } from './guild.js' -import type { DiscordMessage, MessageFlags, MessageTypes } from './message.js' -import type { OAuth2Scope } from './oauth2.js' -import type { DiscordUser } from './user.js' +import type { DiscordApplicationIntegrationType } from './application.js'; +import type { DiscordChannel } from './channel.js'; +import type { DiscordEntitlement } from './entitlement.js'; +import type { DiscordGuild } from './guild.js'; +import type { DiscordMessage, MessageFlags, MessageTypes } from './message.js'; +import type { OAuth2Scope } from './oauth2.js'; +import type { DiscordUser } from './user.js'; /** https://discord.com/developers/docs/events/webhook-events#payload-structure */ export interface DiscordEventWebhookEvent { /** Version scheme for the webhook event. Currently always 1 */ - version: 1 + version: 1; /** ID of your app */ - application_id: string + application_id: string; /** Type of webhook, either 0 for PING or 1 for webhook events */ - type: DiscordWebhookEventType + type: DiscordWebhookEventType; /** Event data payload */ - event?: DiscordEventWebhookEventBody + event?: DiscordEventWebhookEventBody; } /** https://discord.com/developers/docs/events/webhook-events#webhook-types */ @@ -31,9 +31,9 @@ export enum DiscordEventWebhookType { /** https://discord.com/developers/docs/events/webhook-events#event-body-object */ export interface DiscordEventWebhookEventBody { /** Event type */ - type: DiscordWebhookEventType + type: DiscordWebhookEventType; /** Timestamp of when the event occurred in ISO8601 format */ - timestamp: string + timestamp: string; /** Data for the event. The shape depends on the event type */ data?: | DiscordEventWebhookApplicationAuthorizedBody @@ -46,7 +46,7 @@ export interface DiscordEventWebhookEventBody { | DiscordEventWebhookLobbyMessageDeleteBody | DiscordEventWebhookGameDirectMessageCreateBody | DiscordEventWebhookGameDirectMessageUpdateBody - | DiscordEventWebhookGameDirectMessageDeleteBody + | DiscordEventWebhookGameDirectMessageDeleteBody; } /** https://discord.com/developers/docs/events/webhook-events#event-types */ @@ -80,114 +80,114 @@ export enum DiscordWebhookEventType { /** https://discord.com/developers/docs/events/webhook-events#application-authorized-application-authorized-structure */ export interface DiscordEventWebhookApplicationAuthorizedBody { /** Installation context for the authorization. Either guild (0) if installed to a server or user (1) if installed to a user's account */ - integration_type?: DiscordApplicationIntegrationType + integration_type?: DiscordApplicationIntegrationType; /** User who authorized the app */ - user: DiscordUser + user: DiscordUser; /** List of scopes the user authorized */ - scopes: OAuth2Scope[] + scopes: OAuth2Scope[]; /** Server which app was authorized for (when integration type is 0) */ - guild?: DiscordGuild + guild?: DiscordGuild; } /** https://discord.com/developers/docs/events/webhook-events#application-authorized-application-authorized-structure */ export interface DiscordEventWebhookApplicationDeauthorizedBody { /** User who deauthorized the app */ - user: DiscordUser + user: DiscordUser; } /** https://discord.com/developers/docs/events/webhook-events#entitlement-create-entitlement-create-structure */ -export type DiscordEventWebhookEntitlementCreateBody = DiscordEntitlement +export type DiscordEventWebhookEntitlementCreateBody = DiscordEntitlement; /** https://discord.com/developers/docs/events/webhook-events#entitlement-update-entitlement-update-structure */ -export type DiscordEventWebhookEntitlementUpdateBody = DiscordEntitlement +export type DiscordEventWebhookEntitlementUpdateBody = DiscordEntitlement; /** https://discord.com/developers/docs/events/webhook-events#entitlement-delete-entitlement-delete-structure */ -export type DiscordEventWebhookEntitlementDeleteBody = DiscordEntitlement +export type DiscordEventWebhookEntitlementDeleteBody = DiscordEntitlement; /** https://discord.com/developers/docs/events/webhook-events#lobby-message-create-lobby-message-create-structure */ -export type DiscordEventWebhookLobbyMessageCreateBody = DiscordSocialSDKLobbyMessage +export type DiscordEventWebhookLobbyMessageCreateBody = DiscordSocialSDKLobbyMessage; // Discord does not explicitly says what "with additional fields for message updates" means, so we rely on the example and the DiscordMessage structure /** https://discord.com/developers/docs/events/webhook-events#lobby-message-update-lobby-message-update-structure */ export interface DiscordEventWebhookLobbyMessageUpdateBody extends DiscordSocialSDKLobbyMessage { /** ISO8601 timestamp of when the message was last edited */ - edited_timestamp: string | null + edited_timestamp: string | null; /** ISO8601 timestamp of when the message was created */ - timestamp: string + timestamp: string; } /** https://discord.com/developers/docs/events/webhook-events#lobby-message-delete-lobby-message-delete-structure */ export interface DiscordEventWebhookLobbyMessageDeleteBody { /** ID of the deleted message */ - id: string + id: string; /** ID of the lobby where the message was deleted */ - lobby_id: string + lobby_id: string; } /** https://discord.com/developers/docs/events/webhook-events#game-direct-message-create-game-direct-message-create-structure */ -export type DiscordEventWebhookGameDirectMessageCreateBody = DiscordSocialSDKMessage | DiscordSocialSDKPassthroughMessage +export type DiscordEventWebhookGameDirectMessageCreateBody = DiscordSocialSDKMessage | DiscordSocialSDKPassthroughMessage; /** https://discord.com/developers/docs/events/webhook-events#game-direct-message-update-game-direct-message-update-structure */ -export type DiscordEventWebhookGameDirectMessageUpdateBody = DiscordSocialSDKMessage | DiscordSocialSDKPassthroughMessage +export type DiscordEventWebhookGameDirectMessageUpdateBody = DiscordSocialSDKMessage | DiscordSocialSDKPassthroughMessage; /** https://discord.com/developers/docs/events/webhook-events#game-direct-message-delete-game-direct-message-delete-structure */ -export type DiscordEventWebhookGameDirectMessageDeleteBody = DiscordSocialSDKMessage | DiscordSocialSDKPassthroughMessage +export type DiscordEventWebhookGameDirectMessageDeleteBody = DiscordSocialSDKMessage | DiscordSocialSDKPassthroughMessage; /** https://discord.com/developers/docs/events/webhook-events#lobby-message-object-lobby-message-structure */ export interface DiscordSocialSDKLobbyMessage { /** ID of the message */ - id: string + id: string; /** Type of message */ - type: MessageTypes + type: MessageTypes; /** Contents of the message */ - content: string + content: string; /** ID of the lobby where the message was sent */ - lobby_id: string + lobby_id: string; /** ID of the channel the message was sent in */ - channel_id: string + channel_id: string; /** Author of the message */ - author: DiscordUser + author: DiscordUser; /** Additional metadata for the message (key-value pairs) */ - metadata?: Record + metadata?: Record; /** * Message flags combined as a bitfield * * @see {@link MessageFlags} */ - flags: number + flags: number; /** ID of the application (only present during active Social SDK sessions) */ - application_id?: string + application_id?: string; } /** https://discord.com/developers/docs/events/webhook-events#message-object */ export interface DiscordSocialSDKMessage extends DiscordMessage { /** ID of the lobby where the message was created (only present in Linked Channel messages) */ - lobby_id?: string + lobby_id?: string; /** Channel object with recipient information */ - channel: DiscordChannel + channel: DiscordChannel; } /** https://discord.com/developers/docs/events/webhook-events#passthrough-message-object-passthrough-message-structure */ export interface DiscordSocialSDKPassthroughMessage { /** ID of the message */ - id: string + id: string; /** Type of message */ - type: MessageTypes + type: MessageTypes; /** Contents of the message */ - content: string + content: string; /** ID of the channel the message was sent in */ - channel_id: string + channel_id: string; /** ID of the message recipient */ - recipient_id: string + recipient_id: string; /** Author of the message */ - author: DiscordUser + author: DiscordUser; /** Message flags combined as a bitfield * * @see {@link MessageFlags} */ - flags: MessageFlags + flags: MessageFlags; /** ID of the application that created the message */ - application_id: string + application_id: string; /** Channel object with recipient information */ - channel: DiscordChannel + channel: DiscordChannel; } diff --git a/packages/types/src/discordeno/application.ts b/packages/types/src/discordeno/application.ts index 4e99e49c4..9fc8b1c23 100644 --- a/packages/types/src/discordeno/application.ts +++ b/packages/types/src/discordeno/application.ts @@ -5,21 +5,21 @@ import type { DiscordApplicationEventWebhookStatus, DiscordApplicationIntegrationType, DiscordInstallParams, -} from '../discord/application.js' -import type { DiscordWebhookEventType } from '../discord/webhookEvents.js' +} from '../discord/application.js'; +import type { DiscordWebhookEventType } from '../discord/webhookEvents.js'; /** https://discord.com/developers/docs/resources/application#edit-current-application-json-params */ export interface EditApplication { /** Default custom authorization URL for the app, if enabled */ - customInstallUrl?: string + customInstallUrl?: string; /** Description of the app */ - description?: string + description?: string; /** Role connection verification URL for the app */ - roleConnectionsVerificationUrl?: string + roleConnectionsVerificationUrl?: string; /** Settings for the app's default in-app authorization link, if enabled */ - installParams?: DiscordInstallParams + installParams?: DiscordInstallParams; /** Default scopes and permissions for each supported installation context. */ - integrationTypesConfig?: DiscordApplicationIntegrationType + integrationTypesConfig?: DiscordApplicationIntegrationType; /** * App's public flags * @@ -28,29 +28,29 @@ export interface EditApplication { * * @see {@link ApplicationFlags} */ - flags?: number + flags?: number; /** Icon for the app */ - icon?: string | null + icon?: string | null; /** Default rich presence invite cover image for the app */ - coverImage?: string | null + coverImage?: string | null; /** * Interactions endpoint URL for the app * * @remarks * To update an Interactions endpoint URL via the API, the URL must be valid */ - interactionEndpointUrl?: string + interactionEndpointUrl?: string; /** * List of tags describing the content and functionality of the app (max of 20 characters per tag) * * @remarks * There can only be a max of 5 tags */ - tags?: string[] + tags?: string[]; /** Event webhook URL for the app to receive webhook events */ - eventWebhooksUrl?: string + eventWebhooksUrl?: string; /** If webhook events are enabled for the app. 1 to disable, and 2 to enable. */ - eventWebhooksStatus?: DiscordApplicationEventWebhookStatus + eventWebhooksStatus?: DiscordApplicationEventWebhookStatus; /** List of Webhook event types the app subscribes to */ - eventWebhooksTypes?: DiscordWebhookEventType[] + eventWebhooksTypes?: DiscordWebhookEventType[]; } diff --git a/packages/types/src/discordeno/auditLog.ts b/packages/types/src/discordeno/auditLog.ts index 8cdb6fc38..f4687a9d0 100644 --- a/packages/types/src/discordeno/auditLog.ts +++ b/packages/types/src/discordeno/auditLog.ts @@ -1,18 +1,18 @@ /** Types for: https://discord.com/developers/docs/resources/audit-log */ -import type { AuditLogEvents } from '../discord/auditLog.js' -import type { BigString } from '../shared.js' +import type { AuditLogEvents } from '../discord/auditLog.js'; +import type { BigString } from '../shared.js'; /** https://discord.com/developers/docs/resources/audit-log#get-guild-audit-log-query-string-params */ export interface GetGuildAuditLog { /** Entries from a specific user ID */ - userId?: BigString + userId?: BigString; /** Entries for a specific audit log event */ - actionType?: AuditLogEvents + actionType?: AuditLogEvents; /** Entries with ID less than a specific audit log entry ID. */ - before?: BigString + before?: BigString; /** Entries with ID greater than a specific audit log entry ID. */ - after?: BigString + after?: BigString; /** Maximum number of entries (between 1-100) to return, defaults to 50 */ - limit?: number + limit?: number; } diff --git a/packages/types/src/discordeno/autoModeration.ts b/packages/types/src/discordeno/autoModeration.ts index a93f03f1b..6c38699f0 100644 --- a/packages/types/src/discordeno/autoModeration.ts +++ b/packages/types/src/discordeno/autoModeration.ts @@ -5,21 +5,21 @@ import type { AutoModerationEventTypes, AutoModerationTriggerTypes, DiscordAutoModerationRuleTriggerMetadata, -} from '../discord/autoModeration.js' -import type { BigString, Camelize } from '../shared.js' +} from '../discord/autoModeration.js'; +import type { BigString, Camelize } from '../shared.js'; // This needs the prefix Discordeno to avoid conflicts with the @discordeno/bot types. /** https://discord.com/developers/docs/resources/auto-moderation#auto-moderation-action-object-auto-moderation-action-structure */ export interface DiscordenoAutoModerationAction { /** The type of action to take when a rule is triggered */ - type: AutoModerationActionType + type: AutoModerationActionType; /** * Additional metadata needed during execution for this specific action type * * @remarks * Can be omitted based on `type`. */ - metadata?: DiscordenoAutoModerationActionMetadata + metadata?: DiscordenoAutoModerationActionMetadata; } // This needs the prefix Discordeno to avoid conflicts with the @discordeno/bot types. @@ -31,7 +31,7 @@ export interface DiscordenoAutoModerationActionMetadata { * @remarks * Only for actions of type {@link AutoModerationActionType.SendAlertMessage}. */ - channelId?: BigString + channelId?: BigString; /** * Timeout duration in seconds. * @@ -40,7 +40,7 @@ export interface DiscordenoAutoModerationActionMetadata { * * Maximum of 2419200 seconds (4 weeks). */ - durationSeconds?: number + durationSeconds?: number; /** * Additional explanation that will be shown to members whenever their message is blocked. * @@ -51,43 +51,43 @@ export interface DiscordenoAutoModerationActionMetadata { * * Maximum of 150 characters. */ - customMessage?: string + customMessage?: string; } /** https://discord.com/developers/docs/resources/auto-moderation#create-auto-moderation-rule-json-params */ export interface CreateAutoModerationRuleOptions { /** The name of the rule. */ - name: string + name: string; /** The type of event to trigger the rule on. */ - eventType: AutoModerationEventTypes + eventType: AutoModerationEventTypes; /** The type of trigger to use for the rule. */ - triggerType: AutoModerationTriggerTypes + triggerType: AutoModerationTriggerTypes; /** The metadata to use for the trigger. */ - triggerMetadata: Camelize + triggerMetadata: Camelize; /** The actions that will trigger for this rule */ - actions: DiscordenoAutoModerationAction[] + actions: DiscordenoAutoModerationAction[]; /** Whether the rule should be enabled, true by default. */ - enabled?: boolean + enabled?: boolean; /** The role ids that should not be effected by the rule */ - exemptRoles?: BigString[] + exemptRoles?: BigString[]; /** The channel ids that should not be effected by the rule. */ - exemptChannels?: BigString[] + exemptChannels?: BigString[]; } /** https://discord.com/developers/docs/resources/auto-moderation#modify-auto-moderation-rule-json-params */ export interface EditAutoModerationRuleOptions { /** The name of the rule. */ - name?: string + name?: string; /** The type of event to trigger the rule on. */ - eventType?: AutoModerationEventTypes + eventType?: AutoModerationEventTypes; /** The metadata to use for the trigger. */ - triggerMetadata?: Camelize + triggerMetadata?: Camelize; /** The actions that will trigger for this rule */ - actions?: DiscordenoAutoModerationAction[] + actions?: DiscordenoAutoModerationAction[]; /** Whether the rule should be enabled. */ - enabled?: boolean + enabled?: boolean; /** The role ids that should not be effected by the rule */ - exemptRoles?: BigString[] + exemptRoles?: BigString[]; /** The channel ids that should not be effected by the rule. */ - exemptChannels?: BigString[] + exemptChannels?: BigString[]; } diff --git a/packages/types/src/discordeno/channel.ts b/packages/types/src/discordeno/channel.ts index fcea4bd1f..6e2e79252 100644 --- a/packages/types/src/discordeno/channel.ts +++ b/packages/types/src/discordeno/channel.ts @@ -1,52 +1,52 @@ /** Types for: https://discord.com/developers/docs/resources/channel */ -import type { ChannelFlags, ChannelTypes, ForumLayout, OverwriteTypes, SortOrderTypes, VideoQualityModes } from '../discord/channel.js' -import type { TargetTypes } from '../discord/invite.js' -import type { DiscordAttachment, DiscordEmbed, MessageFlags } from '../discord/message.js' -import type { PermissionStrings } from '../discord/permissions.js' -import type { BigString, Camelize } from '../shared.js' -import type { MessageComponents } from './components.js' -import type { AllowedMentions } from './message.js' -import type { FileContent } from './reference.js' +import type { ChannelFlags, ChannelTypes, ForumLayout, OverwriteTypes, SortOrderTypes, VideoQualityModes } from '../discord/channel.js'; +import type { TargetTypes } from '../discord/invite.js'; +import type { DiscordAttachment, DiscordEmbed, MessageFlags } from '../discord/message.js'; +import type { PermissionStrings } from '../discord/permissions.js'; +import type { BigString, Camelize } from '../shared.js'; +import type { MessageComponents } from './components.js'; +import type { AllowedMentions } from './message.js'; +import type { FileContent } from './reference.js'; /** https://discord.com/developers/docs/resources/channel#overwrite-object-overwrite-structure */ export interface Overwrite { /** Role or user id */ - id: BigString + id: BigString; /** Either 0 (role) or 1 (member) */ - type: OverwriteTypes + type: OverwriteTypes; // NOTE: // - We allow PermissionStrings[] because in the rest manager we convert these value to the actual string discord wants // - Discord says that these are always present, we keep them as optional (and allow for null) because when it is sent it can be null / not present, https://discord.com/developers/docs/resources/guild#create-guild-channel-json-params, specificly the ** /** Permission bit set */ - allow?: PermissionStrings[] | string | null + allow?: PermissionStrings[] | string | null; /** Permission bit set */ - deny?: PermissionStrings[] | string | null + deny?: PermissionStrings[] | string | null; } // This needs the prefix Discordeno to avoid conflicts with the @discordeno/bot types. /** https://discord.com/developers/docs/resources/channel#default-reaction-object-default-reaction-structure */ export interface DiscordenoDefaultReactionEmoji { /** The id of a guild's custom emoji */ - emoji_id: BigString | null + emoji_id: BigString | null; /** The unicode character of the emoji */ - emoji_name: string | null + emoji_name: string | null; } // This needs the prefix Discordeno to avoid conflicts with the @discordeno/bot types. /** https://discord.com/developers/docs/resources/channel#forum-tag-object-forum-tag-structure */ export interface DiscordenoForumTag { /** The id of the tag */ - id: string + id: string; /** The name of the tag (0-20 characters) */ - name: string + name: string; /** Whether this tag can only be added to or removed from threads by a member with the MANAGE_THREADS permission */ - moderated: boolean + moderated: boolean; /** The id of a guild's custom emoji. At most one of emoji_id and emoji_name may be set. */ - emoji_id: BigString | null + emoji_id: BigString | null; /** The unicode character of the emoji. At most one of emoji_id and emoji_name may be set. */ - emoji_name: string | null + emoji_name: string | null; } // Since this is a merge of 3 types, the properties appear in order of their first appearance in the 3 types @@ -63,14 +63,14 @@ export interface ModifyChannel { * @remarks * This is valid only when editing group dms, any guild channel type, or a thread */ - name?: string + name?: string; /** * Base64 encoded icon * * @remarks * This is valid only when editing group dms */ - icon?: string + icon?: string; // Guild Channel /** @@ -81,14 +81,14 @@ export interface ModifyChannel { * * This is only valid when editing a guild channel of type {@link ChannelTypes.GuildText} or {@link ChannelTypes.GuildAnnouncement}. */ - type?: ChannelTypes + type?: ChannelTypes; /** * The position of the channel in the left-hand listing (channels with the same position are sorted by id) * * @remarks * This is only valid when editing a guild channel of any type */ - position?: number | null + position?: number | null; /** * Channel topic * @@ -97,14 +97,14 @@ export interface ModifyChannel { * * This is only valid when editing a guild channel of type {@link ChannelTypes.GuildText}, {@link ChannelTypes.GuildAnnouncement}, {@link ChannelTypes.GuildForum} or {@link ChannelTypes.GuildMedia}. */ - topic?: string | null + topic?: string | null; /** * Whether the channel is nsfw * * @remarks * This is only valid when editing a guild channel of type {@link ChannelTypes.GuildText}, {@link ChannelTypes.GuildVoice}, {@link ChannelTypes.GuildAnnouncement}, {@link ChannelTypes.GuildStageVoice} {@link ChannelTypes.GuildForum} or {@link ChannelTypes.GuildMedia}. */ - nsfw?: boolean | null + nsfw?: boolean | null; /** * Amount of seconds a user has to wait before sending another message in seconds (0-21600) * @@ -113,7 +113,7 @@ export interface ModifyChannel { * * This is only valid when editing a guild channel of type {@link ChannelTypes.GuildText}, {@link ChannelTypes.GuildVoice}, {@link ChannelTypes.GuildStageVoice} {@link ChannelTypes.GuildForum} or {@link ChannelTypes.GuildMedia}, or a thread. */ - rateLimitPerUser?: number | null + rateLimitPerUser?: number | null; /** * The bitrate (in bits) of the voice or stage channel * @@ -130,7 +130,7 @@ export interface ModifyChannel { * * This is only valid when editing a guild channel of type {@link ChannelTypes.GuildVoice}, {@link ChannelTypes.GuildStageVoice}. */ - bitrate?: number | null + bitrate?: number | null; /** * The user limit of the voice or stage channel (0 refers to no limit) * @@ -140,42 +140,42 @@ export interface ModifyChannel { * * This is only valid when editing a guild channel of type {@link ChannelTypes.GuildVoice}, {@link ChannelTypes.GuildStageVoice}. */ - userLimit?: number | null + userLimit?: number | null; /** * Channel or category-specific permissions * * @remarks * This is valid when editing a guild channel of any type */ - permissionOverwrites?: Overwrite[] | null + permissionOverwrites?: Overwrite[] | null; /** * Id of the new parent category for a channel * * @remarks * This is only valid when editing a guild channel of type {@link ChannelTypes.GuildText}, {@link ChannelTypes.GuildVoice}, {@link ChannelTypes.GuildAnnouncement}, {@link ChannelTypes.GuildStageVoice} {@link ChannelTypes.GuildForum} or {@link ChannelTypes.GuildMedia}. */ - parentId?: BigString | null + parentId?: BigString | null; /** * Voice region id for the voice channel, automatic when set to null * * @remarks * This is only valid when editing a guild channel of type {@link ChannelTypes.GuildVoice}, {@link ChannelTypes.GuildStageVoice}. */ - rtcRegion?: string | null + rtcRegion?: string | null; /** * The camera video quality mode of the voice channel * * @remarks * This is only valid when editing a guild channel of type {@link ChannelTypes.GuildVoice}, {@link ChannelTypes.GuildStageVoice}. */ - videoQualityMode?: VideoQualityModes | null + videoQualityMode?: VideoQualityModes | null; /** * The default duration that the clients use (not the API) for newly created threads in the channel, in minutes, to automatically archive the thread after recent activity * * @remarks * This is only valid when editing a guild channel of type {@link ChannelTypes.GuildText}, {@link ChannelTypes.GuildAnnouncement}, {@link ChannelTypes.GuildForum} or {@link ChannelTypes.GuildMedia}. */ - defaultAutoArchiveDuration?: 60 | 1440 | 4320 | 10080 | null + defaultAutoArchiveDuration?: 60 | 1440 | 4320 | 10080 | null; /** * Channel flags combined as a bitfield. * @@ -188,7 +188,7 @@ export interface ModifyChannel { * * @see {@link ChannelFlags} */ - flags?: number + flags?: number; /** * The set of tags that can be used in a {@link ChannelTypes.GuildForum} or a {@link ChannelTypes.GuildMedia} channel * @@ -197,14 +197,14 @@ export interface ModifyChannel { * * This is only valid when editing a guild channel of type {@link ChannelTypes.GuildForum} or {@link ChannelTypes.GuildMedia}. */ - availableTags?: DiscordenoForumTag[] + availableTags?: DiscordenoForumTag[]; /** * The emoji to show in the add reaction button on a thread in a {@link ChannelTypes.GuildForum} or a {@link ChannelTypes.GuildMedia} channel * * @remarks * This is only valid when editing a guild channel of type {@link ChannelTypes.GuildForum} or {@link ChannelTypes.GuildMedia}. */ - defaultReactionEmoji?: DiscordenoDefaultReactionEmoji | null + defaultReactionEmoji?: DiscordenoDefaultReactionEmoji | null; /** * The initial `rate_limit_per_user` to set on newly created threads in a channel. * @@ -213,21 +213,21 @@ export interface ModifyChannel { * * This is only valid when editing a guild channel of type {@link ChannelTypes.GuildText}, {@link ChannelTypes.GuildForum} or {@link ChannelTypes.GuildMedia}. */ - defaultThreadRateLimitPerUser?: number + defaultThreadRateLimitPerUser?: number; /** * The default sort order type used to order posts in {@link ChannelTypes.GuildForum} and {@link ChannelTypes.GuildMedia} channels * * @remarks * This is only valid when editing a guild channel of type {@link ChannelTypes.GuildForum} or {@link ChannelTypes.GuildMedia}. */ - defaultSortOrder?: SortOrderTypes | null + defaultSortOrder?: SortOrderTypes | null; /** * The default forum layout type used to display posts in {@link ChannelTypes.GuildForum} channels * * @remarks * This is only valid when editing a guild channel of type {@link ChannelTypes.GuildForum}. */ - defaultForumLayout?: ForumLayout + defaultForumLayout?: ForumLayout; // Thread /** @@ -236,21 +236,21 @@ export interface ModifyChannel { * @remarks * This is only valid when editing a thread */ - archived?: boolean + archived?: boolean; /** * The thread will stop showing in the channel list after `auto_archive_duration` minutes of inactivity * * @remarks * This is only valid when editing a thread */ - autoArchiveDuration?: 60 | 1440 | 4320 | 10080 + autoArchiveDuration?: 60 | 1440 | 4320 | 10080; /** * Whether the thread is locked. When a thread is locked, only users with `MANAGE_THREADS` can unarchive it * * @remarks * This is only valid when editing a thread */ - locked?: boolean + locked?: boolean; /** * Whether non-moderators can add other non-moderators to a thread * @@ -259,7 +259,7 @@ export interface ModifyChannel { * * This is only valid when editing a thread */ - invitable?: boolean + invitable?: boolean; /** * The IDs of the set of tags that have been applied to a thread in a {@link ChannelTypes.GuildForum} or a {@link ChannelTypes.GuildMedia} channel * @@ -268,127 +268,127 @@ export interface ModifyChannel { * * This is only valid when editing a thread */ - appliedTags?: BigString[] + appliedTags?: BigString[]; } /** https://discord.com/developers/docs/resources/channel#edit-channel-permissions-json-params */ export interface EditChannelPermissionOverridesOptions { // This is included in here however it is a route parameter /** Role or user id */ - id: BigString + id: BigString; /** Either 0 (role) or 1 (member) */ - type: OverwriteTypes + type: OverwriteTypes; // We allow PermissionStrings[] because in the rest manager we convert these value to the actual string discord wants /** The bitwise value of all allowed permissions */ - allow?: PermissionStrings[] | string | null + allow?: PermissionStrings[] | string | null; /** The bitwise value of all disallowed permissions */ - deny?: PermissionStrings[] | string | null + deny?: PermissionStrings[] | string | null; } /** https://discord.com/developers/docs/resources/channel#create-channel-invite-json-params */ export interface CreateChannelInvite { /** Duration of invite in seconds before expiry, or 0 for never. Between 0 and 604800 (7 days). Default: 86400 (24 hours) */ - maxAge?: number + maxAge?: number; /** Max number of users or 0 for unlimited. Between 0 and 100. Default: 0 */ - maxUses?: number + maxUses?: number; /** Whether this invite only grants temporary membership. Default: false */ - temporary?: boolean + temporary?: boolean; /** If true, don't try to reuse similar invite (useful for creating many unique one time use invites). Default: false */ - unique?: boolean + unique?: boolean; /** The type of target for this voice channel invite */ - targetType?: TargetTypes + targetType?: TargetTypes; /** The id of the user whose stream to display for this invite, required if `target_type` is 1, the user must be streaming in the channel */ - targetUserId?: BigString + targetUserId?: BigString; /** The id of the embedded application to open for this invite, required if `target_type` is 2, the application must have the `EMBEDDED` flag */ - targetApplicationId?: BigString + targetApplicationId?: BigString; } /** https://discord.com/developers/docs/resources/channel#group-dm-add-recipient-json-params */ export interface AddDmRecipientOptions { /** access token of a user that has granted your app the `gdm.join` scope */ - accessToken: string + accessToken: string; /** nickname of the user being added */ - nick: string + nick: string; } /** https://discord.com/developers/docs/resources/channel#start-thread-from-message-json-params */ export interface StartThreadWithMessage { /** 1-100 character thread name */ - name: string + name: string; /** Duration in minutes to automatically archive the thread after recent activity */ - autoArchiveDuration?: 60 | 1440 | 4320 | 10080 + autoArchiveDuration?: 60 | 1440 | 4320 | 10080; /** Amount of seconds a user has to wait before sending another message (0-21600) */ - rateLimitPerUser?: number | null + rateLimitPerUser?: number | null; } /** https://discord.com/developers/docs/resources/channel#start-thread-without-message-json-params */ export interface StartThreadWithoutMessage { /** 1-100 character thread name */ - name: string + name: string; /** Duration in minutes to automatically archive the thread after recent activity */ - autoArchiveDuration?: 60 | 1440 | 4320 | 10080 + autoArchiveDuration?: 60 | 1440 | 4320 | 10080; /** The type of thread to create. Defaults to PrivateThread */ - type?: ChannelTypes.AnnouncementThread | ChannelTypes.PublicThread | ChannelTypes.PrivateThread + type?: ChannelTypes.AnnouncementThread | ChannelTypes.PublicThread | ChannelTypes.PrivateThread; /** Whether non-moderators can add other non-moderators to a thread; only available when creating a private thread */ - invitable?: boolean + invitable?: boolean; /** Amount of seconds a user has to wait before sending another message (0-21600) */ - rateLimitPerUser?: number | null + rateLimitPerUser?: number | null; } /** https://discord.com/developers/docs/resources/channel#start-thread-in-forum-or-media-channel-jsonform-params*/ export interface CreateForumPostWithMessage { /** 1-100 character thread name */ - name: string + name: string; /** Duration in minutes to automatically archive the thread after recent activity */ - autoArchiveDuration?: 60 | 1440 | 4320 | 10080 + autoArchiveDuration?: 60 | 1440 | 4320 | 10080; /** Amount of seconds a user has to wait before sending another message (0-21600) */ - rateLimitPerUser?: number | null + rateLimitPerUser?: number | null; /** contents of the first message in the forum/media thread */ - message: ForumAndMediaThreadMessage + message: ForumAndMediaThreadMessage; /** The IDs of the set of tags that have been applied to a thread in a GUILD_FORUM or a GUILD_MEDIA channel */ - appliedTags?: BigString[] + appliedTags?: BigString[]; /** The contents of the files being sent */ - files?: FileContent[] + files?: FileContent[]; } /** https://discord.com/developers/docs/resources/channel#start-thread-in-forum-or-media-channel-forum-and-media-thread-message-params-object */ export interface ForumAndMediaThreadMessage { /** The message contents (up to 2000 characters) */ - content?: string + content?: string; /** Embedded `rich` content (up to 6000 characters) */ - embeds?: Camelize[] + embeds?: Camelize[]; /** Allowed mentions for the message */ - allowedMentions?: AllowedMentions + allowedMentions?: AllowedMentions; /** The components you would like to have sent in this message */ - components?: MessageComponents + components?: MessageComponents; /** IDs of up to 3 stickers in the server to send in the message */ - stickerIds?: BigString[] + stickerIds?: BigString[]; /** Attachment objects with `filename` and `description` */ - attachments?: Pick[] + attachments?: Pick[]; /** * Message flags combined as a bitfield, only SUPPRESS_EMBEDS, SUPPRESS_NOTIFICATIONS and IS_COMPONENTS_V2 can be set * * @see {@link MessageFlags} */ - flags?: number + flags?: number; } /** https://discord.com/developers/docs/resources/channel#get-thread-member-query-string-params */ export interface GetThreadMember { /** Whether to include a guild member object for the thread member */ - withMember?: boolean + withMember?: boolean; } /** https://discord.com/developers/docs/resources/channel#list-thread-members-query-string-params */ export interface ListThreadMembers { /** Whether to include a guild member object for the thread member */ - withMember?: boolean + withMember?: boolean; /** Get thread members after this user ID */ - after?: BigString + after?: BigString; /** Max number of thread members to return (1-100). Defaults to 100. */ - limit?: BigString + limit?: BigString; } /** @@ -398,7 +398,7 @@ export interface ListThreadMembers { */ export interface ListArchivedThreads { /** Returns threads before this timestamp */ - before?: number + before?: number; /** Optional maximum number of threads to return */ - limit?: number + limit?: number; } diff --git a/packages/types/src/discordeno/components.ts b/packages/types/src/discordeno/components.ts index db9853d02..5152e0070 100644 --- a/packages/types/src/discordeno/components.ts +++ b/packages/types/src/discordeno/components.ts @@ -1,6 +1,6 @@ /** Types for: https://discord.com/developers/docs/components/reference */ -import type { ChannelTypes } from '../discord/channel.js' +import type { ChannelTypes } from '../discord/channel.js'; import type { ButtonStyles, DiscordMediaGalleryItem, @@ -8,10 +8,10 @@ import type { MessageComponentTypes, SeparatorSpacingSize, TextStyles, -} from '../discord/components.js' -import type { BigString } from '../shared.js' +} from '../discord/components.js'; +import type { BigString } from '../shared.js'; -export type MessageComponents = MessageComponent[] +export type MessageComponents = MessageComponent[]; export type MessageComponent = | ActionRow | ButtonComponent @@ -29,19 +29,19 @@ export type MessageComponent = | ContainerComponent | FileComponent | LabelComponent - | FileUploadComponent + | FileUploadComponent; /** https://discord.com/developers/docs/components/reference#anatomy-of-a-component */ export interface BaseComponent { /** The type of the component */ - type: MessageComponentTypes + type: MessageComponentTypes; /** 32 bit integer used as an optional identifier for component */ - id?: number + id?: number; } /** https://discord.com/developers/docs/components/reference#action-row-action-row-structure */ export interface ActionRow extends BaseComponent { - type: MessageComponentTypes.ActionRow + type: MessageComponentTypes.ActionRow; /** * The components in this row @@ -60,30 +60,30 @@ export interface ActionRow extends BaseComponent { | MentionableSelectComponent | ChannelSelectComponent | TextInputComponent - )[] + )[]; } /** https://discord.com/developers/docs/components/reference#button-button-structure */ export interface ButtonComponent extends BaseComponent { - type: MessageComponentTypes.Button + type: MessageComponentTypes.Button; /** For different styles/colors of the buttons */ - style: ButtonStyles + style: ButtonStyles; /** for what the button says (max 80 characters) */ - label?: string + label?: string; /** Emoji object that includes fields of name, id, and animated supporting unicode and custom emojis. */ emoji?: { /** Emoji id */ - id?: BigString + id?: BigString; /** Emoji name */ - name?: string + name?: string; /** Whether this emoji is animated */ - animated?: boolean - } + animated?: boolean; + }; /** a dev-defined unique string sent on click (max 100 characters). type 5 Link buttons can not have a custom_id */ - customId?: string + customId?: string; /** Identifier for a purchasable SKU, only available when using premium-style buttons */ - skuId?: BigString + skuId?: BigString; /** * optional url for link-style buttons that can navigate a user to the web. * @@ -92,25 +92,25 @@ export interface ButtonComponent extends BaseComponent { * * Maximum 512 characters. */ - url?: string + url?: string; /** Whether or not this button is disabled */ - disabled?: boolean + disabled?: boolean; } /** https://discord.com/developers/docs/components/reference#string-select-string-select-structure */ export interface StringSelectComponent extends BaseComponent { - type: MessageComponentTypes.StringSelect + type: MessageComponentTypes.StringSelect; /** A custom identifier for this component. Maximum 100 characters. */ - customId: string + customId: string; /** The choices! Maximum of 25 items. */ - options: SelectOption[] + options: SelectOption[]; /** A custom placeholder text if nothing is selected. Maximum 150 characters. */ - placeholder?: string + placeholder?: string; /** The minimum number of items that must be selected. Default 1. Between 0-25. */ - minValues?: number + minValues?: number; /** The maximum number of items that can be selected. Default 1. Max 25. */ - maxValues?: number + maxValues?: number; /** * Whether this component is required to be filled * @@ -119,7 +119,7 @@ export interface StringSelectComponent extends BaseComponent { * * @default true */ - required?: boolean + required?: boolean; /** * Whether select menu is disabled * @@ -128,39 +128,39 @@ export interface StringSelectComponent extends BaseComponent { * * @default false */ - disabled?: boolean + disabled?: boolean; } /** https://discord.com/developers/docs/components/reference#string-select-select-option-structure */ export interface SelectOption { /** The user-facing name of the option. Maximum 25 characters. */ - label: string + label: string; /** The dev-defined value of the option. Maximum 100 characters. */ - value: string + value: string; /** An additional description of the option. Maximum 50 characters. */ - description?: string + description?: string; // TODO: Make an alias for this type since it is used a few times /** The id, name, and animated properties of an emoji. */ emoji?: { /** Emoji id */ - id?: BigString + id?: BigString; /** Emoji name */ - name?: string + name?: string; /** Whether this emoji is animated */ - animated?: boolean - } + animated?: boolean; + }; /** Will render this option as already-selected by default. */ - default?: boolean + default?: boolean; } /** https://discord.com/developers/docs/components/reference#text-input-text-input-structure */ export interface TextInputComponent extends BaseComponent { - type: MessageComponentTypes.TextInput + type: MessageComponentTypes.TextInput; /** The customId of the InputText */ - customId: string + customId: string; /** The style of the InputText */ - style: TextStyles + style: TextStyles; /** * The label of the InputText. * @@ -169,36 +169,36 @@ export interface TextInputComponent extends BaseComponent { * * @deprecated Use the `label` and `description` from the {@link LabelComponent} */ - label?: string + label?: string; /** The minimum length of the text the user has to provide */ - minLength?: number + minLength?: number; /** The maximum length of the text the user has to provide */ - maxLength?: number + maxLength?: number; /** Whether or not this input is required. */ - required?: boolean + required?: boolean; /** Pre-filled value for input text. */ - value?: string + value?: string; /** The placeholder of the InputText */ - placeholder?: string + placeholder?: string; } /** https://discord.com/developers/docs/components/reference#user-select-user-select-structure */ export interface UserSelectComponent extends BaseComponent { - type: MessageComponentTypes.UserSelect + type: MessageComponentTypes.UserSelect; /** A custom identifier for this component. Maximum 100 characters. */ - customId: string + customId: string; /** A custom placeholder text if nothing is selected. Maximum 150 characters. */ - placeholder?: string + placeholder?: string; /** * List of default values for auto-populated select menu components * The number of default values must be in the range defined by minValues and maxValues */ - defaultValues?: SelectMenuDefaultValue[] + defaultValues?: SelectMenuDefaultValue[]; /** The minimum number of items that must be selected. Default 1. Between 0-25. */ - minValues?: number + minValues?: number; /** The maximum number of items that can be selected. Default 1. Max 25. */ - maxValues?: number + maxValues?: number; /** * Whether this component is required to be filled * @@ -207,7 +207,7 @@ export interface UserSelectComponent extends BaseComponent { * * @default true */ - required?: boolean + required?: boolean; /** * Whether select menu is disabled * @@ -216,34 +216,34 @@ export interface UserSelectComponent extends BaseComponent { * * @default false */ - disabled?: boolean + disabled?: boolean; } /** https://discord.com/developers/docs/components/reference#user-select-select-default-value-structure */ export interface SelectMenuDefaultValue { /** ID of a user, role, or channel */ - id: BigString + id: BigString; /** Type of value that id represents. */ - type: 'user' | 'role' | 'channel' + type: 'user' | 'role' | 'channel'; } /** https://discord.com/developers/docs/components/reference#role-select-role-select-structure */ export interface RoleSelectComponent extends BaseComponent { - type: MessageComponentTypes.RoleSelect + type: MessageComponentTypes.RoleSelect; /** A custom identifier for this component. Maximum 100 characters. */ - customId: string + customId: string; /** A custom placeholder text if nothing is selected. Maximum 150 characters. */ - placeholder?: string + placeholder?: string; /** * List of default values for auto-populated select menu components * The number of default values must be in the range defined by minValues and maxValues */ - defaultValues?: SelectMenuDefaultValue[] + defaultValues?: SelectMenuDefaultValue[]; /** The minimum number of items that must be selected. Default 1. Between 0-25. */ - minValues?: number + minValues?: number; /** The maximum number of items that can be selected. Default 1. Max 25. */ - maxValues?: number + maxValues?: number; /** * Whether this component is required to be filled * @@ -252,7 +252,7 @@ export interface RoleSelectComponent extends BaseComponent { * * @default true */ - required?: boolean + required?: boolean; /** * Whether select menu is disabled * @@ -261,26 +261,26 @@ export interface RoleSelectComponent extends BaseComponent { * * @default false */ - disabled?: boolean + disabled?: boolean; } /** https://discord.com/developers/docs/components/reference#mentionable-select-mentionable-select-structure */ export interface MentionableSelectComponent extends BaseComponent { - type: MessageComponentTypes.MentionableSelect + type: MessageComponentTypes.MentionableSelect; /** A custom identifier for this component. Maximum 100 characters. */ - customId: string + customId: string; /** A custom placeholder text if nothing is selected. Maximum 150 characters. */ - placeholder?: string + placeholder?: string; /** * List of default values for auto-populated select menu components * The number of default values must be in the range defined by minValues and maxValues */ - defaultValues?: SelectMenuDefaultValue[] + defaultValues?: SelectMenuDefaultValue[]; /** The minimum number of items that must be selected. Default 1. Between 0-25. */ - minValues?: number + minValues?: number; /** The maximum number of items that can be selected. Default 1. Max 25. */ - maxValues?: number + maxValues?: number; /** * Whether this component is required to be filled * @@ -289,7 +289,7 @@ export interface MentionableSelectComponent extends BaseComponent { * * @default true */ - required?: boolean + required?: boolean; /** * Whether select menu is disabled * @@ -298,28 +298,28 @@ export interface MentionableSelectComponent extends BaseComponent { * * @default false */ - disabled?: boolean + disabled?: boolean; } /** https://discord.com/developers/docs/components/reference#channel-select-channel-select-structure */ export interface ChannelSelectComponent extends BaseComponent { - type: MessageComponentTypes.ChannelSelect + type: MessageComponentTypes.ChannelSelect; /** A custom identifier for this component. Maximum 100 characters. */ - customId: string + customId: string; /** List of channel types to include in the options list */ - channelTypes?: ChannelTypes[] + channelTypes?: ChannelTypes[]; /** A custom placeholder text if nothing is selected. Maximum 150 characters. */ - placeholder?: string + placeholder?: string; /** * List of default values for auto-populated select menu components * The number of default values must be in the range defined by minValues and maxValues */ - defaultValues?: SelectMenuDefaultValue[] + defaultValues?: SelectMenuDefaultValue[]; /** The minimum number of items that must be selected. Default 1. Between 0-25. */ - minValues?: number + minValues?: number; /** The maximum number of items that can be selected. Default 1. Max 25. */ - maxValues?: number + maxValues?: number; /** * Whether this component is required to be filled * @@ -328,7 +328,7 @@ export interface ChannelSelectComponent extends BaseComponent { * * @default true */ - required?: boolean + required?: boolean; /** * Whether select menu is disabled * @@ -337,86 +337,86 @@ export interface ChannelSelectComponent extends BaseComponent { * * @default false */ - disabled?: boolean + disabled?: boolean; } /** https://discord.com/developers/docs/components/reference#section-section-structure */ export interface SectionComponent extends BaseComponent { - type: MessageComponentTypes.Section + type: MessageComponentTypes.Section; /** One to three text components */ - components: TextDisplayComponent[] + components: TextDisplayComponent[]; /** A thumbnail or a button component, with a future possibility of adding more compatible components */ - accessory: ButtonComponent | ThumbnailComponent + accessory: ButtonComponent | ThumbnailComponent; } /** https://discord.com/developers/docs/components/reference#text-display */ export interface TextDisplayComponent extends BaseComponent { - type: MessageComponentTypes.TextDisplay + type: MessageComponentTypes.TextDisplay; /** Text that will be displayed similar to a message */ - content: string + content: string; } /** https://discord.com/developers/docs/components/reference#thumbnail */ export interface ThumbnailComponent extends BaseComponent { - type: MessageComponentTypes.Thumbnail + type: MessageComponentTypes.Thumbnail; /** A url or attachment */ - media: DiscordUnfurledMediaItem + media: DiscordUnfurledMediaItem; /** Alt text for the media */ - description?: string + description?: string; /** Whether the thumbnail should be a spoiler (or blurred out). Defaults to `false` */ - spoiler?: boolean + spoiler?: boolean; } /** https://discord.com/developers/docs/components/reference#media-gallery */ export interface MediaGalleryComponent extends BaseComponent { - type: MessageComponentTypes.MediaGallery + type: MessageComponentTypes.MediaGallery; /** 1 to 10 media gallery items */ - items: DiscordMediaGalleryItem[] + items: DiscordMediaGalleryItem[]; } /** https://discord.com/developers/docs/components/reference#file */ export interface FileComponent extends BaseComponent { - type: MessageComponentTypes.File + type: MessageComponentTypes.File; /** This unfurled media item is unique in that it only supports attachment references using the attachment:// syntax */ - file: DiscordUnfurledMediaItem + file: DiscordUnfurledMediaItem; /** Whether the media should be a spoiler (or blurred out). Defaults to `false` */ - spoiler?: boolean + spoiler?: boolean; /** The name of the file. This field is ignored and provided by the API as part of the response */ - name: string + name: string; /** The size of the file in bytes. This field is ignored and provided by the API as part of the response */ - size: number + size: number; } /** https://discord.com/developers/docs/components/reference#separator */ export interface SeparatorComponent extends BaseComponent { - type: MessageComponentTypes.Separator + type: MessageComponentTypes.Separator; /** Whether a visual divider should be displayed in the component. Defaults to `true` */ - divider?: boolean + divider?: boolean; /** Size of separator padding — `1` for small padding, `2` for large padding. Defaults to `1` */ - spacing?: SeparatorSpacingSize + spacing?: SeparatorSpacingSize; } /** https://discord.com/developers/docs/components/reference#container */ export interface ContainerComponent extends BaseComponent { - type: MessageComponentTypes.Container + type: MessageComponentTypes.Container; /** Components of the type action row, text display, section, media gallery, separator, or file */ - components: Array + components: Array; /** Color for the accent on the container as RGB from 0x000000 to 0xFFFFFF */ - accentColor?: number | null + accentColor?: number | null; /** Whether the container should be a spoiler (or blurred out). Defaults to `false` */ - spoiler?: boolean + spoiler?: boolean; } /** https://discord.com/developers/docs/components/reference#label-label-structure */ export interface LabelComponent extends BaseComponent { - type: MessageComponentTypes.Label + type: MessageComponentTypes.Label; /** * The label text @@ -424,14 +424,14 @@ export interface LabelComponent extends BaseComponent { * @remarks * Max 45 characters. */ - label: string + label: string; /** * An optional description text for the label * * @remarks * Max 100 characters. */ - description?: string + description?: string; /** The component within the label */ component: | TextInputComponent @@ -440,32 +440,32 @@ export interface LabelComponent extends BaseComponent { | RoleSelectComponent | MentionableSelectComponent | ChannelSelectComponent - | FileUploadComponent + | FileUploadComponent; } /** https://discord.com/developers/docs/components/reference#file-upload-file-upload-structure */ export interface FileUploadComponent extends BaseComponent { - type: MessageComponentTypes.FileUpload + type: MessageComponentTypes.FileUpload; /** The custom id for the file upload */ - customId: string + customId: string; /** * The minimum number of files that must be uploaded * * @remarks * Between 0-10 */ - minValues?: number + minValues?: number; /** The maximum number of files that can be uploaded * * @remarks * Between 1-10 */ - maxValues?: number + maxValues?: number; /** * Whether this component is required to be filled * * @default true */ - required?: boolean + required?: boolean; } diff --git a/packages/types/src/discordeno/emoji.ts b/packages/types/src/discordeno/emoji.ts index a2ec0c355..5b6d7c247 100644 --- a/packages/types/src/discordeno/emoji.ts +++ b/packages/types/src/discordeno/emoji.ts @@ -1,35 +1,35 @@ /** Types for: https://discord.com/developers/docs/resources/emoji */ -import type { BigString } from '../shared.js' +import type { BigString } from '../shared.js'; /** https://discord.com/developers/docs/resources/emoji#create-guild-emoji */ export interface CreateGuildEmoji { /** Name of the emoji */ - name: string + name: string; /** The 128x128 emoji image. */ - image: string + image: string; /** Roles allowed to use this emoji */ - roles: BigString[] + roles: BigString[]; } /** https://discord.com/developers/docs/resources/emoji#modify-guild-emoji */ export interface ModifyGuildEmoji { /** Name of the emoji */ - name?: string + name?: string; /** Roles allowed to use this emoji */ - roles?: BigString[] | null + roles?: BigString[] | null; } /** https://discord.com/developers/docs/resources/emoji#create-application-emoji */ export interface CreateApplicationEmoji { /** Name of the emoji */ - name: string + name: string; /** The 128x128 emoji image. */ - image: string + image: string; } /** https://discord.com/developers/docs/resources/emoji#modify-application-emoji */ export interface ModifyApplicationEmoji { /** Name of the emoji */ - name: string + name: string; } diff --git a/packages/types/src/discordeno/entitlement.ts b/packages/types/src/discordeno/entitlement.ts index 4d38ceb08..c496f141b 100644 --- a/packages/types/src/discordeno/entitlement.ts +++ b/packages/types/src/discordeno/entitlement.ts @@ -1,35 +1,35 @@ /** Types for: https://discord.com/developers/docs/resources/entitlement */ -import type { BigString } from '../shared.js' +import type { BigString } from '../shared.js'; /** https://discord.com/developers/docs/resources/entitlement#list-entitlements-query-string-params */ export interface GetEntitlements { /** User ID to look up entitlements for */ - userId?: BigString + userId?: BigString; /** Optional list of SKU IDs to check entitlements for */ - skuIds?: BigString[] + skuIds?: BigString[]; /** Retrieve entitlements before this entitlement ID */ - before?: BigString + before?: BigString; /** Retrieve entitlements after this entitlement ID */ - after?: BigString + after?: BigString; /** Number of entitlements to return, 1-100, default 100 */ - limit?: number + limit?: number; /** Guild ID to look up entitlements for */ - guildId?: BigString + guildId?: BigString; /** Whether or not ended entitlements should be omitted. Defaults to false, ended entitlements are included by default. */ - excludeEnded?: boolean + excludeEnded?: boolean; /** Whether or not deleted entitlements should be omitted. Defaults to true, deleted entitlements are not included by default. */ - excludeDeleted?: boolean + excludeDeleted?: boolean; } /** https://discord.com/developers/docs/monetization/entitlements#create-test-entitlement-json-params */ export interface CreateTestEntitlement { /** ID of the SKU to grant the entitlement to */ - skuId: BigString + skuId: BigString; /** ID of the guild or user to grant the entitlement to */ - ownerId: BigString + ownerId: BigString; /** The type of entitlement, guild subscription or user subscription */ - ownerType: CreateEntitlementOwnerType + ownerType: CreateEntitlementOwnerType; } /** https://discord.com/developers/docs/monetization/entitlements#create-test-entitlement-json-params - Description of ownerType */ diff --git a/packages/types/src/discordeno/gateway.ts b/packages/types/src/discordeno/gateway.ts index 4d5d323e0..83c766e68 100644 --- a/packages/types/src/discordeno/gateway.ts +++ b/packages/types/src/discordeno/gateway.ts @@ -4,20 +4,20 @@ * - https://discord.com/developers/docs/events/gateway-events */ -import type { BigString } from '../shared.js' +import type { BigString } from '../shared.js'; /** https://discord.com/developers/docs/events/gateway-events#request-guild-members */ export interface RequestGuildMembers { /** id of the guild to get members for */ - guildId: BigString + guildId: BigString; /** String that username starts with, or an empty string to return all members */ - query?: string + query?: string; /** Maximum number of members to send matching the query; a limit of 0 can be used with an empty string query to return all members */ - limit: number + limit: number; /** Used to specify if we want the presences of the matched members */ - presences?: boolean + presences?: boolean; /** Used to specify which users you wish to fetch */ - userIds?: BigString[] + userIds?: BigString[]; /** Nonce to identify the Guild Members Chunk response */ - nonce?: string + nonce?: string; } diff --git a/packages/types/src/discordeno/guild.ts b/packages/types/src/discordeno/guild.ts index 3cfabca7d..b84768a2e 100644 --- a/packages/types/src/discordeno/guild.ts +++ b/packages/types/src/discordeno/guild.ts @@ -1,6 +1,6 @@ /** Types for: https://discord.com/developers/docs/resources/guild */ -import type { ChannelTypes, ForumLayout, SortOrderTypes, VideoQualityModes } from '../discord/channel.js' +import type { ChannelTypes, ForumLayout, SortOrderTypes, VideoQualityModes } from '../discord/channel.js'; import type { DefaultMessageNotificationLevels, DiscordGuildOnboardingMode, @@ -11,182 +11,182 @@ import type { MemberFlags, SystemChannelFlags, VerificationLevels, -} from '../discord/guild.js' -import type { PermissionStrings } from '../discord/permissions.js' -import type { BigString, Camelize } from '../shared.js' -import type { DiscordenoDefaultReactionEmoji, DiscordenoForumTag, Overwrite } from './channel.js' -import type { GuildRoleColors } from './permissions.js' +} from '../discord/guild.js'; +import type { PermissionStrings } from '../discord/permissions.js'; +import type { BigString, Camelize } from '../shared.js'; +import type { DiscordenoDefaultReactionEmoji, DiscordenoForumTag, Overwrite } from './channel.js'; +import type { GuildRoleColors } from './permissions.js'; /** https://discord.com/developers/docs/resources/guild#modify-guild-json-params */ export interface ModifyGuild { /** Guild name */ - name?: string + name?: string; /** Verification level */ - verificationLevel?: VerificationLevels | null + verificationLevel?: VerificationLevels | null; /** Default message notification filter level */ - defaultMessageNotifications?: DefaultMessageNotificationLevels | null + defaultMessageNotifications?: DefaultMessageNotificationLevels | null; /** Explicit content filter level */ - explicitContentFilter?: ExplicitContentFilterLevels | null + explicitContentFilter?: ExplicitContentFilterLevels | null; /** Id for afk channel */ - afkChannelId?: BigString | null + afkChannelId?: BigString | null; /** Afk timeout in seconds */ - afkTimeout?: number + afkTimeout?: number; /** Base64 1024x1024 png/jpeg/gif image for the guild icon (can be animated gif when the server has the `ANIMATED_ICON` feature) */ - icon?: string | null + icon?: string | null; /** Base64 16:9 png/jpeg image for the guild splash (when the server has `INVITE_SPLASH` feature) */ - splash?: string | null + splash?: string | null; /** Base64 16:9 png/jpeg image for the guild discovery spash (when the server has the `DISCOVERABLE` feature) */ - discoverySplash?: string | null + discoverySplash?: string | null; /** Base64 16:9 png/jpeg image for the guild banner (when the server has BANNER feature) */ - banner?: string | null + banner?: string | null; /** The id of the channel where guild notices such as welcome messages and boost events are posted */ - systemChannelId?: BigString | null + systemChannelId?: BigString | null; /** * System channel flags * * @see {@link SystemChannelFlags} */ - systemChannelFlags?: number + systemChannelFlags?: number; /** The id of the channel where Community guilds display rules and/or guidelines */ - rulesChannelId?: BigString | null + rulesChannelId?: BigString | null; /** The id of the channel where admins and moderators of Community guilds receive notices from Discord */ - publicUpdatesChannelId?: BigString | null + publicUpdatesChannelId?: BigString | null; /** The preferred locale of a Community guild used in server discovery and notices from Discord; defaults to "en-US" */ - preferredLocale?: string | null + preferredLocale?: string | null; /** Enabled guild features */ - features?: GuildFeatures[] + features?: GuildFeatures[]; /** The description for the guild */ - description?: string | null + description?: string | null; /** Whether the guild's boost progress bar should be enabled */ - premiumProgressBarEnabled?: boolean + premiumProgressBarEnabled?: boolean; /** The id of the channel where admins and moderators of Community guilds receive safety alerts from Discord */ - safetyAlertsChannelId?: BigString | null + safetyAlertsChannelId?: BigString | null; } /** https://discord.com/developers/docs/resources/guild#create-guild-channel-json-params */ export interface CreateGuildChannel { /** Channel name (1-100 characters) */ - name: string + name: string; /** The type of channel */ - type?: ChannelTypes + type?: ChannelTypes; /** Channel topic (0-1024 characters) */ - topic?: string + topic?: string; /** The bitrate (in bits) of the voice channel (voice only) */ - bitrate?: number + bitrate?: number; /** The user limit of the voice channel (voice only) */ - userLimit?: number + userLimit?: number; /** Amount of seconds a user has to wait before sending another message (0-21600); bots, as well as users with the permission `manage_messages` or `manage_channel`, are unaffected */ - rateLimitPerUser?: number + rateLimitPerUser?: number; /** Sorting position of the channel (channels with the same position are sorted by id) */ - position?: number + position?: number; /** The channel's permission overwrites */ - permissionOverwrites?: Overwrite[] + permissionOverwrites?: Overwrite[]; /** Id of the parent category for a channel */ - parentId?: BigString + parentId?: BigString; /** Whether the channel is nsfw */ - nsfw?: boolean + nsfw?: boolean; /** Channel voice region id of the voice or stage channel, automatic when set to null */ - rtcRegion?: string + rtcRegion?: string; /** The camera video quality mode of the voice channel */ - videoQualityMode?: VideoQualityModes + videoQualityMode?: VideoQualityModes; /** Default duration (in minutes) that clients (not the API) use for newly created threads in this channel, to determine when to automatically archive the thread after the last activity */ - defaultAutoArchiveDuration?: number + defaultAutoArchiveDuration?: number; /** Emoji to show in the add reaction button on a thread in a forum channel */ - defaultReactionEmoji?: DiscordenoDefaultReactionEmoji + defaultReactionEmoji?: DiscordenoDefaultReactionEmoji; /** Set of tags that can be used in a forum channel */ - availableTags?: DiscordenoForumTag[] + availableTags?: DiscordenoForumTag[]; /** The default sort order type used to order posts in forum channels */ - defaultSortOrder?: SortOrderTypes | null + defaultSortOrder?: SortOrderTypes | null; /** the default forum layout view used to display posts in GUILD_FORUM channels */ - defaultForumLayout?: ForumLayout + defaultForumLayout?: ForumLayout; /** The initial ratelimit to set on newly created threads in a channel. */ - defaultThreadRateLimitPerUser?: number + defaultThreadRateLimitPerUser?: number; } /** https://discord.com/developers/docs/resources/guild#modify-guild-channel-positions-json-params */ export interface ModifyGuildChannelPositions { /** Channel id */ - id: BigString + id: BigString; /** Sorting position of the channel (channels with the same position are sorted by id) */ - position?: number | null + position?: number | null; /** Syncs the permission overwrites with the new parent, if moving to a new category */ - lockPermissions?: boolean | null + lockPermissions?: boolean | null; /** The new parent ID for the channel that is moved */ - parentId?: BigString | null + parentId?: BigString | null; } /** https://discord.com/developers/docs/resources/guild#list-guild-members-query-string-params */ export interface ListGuildMembers { /** Max number of members to return (1-1000). Default: 1 */ - limit?: number + limit?: number; /** The highest user id in the previous page. Default: 0 */ - after?: string + after?: string; } /** https://discord.com/developers/docs/resources/guild#search-guild-members-query-string-params */ export interface SearchMembers { /** Query string to match username(s) and nickname(s) against */ - query: string + query: string; /** Max number of members to return (1-1000). Default: 1 */ - limit?: number + limit?: number; } /** https://discord.com/developers/docs/resources/guild#add-guild-member-json-params */ export interface AddGuildMemberOptions { /** access token of a user that has granted your app the `guilds.join` scope */ - accessToken: string + accessToken: string; /** Value to set user's nickname to. Requires MANAGE_NICKNAMES permission on the bot */ - nick?: string + nick?: string; /** Array of role ids the member is assigned. Requires MANAGE_ROLES permission on the bot */ - roles?: BigString[] + roles?: BigString[]; /** Whether the user is muted in voice channels. Requires MUTE_MEMBERS permission on the bot */ - mute?: boolean + mute?: boolean; /** Whether the user is deafened in voice channels. Requires DEAFEN_MEMBERS permission on the bot */ - deaf?: boolean + deaf?: boolean; } /** https://discord.com/developers/docs/resources/guild#modify-guild-member-json-params */ export interface ModifyGuildMember { /** Value to set users nickname to. Requires the `MANAGE_NICKNAMES` permission */ - nick?: string | null + nick?: string | null; /** Array of role ids the member is assigned. Requires the `MANAGE_ROLES` permission */ - roles?: BigString[] | null + roles?: BigString[] | null; /** Whether the user is muted in voice channels. Will throw a 400 if the user is not in a voice channel. Requires the `MUTE_MEMBERS` permission */ - mute?: boolean | null + mute?: boolean | null; /** Whether the user is deafened in voice channels. Will throw a 400 if the user is not in a voice channel. Requires the `MOVE_MEMBERS` permission */ - deaf?: boolean | null + deaf?: boolean | null; /** Id of channel to move user to (if they are connected to voice). Requires the `MOVE_MEMBERS` permission */ - channelId?: BigString | null + channelId?: BigString | null; /** When the user's timeout will expire and the user will be able to communicate in the guild again (up to 28 days in the future), set to null to remove timeout. Requires the `MODERATE_MEMBERS` permission. The date must be given in a ISO string form. */ - communicationDisabledUntil?: string | null + communicationDisabledUntil?: string | null; /** * Set the flags for the guild member. Requires the `MANAGE_GUILD` or `MANAGE_ROLES` or the combination of `MODERATE_MEMBERS` and `KICK_MEMBERS` and `BAN_MEMBERS` * * @see {@link MemberFlags} */ - flags?: number + flags?: number; } /** https://discord.com/developers/docs/resources/guild#modify-current-member-json-params */ export interface EditBotMemberOptions { /** Value to set user's nickname to */ - nick?: string | null + nick?: string | null; /** Data URI base64 encoded banner image */ - banner?: string | null + banner?: string | null; /** Data URI base64 encoded avatar image */ - avatar?: string | null + avatar?: string | null; /** Guild member bio */ - bio?: string | null + bio?: string | null; } /** https://discord.com/developers/docs/resources/guild#get-guild-bans-query-string-params */ export interface GetBans { /** Number of users to return (up to maximum 1000). Default: 1000 */ - limit?: number + limit?: number; /** Consider only users before given user id */ - before?: BigString + before?: BigString; /** Consider only users after given user id */ - after?: BigString + after?: BigString; } /** https://discord.com/developers/docs/resources/guild#create-guild-ban-json-params */ @@ -196,91 +196,91 @@ export interface CreateGuildBan { * * @default 0 */ - deleteMessageSeconds?: number + deleteMessageSeconds?: number; } /** https://discord.com/developers/docs/resources/guild#bulk-guild-ban-json-params */ export interface CreateGuildBulkBan { /** list of user ids to ban (max 200) */ - userIds: BigString[] + userIds: BigString[]; /** * Number of seconds to delete messages for, between 0 and 604800 (7 days) * * @default 0 */ - deleteMessageSeconds?: number + deleteMessageSeconds?: number; } /** https://discord.com/developers/docs/resources/guild#create-guild-role-json-params */ export interface CreateGuildRole { /** Name of the role, max 100 characters, default: "new role" */ - name?: string + name?: string; /** Bitwise value of the enabled/disabled permissions, default: everyone permissions in guild */ - permissions?: PermissionStrings[] | string + permissions?: PermissionStrings[] | string; /** * RGB color value, default: 0 * @deprecated the {@link colors} field is recommended for use instead of this field */ - color?: number + color?: number; /** The role's color */ - colors?: GuildRoleColors + colors?: GuildRoleColors; /** Whether the role should be displayed separately in the sidebar, default: false */ - hoist?: boolean + hoist?: boolean; /** the role's icon image (if the guild has the `ROLE_ICONS` feature) */ - icon?: string | null + icon?: string | null; /** The role's unicode emoji (if the guild has the `ROLE_ICONS` feature) */ - unicodeEmoji?: string | null + unicodeEmoji?: string | null; /** Whether the role should be mentionable, default: false */ - mentionable?: boolean + mentionable?: boolean; } /** https://discord.com/developers/docs/resources/guild#modify-guild-role-positions-json-params */ export interface ModifyRolePositions { /** The role id */ - id: BigString + id: BigString; /** The sorting position for the role. (roles with the same position are sorted by id) */ - position?: number | null + position?: number | null; } /** https://discord.com/developers/docs/resources/guild#modify-guild-role-json-params */ export interface EditGuildRole { /** Name of the role, max 100 characters, default: "new role" */ - name?: string | null + name?: string | null; /** Bitwise value of the enabled/disabled permissions, default: everyone permissions in guild */ - permissions?: PermissionStrings[] | string | null + permissions?: PermissionStrings[] | string | null; /** * RGB color value, default: 0 * @deprecated the {@link colors} field is recommended for use instead of this field */ - color?: number | null + color?: number | null; /** The role's color */ - colors?: GuildRoleColors | null + colors?: GuildRoleColors | null; /** Whether the role should be displayed separately in the sidebar, default: false */ - hoist?: boolean | null + hoist?: boolean | null; /** the role's icon image (if the guild has the `ROLE_ICONS` feature) */ - icon?: string | null + icon?: string | null; /** The role's unicode emoji (if the guild has the `ROLE_ICONS` feature) */ - unicodeEmoji?: string | null + unicodeEmoji?: string | null; /** Whether the role should be mentionable, default: false */ - mentionable?: boolean | null + mentionable?: boolean | null; } /** https://discord.com/developers/docs/resources/guild#get-guild-prune-count */ export interface GetGuildPruneCountQuery { /** Number of days to count prune for (1 or more), default: 7 */ - days?: number + days?: number; /** Role(s) to include, default: none */ - includeRoles?: string | string[] + includeRoles?: string | string[]; } /** https://discord.com/developers/docs/resources/guild#begin-guild-prune */ export interface BeginGuildPrune { /** Number of days to prune (1 or more), default: 7 */ - days?: number + days?: number; /** Whether 'pruned' is returned, discouraged for large guilds, default: true */ - computePruneCount?: boolean + computePruneCount?: boolean; /** Role(s) ro include, default: none */ - includeRoles?: string[] + includeRoles?: string[]; } /** https://discord.com/developers/docs/resources/guild#get-guild-widget-image-query-string-params */ @@ -294,19 +294,19 @@ export interface GetGuildWidgetImageQuery { * Banner3: Large image with guild icon, name and online count. In the footer, Discord logo on the left and "Chat Now" on the right * Banner4: Large Discord logo at the top of the widget. Guild icon, name and online count in the middle portion of the widget and a "JOIN MY SERVER" button at the bottom */ - style?: 'shield' | 'banner1' | 'banner2' | 'banner3' | 'banner4' + style?: 'shield' | 'banner1' | 'banner2' | 'banner3' | 'banner4'; } /** https://discord.com/developers/docs/resources/guild#modify-guild-onboarding-json-params */ export interface EditGuildOnboarding { /** Prompts shown during onboarding and in customize community */ - prompts?: Camelize[] + prompts?: Camelize[]; /** Channel IDs that members get opted into automatically */ - defaultChannelIds?: BigString[] + defaultChannelIds?: BigString[]; /** Whether onboarding is enabled in the guild */ - enabled?: boolean + enabled?: boolean; /** Current mode of onboarding */ - mode?: DiscordGuildOnboardingMode + mode?: DiscordGuildOnboardingMode; } /** https://discord.com/developers/docs/resources/guild#modify-guild-incident-actions-json-params */ @@ -320,7 +320,7 @@ export interface ModifyGuildIncidentActions { * Can be enabled for a maximal timespan of 24 hours in the future. * Supplying null disables the action */ - invitesDisabledUntil?: string | null + invitesDisabledUntil?: string | null; /** * When direct messages will be enabled again * @@ -330,15 +330,15 @@ export interface ModifyGuildIncidentActions { * Can be enabled for a maximal timespan of 24 hours in the future. * Supplying null disables the action */ - dmsDisabledUntil?: string | null + dmsDisabledUntil?: string | null; } /** https://discord.com/developers/docs/resources/guild#modify-guild-welcome-screen */ export interface ModifyGuildWelcomeScreen { /** Whether the welcome screen is enabled */ - enabled?: boolean | null + enabled?: boolean | null; /** Channels linked in the welcome screen and their display options */ - welcome_screen?: DiscordWelcomeScreenChannel[] | null + welcome_screen?: DiscordWelcomeScreenChannel[] | null; /** The server description to show in the welcome screen */ - description?: string | null + description?: string | null; } diff --git a/packages/types/src/discordeno/guildScheduledEvent.ts b/packages/types/src/discordeno/guildScheduledEvent.ts index 6a422ecfe..53386584f 100644 --- a/packages/types/src/discordeno/guildScheduledEvent.ts +++ b/packages/types/src/discordeno/guildScheduledEvent.ts @@ -6,71 +6,71 @@ import type { ScheduledEventEntityType, ScheduledEventPrivacyLevel, ScheduledEventStatus, -} from '../discord/guildScheduledEvent.js' -import type { BigString } from '../shared.js' +} from '../discord/guildScheduledEvent.js'; +import type { BigString } from '../shared.js'; /** https://discord.com/developers/docs/resources/guild-scheduled-event#list-scheduled-events-for-guild-query-string-params */ export interface GetScheduledEvents { /** include number of users subscribed to each event */ - withUserCount?: boolean + withUserCount?: boolean; } /** https://discord.com/developers/docs/resources/guild-scheduled-event#create-guild-scheduled-event-json-params */ export interface CreateScheduledEvent { /** the channel id of the scheduled event. */ - channelId?: BigString - entityMetadata?: DiscordScheduledEventEntityMetadata + channelId?: BigString; + entityMetadata?: DiscordScheduledEventEntityMetadata; /** the name of the scheduled event */ - name: string + name: string; /** the privacy level of the scheduled event */ - privacyLevel?: ScheduledEventPrivacyLevel + privacyLevel?: ScheduledEventPrivacyLevel; /** the time the scheduled event will start */ - scheduledStartTime: string + scheduledStartTime: string; /** the time the scheduled event will end if it does end. Required for events with `entityType: ScheduledEventEntityType.External` */ - scheduledEndTime?: string + scheduledEndTime?: string; /** the description of the scheduled event */ - description: string + description: string; /** the type of hosting entity associated with a scheduled event */ - entityType: ScheduledEventEntityType + entityType: ScheduledEventEntityType; /** the cover image of the scheduled event */ - image?: string + image?: string; /** the definition for how often this event should recur */ - recurrenceRule?: DiscordScheduledEventRecurrenceRule + recurrenceRule?: DiscordScheduledEventRecurrenceRule; } /** https://discord.com/developers/docs/resources/guild-scheduled-event#modify-guild-scheduled-event-json-params */ export interface EditScheduledEvent { /** the channel id of the scheduled event. null if switching to external event. */ - channelId?: BigString | null + channelId?: BigString | null; /** The entity metadata for the scheduled event */ - entityMetadata?: DiscordScheduledEventEntityMetadata | null + entityMetadata?: DiscordScheduledEventEntityMetadata | null; /** the name of the scheduled event */ - name?: string + name?: string; /** the privacy level of the scheduled event */ - privacyLevel?: ScheduledEventPrivacyLevel + privacyLevel?: ScheduledEventPrivacyLevel; /** the time the scheduled event will start */ - scheduledStartTime?: string + scheduledStartTime?: string; /** the time the scheduled event will end if it does end. */ - scheduledEndTime?: string + scheduledEndTime?: string; /** the description of the scheduled event */ - description?: string | null + description?: string | null; /** the type of hosting entity associated with a scheduled event */ - entityType?: ScheduledEventEntityType + entityType?: ScheduledEventEntityType; /** the status of the scheduled event */ - status?: ScheduledEventStatus + status?: ScheduledEventStatus; /** the cover image of the scheduled event */ - image?: string + image?: string; /** the definition for how often this event should recur */ - recurrenceRule?: DiscordScheduledEventRecurrenceRule | null + recurrenceRule?: DiscordScheduledEventRecurrenceRule | null; } export interface GetScheduledEventUsers { /** number of users to return (up to maximum 100), defaults to 100 */ - limit?: number + limit?: number; /** whether to also have member objects provided, defaults to false */ - withMember?: boolean + withMember?: boolean; /** consider only users before given user id */ - before?: BigString + before?: BigString; /** consider only users after given user id. If both before and after are provided, only before is respected. Fetching users in-between before and after is not supported. */ - after?: BigString + after?: BigString; } diff --git a/packages/types/src/discordeno/guildTemplate.ts b/packages/types/src/discordeno/guildTemplate.ts index 92b9436df..48a790059 100644 --- a/packages/types/src/discordeno/guildTemplate.ts +++ b/packages/types/src/discordeno/guildTemplate.ts @@ -3,15 +3,15 @@ /** https://discord.com/developers/docs/resources/guild-template#create-guild-template-json-params */ export interface CreateTemplate { /** Name which the template should have */ - name: string + name: string; /** Description of the template */ - description?: string | null + description?: string | null; } /** https://discord.com/developers/docs/resources/guild-template#modify-guild-template-json-params */ export interface ModifyGuildTemplate { /** Name of the template (1-100 characters) */ - name?: string + name?: string; /** Description of the template (0-120 characters) */ - description?: string | null + description?: string | null; } diff --git a/packages/types/src/discordeno/interactions.ts b/packages/types/src/discordeno/interactions.ts index 72950bcdf..b6667ea56 100644 --- a/packages/types/src/discordeno/interactions.ts +++ b/packages/types/src/discordeno/interactions.ts @@ -4,7 +4,7 @@ * - https://discord.com/developers/docs/interactions/application-commands */ -import type { DiscordApplicationIntegrationType } from '../discord/application.js' +import type { DiscordApplicationIntegrationType } from '../discord/application.js'; import type { ApplicationCommandTypes, DiscordApplicationCommandOption, @@ -12,22 +12,22 @@ import type { DiscordInteractionContextType, DiscordInteractionEntryPointCommandHandlerType, InteractionResponseTypes, -} from '../discord/interactions.js' -import type { DiscordAttachment, DiscordEmbed, MessageFlags } from '../discord/message.js' -import type { PermissionStrings } from '../discord/permissions.js' -import type { Localization } from '../discord/reference.js' -import type { BigString, Camelize } from '../shared.js' -import type { MessageComponents } from './components.js' -import type { AllowedMentions } from './message.js' -import type { CreatePoll } from './poll.js' -import type { FileContent } from './reference.js' +} from '../discord/interactions.js'; +import type { DiscordAttachment, DiscordEmbed, MessageFlags } from '../discord/message.js'; +import type { PermissionStrings } from '../discord/permissions.js'; +import type { Localization } from '../discord/reference.js'; +import type { BigString, Camelize } from '../shared.js'; +import type { MessageComponents } from './components.js'; +import type { AllowedMentions } from './message.js'; +import type { CreatePoll } from './poll.js'; +import type { FileContent } from './reference.js'; /** https://discord.com/developers/docs/interactions/receiving-and-responding#interaction-response-object-interaction-response-structure */ export interface InteractionResponse { /** The type of response */ - type: InteractionResponseTypes + type: InteractionResponseTypes; /** An optional response message */ - data?: InteractionCallbackData + data?: InteractionCallbackData; } // Since this is a merge of 3 types, the properties appear in order of their first appearance in the 3 types @@ -39,37 +39,37 @@ export interface InteractionResponse { export interface InteractionCallbackData { // Messages /** True if this is a TTS message */ - tts?: boolean + tts?: boolean; /** The message contents (up to 2000 characters) */ - content?: string + content?: string; /** Embedded `rich` content (up to 6000 characters) */ - embeds?: Camelize[] + embeds?: Camelize[]; /** Allowed mentions for the message */ - allowedMentions?: AllowedMentions + allowedMentions?: AllowedMentions; /** * Message flags combined as a bit field (only `SUPPRESS_EMBEDS`, `EPHEMERAL`, `IS_COMPONENTS_V2`, `IS_VOICE_MESSAGE` and `SUPPRESS_NOTIFICATIONS` can be set) * * @see {@link MessageFlags} */ - flags?: number + flags?: number; /** The components you would like to have sent in this message */ - components?: MessageComponents + components?: MessageComponents; /** Attachment objects with filename and description */ - attachments?: Pick[] + attachments?: Pick[]; /** The contents of the files being sent */ - files?: FileContent[] + files?: FileContent[]; /** Details about the poll */ - poll?: CreatePoll + poll?: CreatePoll; // Autocomplete /** Autocomplete choices (max of 25 choices) */ - choices?: Camelize[] + choices?: Camelize[]; // Modal /** The customId you want to use for this modal response. */ - customId?: string + customId?: string; /** The title you want to use for this modal response. */ - title?: string + title?: string; } /** @@ -77,7 +77,7 @@ export interface InteractionCallbackData { * - https://discord.com/developers/docs/interactions/application-commands#create-guild-application-command-json-params */ export interface InteractionCallbackOptions { - withResponse?: boolean + withResponse?: boolean; } /** https://discord.com/developers/docs/interactions/application-commands#get-global-application-commands-query-string-params */ @@ -86,7 +86,7 @@ export interface GetGlobalApplicationCommandsOptions { * Whether to include full localization dictionaries (`nameLocalizations` and `descriptionLocalizations`) in the returned objects, instead of the `nameLocalized` and `descriptionLocalized` fields. * @default false */ - withLocalizations?: boolean + withLocalizations?: boolean; } /** @@ -96,7 +96,7 @@ export interface GetGlobalApplicationCommandsOptions { */ export interface CreateGlobalApplicationCommandOptions { /** The bearer token of the developer of the application */ - bearerToken: string + bearerToken: string; } /** @@ -113,34 +113,34 @@ export interface CreateApplicationCommand { * Characters with no lowercase variants and/or uncased letters are still allowed. * ApplicationCommandTypes.User` and `ApplicationCommandTypes.Message` commands may be mixed case and can include spaces. */ - name: string + name: string; /** Localization object for the `name` field. Values follow the same restrictions as `name` */ - nameLocalizations?: Localization | null + nameLocalizations?: Localization | null; /** 1-100 character description */ - description?: string + description?: string; /** Localization object for the `description` field. Values follow the same restrictions as `description` */ - descriptionLocalizations?: Localization | null + descriptionLocalizations?: Localization | null; /** * Parameters for the command * * @remarks * This is only valid in commands of type {@link ApplicationCommandTypes.ChatInput | ChatInput} */ - options?: Camelize + options?: Camelize; /** Set of permissions represented as a bit set */ - defaultMemberPermissions?: PermissionStrings[] | string | null + defaultMemberPermissions?: PermissionStrings[] | string | null; /** * Indicates whether the command is available in DMs with the app, only for globally-scoped commands. By default, commands are visible. * * @deprecated use {@link contexts} instead */ - dmPermission?: boolean | null + dmPermission?: boolean | null; /** * Replaced by default_member_permissions and will be deprecated in the future. Indicates whether the command is enabled by default when the app is added to a guild. * * @default true */ - defaultPermission?: boolean + defaultPermission?: boolean; /** * Integration types where the command is available * @@ -148,18 +148,18 @@ export interface CreateApplicationCommand { * This value is available only for globally-scoped commands * Defaults to the application configured contexts */ - integrationTypes?: DiscordApplicationIntegrationType[] + integrationTypes?: DiscordApplicationIntegrationType[]; /** * Interaction context types where the command is available. * * @remarks * This value is available only for globally-scoped commands. */ - contexts?: DiscordInteractionContextType[] + contexts?: DiscordInteractionContextType[]; /** Type of command, defaults `ApplicationCommandTypes.ChatInput` if not set */ - type?: ApplicationCommandTypes + type?: ApplicationCommandTypes; /** Indicates whether the command is age-restricted, defaults to `false` */ - nsfw?: boolean + nsfw?: boolean; // Discord seems to have forgot to add this to the docs, however it is in the examples for this feature... /** * Determines whether the interaction is handled by the app's interactions handler or by Discord @@ -167,7 +167,7 @@ export interface CreateApplicationCommand { * @remarks * This can only be set for application commands of type `PRIMARY_ENTRY_POINT` for applications with the `EMBEDDED` flag (i.e. applications that have an Activity). */ - handler?: DiscordInteractionEntryPointCommandHandlerType + handler?: DiscordInteractionEntryPointCommandHandlerType; } /** @@ -177,7 +177,7 @@ export interface CreateApplicationCommand { */ export interface UpsertGlobalApplicationCommandOptions { /** The bearer token of the developer of the application */ - bearerToken: string + bearerToken: string; } /** @@ -187,7 +187,7 @@ export interface UpsertGlobalApplicationCommandOptions { */ export interface CreateGuildApplicationCommandOptions { /** The bearer token of the developer of the application */ - bearerToken: string + bearerToken: string; } /** https://discord.com/developers/docs/interactions/application-commands#get-guild-application-commands-query-string-params */ @@ -196,7 +196,7 @@ export interface GetGuildApplicationCommandsOptions { * Whether to include full localization dictionaries (`nameLocalizations` and `descriptionLocalizations`) in the returned objects, instead of the `nameLocalized` and `descriptionLocalized` fields. * @default false */ - withLocalizations?: boolean + withLocalizations?: boolean; } /** @@ -206,7 +206,7 @@ export interface GetGuildApplicationCommandsOptions { */ export interface UpsertGuildApplicationCommandOptions { /** The bearer token of the developer of the application */ - bearerToken: string + bearerToken: string; } /** @@ -220,7 +220,7 @@ export interface UpsertGuildApplicationCommandOptions { */ export interface GetApplicationCommandPermissionOptions { /** Access token of the user. Requires the `applications.commands.permissions.update` scope */ - accessToken: string + accessToken: string; /** Id of the application */ - applicationId: BigString + applicationId: BigString; } diff --git a/packages/types/src/discordeno/invite.ts b/packages/types/src/discordeno/invite.ts index 60423e1df..8b789b44d 100644 --- a/packages/types/src/discordeno/invite.ts +++ b/packages/types/src/discordeno/invite.ts @@ -1,11 +1,11 @@ /** Types for: https://discord.com/developers/docs/resources/invite */ -import type { BigString } from '../shared.js' +import type { BigString } from '../shared.js'; /** https://discord.com/developers/docs/resources/invite#get-invite */ export interface GetInvite { /** Whether the invite should contain approximate member counts */ - withCounts?: boolean + withCounts?: boolean; /** the guild scheduled event to include with the invite */ - scheduledEventId?: BigString + scheduledEventId?: BigString; } diff --git a/packages/types/src/discordeno/lobby.ts b/packages/types/src/discordeno/lobby.ts index 93a6dcdc9..f1e94856c 100644 --- a/packages/types/src/discordeno/lobby.ts +++ b/packages/types/src/discordeno/lobby.ts @@ -1,52 +1,52 @@ /** Types for: https://discord.com/developers/docs/resources/lobby */ -import type { DiscordLobbyMemberFlags } from '../discord/lobby.js' -import type { BigString } from '../shared.js' +import type { DiscordLobbyMemberFlags } from '../discord/lobby.js'; +import type { BigString } from '../shared.js'; /** https://discord.com/developers/docs/resources/lobby#create-lobby */ export interface CreateLobby { /** Optional dictionary of string key/value pairs. The max total length is 1000. */ - metadata?: Record | null + metadata?: Record | null; /** Optional array of up to 25 users to be added to the lobby */ - members?: CreateLobbyMember[] + members?: CreateLobbyMember[]; /** Seconds to wait before shutting down a lobby after it becomes idle. Value can be between 5 and 604800 (7 days). */ - idleTimeoutSeconds?: number + idleTimeoutSeconds?: number; } /** https://discord.com/developers/docs/resources/lobby#create-lobby */ export interface CreateLobbyMember { /** Discord user id of the user to add to the lobby */ - id: BigString + id: BigString; /** Optional dictionary of string key/value pairs. The max total length is 1000. */ - metadata?: Record | null + metadata?: Record | null; /** * Lobby member flags combined as a bitfield * * @see {@link DiscordLobbyMemberFlags} */ - flags?: number + flags?: number; } /** https://discord.com/developers/docs/resources/lobby#add-a-member-to-a-lobby */ export interface ModifyLobby { /** Optional dictionary of string key/value pairs. The max total length is 1000. Overwrites any existing metadata. */ - metadata?: Record | null + metadata?: Record | null; /** Optional array of up to 25 users to replace the lobby members with. If provided, lobby members not in this list will be removed from the lobby. */ - members?: CreateLobbyMember[] + members?: CreateLobbyMember[]; /** Seconds to wait before shutting down a lobby after it becomes idle. Value can be between 5 and 604800 (7 days). */ - idleTimeoutSeconds?: number + idleTimeoutSeconds?: number; } /** https://discord.com/developers/docs/resources/lobby#add-a-member-to-a-lobby */ export interface AddLobbyMember { /** Optional dictionary of string key/value pairs. The max total length is 1000. */ - metadata?: Record | null + metadata?: Record | null; /** Lobby member flags combined as a bitfield */ - flags?: number + flags?: number; } /** https://discord.com/developers/docs/resources/lobby#link-channel-to-lobby */ export interface LinkChannelToLobby { /** The id of the channel to link to the lobby. If not provided, will unlink any currently linked channels from the lobby. */ - channelId?: BigString + channelId?: BigString; } diff --git a/packages/types/src/discordeno/message.ts b/packages/types/src/discordeno/message.ts index 2e0cf3313..4f956266e 100644 --- a/packages/types/src/discordeno/message.ts +++ b/packages/types/src/discordeno/message.ts @@ -7,91 +7,91 @@ import type { DiscordMessageReferenceType, DiscordReactionType, MessageFlags, -} from '../discord/message.js' -import type { BigString, Camelize } from '../shared.js' -import type { MessageComponents } from './components.js' -import type { CreatePoll } from './poll.js' -import type { FileContent } from './reference.js' +} from '../discord/message.js'; +import type { BigString, Camelize } from '../shared.js'; +import type { MessageComponents } from './components.js'; +import type { CreatePoll } from './poll.js'; +import type { FileContent } from './reference.js'; // This needs the prefix Discordeno to avoid conflicts with the @discordeno/bot types. /** https://discord.com/developers/docs/resources/message#message-reference-structure */ export interface DiscordenoMessageReference { /** Type of reference */ - type?: DiscordMessageReferenceType + type?: DiscordMessageReferenceType; /** id of the originating message */ - messageId?: BigString + messageId?: BigString; /** * id of the originating message's channel * Note: `channel_id` is optional when creating a reply, but will always be present when receiving an event/response that includes this data model. */ - channelId?: BigString + channelId?: BigString; /** id of the originating message's guild */ - guildId?: BigString + guildId?: BigString; /** When sending, whether to error if the referenced message doesn't exist instead of sending as a normal (non-reply) message, default true */ - failIfNotExists?: boolean + failIfNotExists?: boolean; } /** https://discord.com/developers/docs/resources/message#allowed-mentions-object-default-settings-for-allowed-mentions */ export interface AllowedMentions { /** An array of allowed mention types to parse from the content. */ - parse?: AllowedMentionsTypes[] + parse?: AllowedMentionsTypes[]; /** For replies, whether to mention the author of the message being replied to (default false) */ - repliedUser?: boolean + repliedUser?: boolean; /** Array of role_ids to mention (Max size of 100) */ - roles?: bigint[] + roles?: bigint[]; /** Array of user_ids to mention (Max size of 100) */ - users?: bigint[] + users?: bigint[]; } /** https://discord.com/developers/docs/resources/channel#get-channel-messages-query-string-params */ export interface GetMessagesLimit { /** Max number of messages to return (1-100) default 50 */ - limit?: number + limit?: number; } /** https://discord.com/developers/docs/resources/channel#get-channel-messages-query-string-params */ export interface GetMessagesAround extends GetMessagesLimit { /** Get messages around this message id */ - around?: BigString + around?: BigString; } /** https://discord.com/developers/docs/resources/channel#get-channel-messages-query-string-params */ export interface GetMessagesBefore extends GetMessagesLimit { /** Get messages before this message id */ - before?: BigString + before?: BigString; } /** https://discord.com/developers/docs/resources/channel#get-channel-messages-query-string-params */ export interface GetMessagesAfter extends GetMessagesLimit { /** Get messages after this message id */ - after?: BigString + after?: BigString; } /** https://discord.com/developers/docs/resources/channel#get-channel-messages-query-string-params */ -export type GetMessagesOptions = GetMessagesAfter | GetMessagesBefore | GetMessagesAround | GetMessagesLimit +export type GetMessagesOptions = GetMessagesAfter | GetMessagesBefore | GetMessagesAround | GetMessagesLimit; /** https://discord.com/developers/docs/resources/message#create-message-jsonform-params */ export interface CreateMessageOptions { /** The message contents (up to 2000 characters) */ - content?: string + content?: string; /** Can be used to verify a message was sent (up to 25 characters). Value will appear in the Message Create event. */ - nonce?: string | number + nonce?: string | number; /** true if this is a TTS message */ - tts?: boolean + tts?: boolean; /** Embedded `rich` content (up to 6000 characters) */ - embeds?: Camelize[] + embeds?: Camelize[]; /** Allowed mentions for the message */ - allowedMentions?: AllowedMentions + allowedMentions?: AllowedMentions; /** Include to make your message a reply or a forward */ - messageReference?: DiscordenoMessageReference + messageReference?: DiscordenoMessageReference; /** The components you would like to have sent in this message */ - components?: MessageComponents + components?: MessageComponents; /** IDs of up to 3 stickers in the server to send in the message */ - stickerIds?: BigString[] + stickerIds?: BigString[]; /** The contents of the files being sent */ - files?: FileContent[] + files?: FileContent[]; /** Attachment objects with filename and description */ - attachments?: Pick[] + attachments?: Pick[]; /** * Message flags combined as a bitfield * @@ -100,29 +100,29 @@ export interface CreateMessageOptions { * * @see {@link MessageFlags} */ - flags?: number + flags?: number; /** If true and nonce is present, it will be checked for uniqueness in the past few minutes. If another message was created by the same author with the same nonce, that message will be returned and no new message will be created. */ - enforceNonce?: boolean + enforceNonce?: boolean; /** A poll object */ - poll?: CreatePoll + poll?: CreatePoll; } /** https://discord.com/developers/docs/resources/message#get-reactions-query-string-params */ export interface GetReactions { /** The type of reaction */ - type: DiscordReactionType + type: DiscordReactionType; /** Get users after this user Id */ - after?: string + after?: string; /** Max number of users to return (1-100) */ - limit?: number + limit?: number; } /** https://discord.com/developers/docs/resources/channel#edit-message-json-params */ export interface EditMessage { /** The new message contents (up to 2000 characters) */ - content?: string | null + content?: string | null; /** Embedded `rich` content (up to 6000 characters) */ - embeds?: Camelize[] | null + embeds?: Camelize[] | null; /** * Edit the flags of the message * @@ -131,21 +131,21 @@ export interface EditMessage { * * @see {@link MessageFlags} */ - flags?: number | null + flags?: number | null; /** Allowed mentions for the message */ - allowedMentions?: AllowedMentions | null + allowedMentions?: AllowedMentions | null; /** The components you would like to have sent in this message */ - components?: MessageComponents + components?: MessageComponents; /** The contents of the files being sent/edited */ - files?: FileContent[] + files?: FileContent[]; /** When specified (adding new attachments), attachments which are not provided in this list will be removed. */ - attachments?: Pick[] + attachments?: Pick[]; } /** https://discord.com/developers/docs/resources/message#get-channel-pins-query-string-params */ export interface GetChannelPinsOptions { /** Get messages pinned before this timestamp */ - before?: string + before?: string; /** Max number of pins to return (1-50), defaults to 50 */ - limit?: number + limit?: number; } diff --git a/packages/types/src/discordeno/permissions.ts b/packages/types/src/discordeno/permissions.ts index 3cffc54e1..c0e1583d7 100644 --- a/packages/types/src/discordeno/permissions.ts +++ b/packages/types/src/discordeno/permissions.ts @@ -3,9 +3,9 @@ /** https://discord.com/developers/docs/topics/permissions#role-object-role-colors-object */ export interface GuildRoleColors { /** The primary color for the role */ - primaryColor: number + primaryColor: number; /** The secondary color for the role, this will make the role a gradient between the other provided colors */ - secondaryColor?: number + secondaryColor?: number; /** The tertiary color for the role, this will turn the gradient into a holographic style */ - tertiaryColor?: number + tertiaryColor?: number; } diff --git a/packages/types/src/discordeno/poll.ts b/packages/types/src/discordeno/poll.ts index 3d08c58de..f58d21db5 100644 --- a/packages/types/src/discordeno/poll.ts +++ b/packages/types/src/discordeno/poll.ts @@ -1,14 +1,14 @@ /** Types for: https://discord.com/developers/docs/resources/poll */ -import type { DiscordPollAnswer, DiscordPollLayoutType, DiscordPollMedia } from '../discord/poll.js' -import type { BigString, Camelize } from '../shared.js' +import type { DiscordPollAnswer, DiscordPollLayoutType, DiscordPollMedia } from '../discord/poll.js'; +import type { BigString, Camelize } from '../shared.js'; /** https://discord.com/developers/docs/resources/poll#poll-create-request-object */ export interface CreatePoll { /** The question of the poll. Only `text` is supported. */ - question: Pick, 'text'> + question: Pick, 'text'>; /** Each of the answers available in the poll, up to 10 */ - answers: Omit, 'answerId'>[] + answers: Omit, 'answerId'>[]; /** * Number of hours the poll should be open for * @@ -17,25 +17,25 @@ export interface CreatePoll { * * @default 24 */ - duration: number + duration: number; /** * Whether a user can select multiple answers * * @default false */ - allowMultiselect: boolean + allowMultiselect: boolean; /** The layout type of the poll */ - layoutType?: DiscordPollLayoutType + layoutType?: DiscordPollLayoutType; } /** https://discord.com/developers/docs/resources/poll#get-answer-voters-query-string-params */ export interface GetPollAnswerVotes { /** Get users after this user ID */ - after?: BigString + after?: BigString; /** * Max number of users to return (1-100) * * @default 25 */ - limit?: number + limit?: number; } diff --git a/packages/types/src/discordeno/reference.ts b/packages/types/src/discordeno/reference.ts index c63ff2d8b..e9182278b 100644 --- a/packages/types/src/discordeno/reference.ts +++ b/packages/types/src/discordeno/reference.ts @@ -12,7 +12,7 @@ */ export interface FileContent { /** The file blob */ - blob: Blob + blob: Blob; /** The name of the file */ - name: string + name: string; } diff --git a/packages/types/src/discordeno/soundboard.ts b/packages/types/src/discordeno/soundboard.ts index 8e6e09339..a0bc23d7e 100644 --- a/packages/types/src/discordeno/soundboard.ts +++ b/packages/types/src/discordeno/soundboard.ts @@ -1,37 +1,37 @@ /** Types for: https://discord.com/developers/docs/resources/soundboard */ -import type { BigString } from '../shared.js' +import type { BigString } from '../shared.js'; /** https://discord.com/developers/docs/resources/soundboard#send-soundboard-sound-json-params */ export interface SendSoundboardSound { /** The id of the soundboard sound to play */ - soundId: BigString + soundId: BigString; /** The id of the guild the soundboard sound is from, required to play sounds from different servers */ - sourceGuildId?: BigString + sourceGuildId?: BigString; } /** https://discord.com/developers/docs/resources/soundboard#create-guild-soundboard-sound-json-params */ export interface CreateGuildSoundboardSound { /** Name of the soundboard sound (2-32 characters) */ - name: string + name: string; /** The mp3 or ogg sound data, base64 encoded, similar to image data */ - sound: string + sound: string; /** The volume of the soundboard sound, from 0 to 1, defaults to 1 */ - volume?: number | null + volume?: number | null; /** The id of the custom emoji for the soundboard sound */ - emojiId?: BigString | null + emojiId?: BigString | null; /** The unicode character of a standard emoji for the soundboard sound */ - emojiName?: string | null + emojiName?: string | null; } /** https://discord.com/developers/docs/resources/soundboard#modify-guild-soundboard-sound-json-params */ export interface ModifyGuildSoundboardSound { /** Name of the soundboard sound (2-32 characters) */ - name?: string + name?: string; /** The volume of the soundboard sound, from 0 to 1, defaults to 1 */ - volume?: number | null + volume?: number | null; /** The id of the custom emoji for the soundboard sound */ - emojiId?: BigString | null + emojiId?: BigString | null; /** The unicode character of a standard emoji for the soundboard sound */ - emojiName?: string | null + emojiName?: string | null; } diff --git a/packages/types/src/discordeno/stageInstance.ts b/packages/types/src/discordeno/stageInstance.ts index 41008e975..b40688c04 100644 --- a/packages/types/src/discordeno/stageInstance.ts +++ b/packages/types/src/discordeno/stageInstance.ts @@ -1,26 +1,26 @@ /** Types for: https://discord.com/developers/docs/resources/stage-instance */ -import type { DiscordStageInstancePrivacyLevel } from '../discord/stageInstance.js' -import type { BigString } from '../shared.js' +import type { DiscordStageInstancePrivacyLevel } from '../discord/stageInstance.js'; +import type { BigString } from '../shared.js'; /** https://discord.com/developers/docs/resources/stage-instance#create-stage-instance-json-params */ export interface CreateStageInstance { /** The id of the Stage channel */ - channelId: BigString + channelId: BigString; /** The topic of the Stage instance (1-120 characters) */ - topic: string + topic: string; /** The privacy level of the Stage instance */ - privacyLevel?: DiscordStageInstancePrivacyLevel + privacyLevel?: DiscordStageInstancePrivacyLevel; /** Notify \@everyone that the stage instance has started. Requires the MENTION_EVERYONE permission. */ - sendStartNotification?: boolean + sendStartNotification?: boolean; /** The guild scheduled event associated with this Stage instance */ - guildScheduledEventId?: BigString + guildScheduledEventId?: BigString; } /** https://discord.com/developers/docs/resources/stage-instance#modify-stage-instance-json-params */ export interface EditStageInstanceOptions { /** The topic of the Stage instance (1-120 characters) */ - topic?: string + topic?: string; /** The privacy level of the Stage instance */ - privacyLevel?: DiscordStageInstancePrivacyLevel + privacyLevel?: DiscordStageInstancePrivacyLevel; } diff --git a/packages/types/src/discordeno/sticker.ts b/packages/types/src/discordeno/sticker.ts index d04dff607..601e36c14 100644 --- a/packages/types/src/discordeno/sticker.ts +++ b/packages/types/src/discordeno/sticker.ts @@ -1,25 +1,25 @@ /** Types for: https://discord.com/developers/docs/resources/sticker */ -import type { FileContent } from './reference.js' +import type { FileContent } from './reference.js'; /** https://discord.com/developers/docs/resources/sticker#create-guild-sticker-form-params */ export interface CreateGuildStickerOptions { /** Name of the sticker (2-30 characters) */ - name: string + name: string; /** Description of the sticker (empty or 2-100 characters) */ - description: string + description: string; /** Autocomplete/suggestion tags for the sticker (max 200 characters) */ - tags: string + tags: string; /** The sticker file to upload, must be a PNG, APNG, or Lottie JSON file, max 512 KB */ - file: FileContent + file: FileContent; } /** https://discord.com/developers/docs/resources/sticker#modify-guild-sticker-json-params */ export interface EditGuildStickerOptions { /** Name of the sticker (2-30 characters) */ - name?: string + name?: string; /** Description of the sticker (empty or 2-100 characters) */ - description?: string | null + description?: string | null; /** Autocomplete/suggestion tags for the sticker (max 200 characters) */ - tags?: string + tags?: string; } diff --git a/packages/types/src/discordeno/subscription.ts b/packages/types/src/discordeno/subscription.ts index c728de9e6..f1198e268 100644 --- a/packages/types/src/discordeno/subscription.ts +++ b/packages/types/src/discordeno/subscription.ts @@ -1,15 +1,15 @@ /** Types for: https://discord.com/developers/docs/resources/subscription */ -import type { BigString } from '../shared.js' +import type { BigString } from '../shared.js'; /** https://discord.com/developers/docs/resources/subscription#query-string-params */ export interface ListSkuSubscriptionsOptions { /** List subscriptions before this ID */ - before?: BigString + before?: BigString; /** List subscriptions after this ID */ - after?: BigString + after?: BigString; /** Number of results to return (1-100) */ - limit?: number + limit?: number; /** User ID for which to return subscriptions. Required except for OAuth queries. */ - userId?: BigString + userId?: BigString; } diff --git a/packages/types/src/discordeno/user.ts b/packages/types/src/discordeno/user.ts index 2f9a9ee2c..945550646 100644 --- a/packages/types/src/discordeno/user.ts +++ b/packages/types/src/discordeno/user.ts @@ -1,23 +1,23 @@ /** Types for: https://discord.com/developers/docs/resources/user */ -import type { BigString } from '../shared.js' +import type { BigString } from '../shared.js'; /** https://discord.com/developers/docs/resources/user#get-current-user-guilds-query-string-params */ export interface GetUserGuilds { /** Get guilds before this guild ID */ - before?: BigString + before?: BigString; /** Get guilds after this guild ID */ - after?: BigString + after?: BigString; /** Maximum number of entries (between 1-200) to return, defaults to 200 */ - limit?: number + limit?: number; /** Include approximate member and presence counts in response, defaults to false */ - withCounts?: boolean + withCounts?: boolean; } /** https://discord.com/developers/docs/resources/user#create-group-dm-json-params */ export interface CreateGroupDmOptions { /** Access tokens of users that have granted your app the `gdm.join` scope */ - accessTokens: string[] + accessTokens: string[]; /** A mapping of user ids to their respective nicknames */ - nicks: Record + nicks: Record; } diff --git a/packages/types/src/discordeno/voice.ts b/packages/types/src/discordeno/voice.ts index 7d829c3ea..296859024 100644 --- a/packages/types/src/discordeno/voice.ts +++ b/packages/types/src/discordeno/voice.ts @@ -1,23 +1,23 @@ /** Types for: https://discord.com/developers/docs/resources/voice */ -import type { BigString } from '../shared.js' +import type { BigString } from '../shared.js'; /** https://discord.com/developers/docs/resources/voice#modify-current-user-voice-state-json-params */ export interface EditOwnVoiceState { /** The id of the channel the user is currently in */ - channelId?: BigString + channelId?: BigString; /** Toggles the user's suppress state */ - suppress?: boolean + suppress?: boolean; /** Sets the user's request to speak */ - requestToSpeakTimestamp?: number | null + requestToSpeakTimestamp?: number | null; } /** https://discord.com/developers/docs/resources/voice#modify-user-voice-state-json-params */ export interface EditUserVoiceState { /** The id of the channel the user is currently in */ - channelId?: BigString + channelId?: BigString; /** Toggles the user's suppress state */ - suppress?: boolean + suppress?: boolean; /** The user id to target */ - userId: BigString + userId: BigString; } diff --git a/packages/types/src/discordeno/webhook.ts b/packages/types/src/discordeno/webhook.ts index 7e66eaed8..098f5a24f 100644 --- a/packages/types/src/discordeno/webhook.ts +++ b/packages/types/src/discordeno/webhook.ts @@ -1,28 +1,28 @@ /** Types for: https://discord.com/developers/docs/resources/webhook */ -import type { DiscordAttachment, DiscordEmbed } from '../discord/message.js' -import type { BigString, Camelize } from '../shared.js' -import type { MessageComponents } from './components.js' -import type { AllowedMentions } from './message.js' -import type { CreatePoll } from './poll.js' -import type { FileContent } from './reference.js' +import type { DiscordAttachment, DiscordEmbed } from '../discord/message.js'; +import type { BigString, Camelize } from '../shared.js'; +import type { MessageComponents } from './components.js'; +import type { AllowedMentions } from './message.js'; +import type { CreatePoll } from './poll.js'; +import type { FileContent } from './reference.js'; /** https://discord.com/developers/docs/resources/webhook#create-webhook-json-params */ export interface CreateWebhook { /** Name of the webhook (1-80 characters) */ - name: string + name: string; /** Image url for the default webhook avatar */ - avatar?: string | null + avatar?: string | null; } /** https://discord.com/developers/docs/resources/webhook#modify-webhook-json-params */ export interface ModifyWebhook { /** The default name of the webhook */ - name?: string + name?: string; /** Image for the default webhook avatar */ - avatar?: BigString | null + avatar?: BigString | null; /** The new channel id this webhook should be moved to */ - channelId?: BigString + channelId?: BigString; } /** https://discord.com/developers/docs/resources/webhook#execute-webhook */ @@ -30,31 +30,31 @@ export interface ExecuteWebhook { // Query Parameters /** Waits for server confirmation of message send before response, and returns the created message body (defaults to `false`; when `false` a message that is not saved does not return an error) */ - wait?: boolean + wait?: boolean; /** Send a message to the specified thread within a webhook's channel. The thread will automatically be unarchived. */ - threadId?: BigString + threadId?: BigString; /** * Whether to respect the `components` field of the request. * When enabled, allows application-owned webhooks to use all components and non-owned webhooks to use non-interactive components. * * @default false */ - withComponents?: boolean + withComponents?: boolean; // JSON Parameters /** The message contents (up to 2000 characters) */ - content?: string + content?: string; /** Override the default username of the webhook */ - username?: string + username?: string; /** Override the default avatar of the webhook */ - avatarUrl?: string + avatarUrl?: string; /** True if this is a TTS message */ - tts?: boolean + tts?: boolean; /** Embedded `rich` content */ - embeds?: Camelize[] + embeds?: Camelize[]; /** Allowed mentions for the message */ - allowedMentions?: AllowedMentions + allowedMentions?: AllowedMentions; /** * The components to include with the message * @@ -62,58 +62,58 @@ export interface ExecuteWebhook { * Application-owned webhooks can always send components. * Non-application-owned webhooks cannot send interactive components, and the `components` field will be ignored unless they set the `with_components` query param. */ - components?: MessageComponents + components?: MessageComponents; /** The contents of the files being sent */ - files?: FileContent[] + files?: FileContent[]; /** Attachment objects with filename and description */ - attachments?: Pick[] + attachments?: Pick[]; /** * Message flags combined in a bitfield * * @see {@link MessageFlags} */ - flags?: number + flags?: number; /** Name of the thread to create (target channel has to be type of forum channel) */ - threadName?: string + threadName?: string; /** Array of tag ids to apply to the thread (requires the webhook channel to be a forum or media channel) */ - appliedTags?: BigString[] + appliedTags?: BigString[]; /** A poll object */ - poll?: CreatePoll + poll?: CreatePoll; } /** https://discord.com/developers/docs/resources/webhook#get-webhook-message-query-string-params */ export interface GetWebhookMessageOptions { /** id of the thread the message is in */ - threadId: BigString + threadId: BigString; } /** https://discord.com/developers/docs/resources/webhook#edit-webhook-message */ export interface EditWebhookMessageOptions { // Query parameters /** Id of the thread the message is in */ - threadId?: BigString + threadId?: BigString; /** * Whether to respect the `components` field of the request. * When enabled, allows application-owned webhooks to use all components and non-owned webhooks to use non-interactive components. * * @default false */ - withComponents?: boolean + withComponents?: boolean; // JSON parameters /** The message contents (up to 2000 characters) */ - content?: string + content?: string; /** Embedded `rich` content */ - embeds?: Camelize[] + embeds?: Camelize[]; /** * Message flags combined in a bitfield * * @see {@link MessageFlags} */ - flags?: number + flags?: number; /** Allowed mentions for the message */ - allowedMentions?: AllowedMentions + allowedMentions?: AllowedMentions; /** * The components to include with the message * @@ -121,22 +121,22 @@ export interface EditWebhookMessageOptions { * Application-owned webhooks can always send components. * Non-application-owned webhooks cannot send interactive components, and the `components` field will be ignored unless they set the `with_components` query param. */ - components?: MessageComponents + components?: MessageComponents; /** The contents of the files being sent */ - files?: FileContent[] + files?: FileContent[]; /** Attached files to keep and possible descriptions for new files */ - attachments?: Pick[] + attachments?: Pick[]; /** * A poll! * * @remarks * Polls can only be added when editing a deferred interaction response. */ - poll?: CreatePoll + poll?: CreatePoll; } /** https://discord.com/developers/docs/resources/webhook#delete-webhook-message-query-string-params */ export interface DeleteWebhookMessageOptions { /** id of the thread the message is in */ - threadId: BigString + threadId: BigString; } diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index b691b4fc1..4dbd3712a 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -1,57 +1,57 @@ -export * from './discord/application.js' -export * from './discord/applicationRoleConnectionMetadata.js' -export * from './discord/auditLog.js' -export * from './discord/autoModeration.js' -export * from './discord/channel.js' -export * from './discord/components.js' -export * from './discord/emoji.js' -export * from './discord/entitlement.js' -export * from './discord/gateway.js' -export * from './discord/guild.js' -export * from './discord/guildScheduledEvent.js' -export * from './discord/guildTemplate.js' -export * from './discord/interactions.js' -export * from './discord/invite.js' -export * from './discord/lobby.js' -export * from './discord/message.js' -export * from './discord/oauth2.js' -export * from './discord/opcodes.js' -export * from './discord/permissions.js' -export * from './discord/poll.js' -export * from './discord/reference.js' -export * from './discord/sku.js' -export * from './discord/soundboard.js' -export * from './discord/stageInstance.js' -export * from './discord/sticker.js' -export * from './discord/subscription.js' -export * from './discord/teams.js' -export * from './discord/user.js' -export * from './discord/voice.js' -export * from './discord/webhook.js' -export * from './discord/webhookEvents.js' -export * from './discordeno/application.js' -export * from './discordeno/auditLog.js' -export * from './discordeno/autoModeration.js' -export * from './discordeno/channel.js' -export * from './discordeno/components.js' -export * from './discordeno/emoji.js' -export * from './discordeno/entitlement.js' -export * from './discordeno/gateway.js' -export * from './discordeno/guild.js' -export * from './discordeno/guildScheduledEvent.js' -export * from './discordeno/guildTemplate.js' -export * from './discordeno/interactions.js' -export * from './discordeno/invite.js' -export * from './discordeno/lobby.js' -export * from './discordeno/message.js' -export * from './discordeno/permissions.js' -export * from './discordeno/poll.js' -export * from './discordeno/reference.js' -export * from './discordeno/soundboard.js' -export * from './discordeno/stageInstance.js' -export * from './discordeno/sticker.js' -export * from './discordeno/subscription.js' -export * from './discordeno/user.js' -export * from './discordeno/voice.js' -export * from './discordeno/webhook.js' -export * from './shared.js' +export * from './discord/application.js'; +export * from './discord/applicationRoleConnectionMetadata.js'; +export * from './discord/auditLog.js'; +export * from './discord/autoModeration.js'; +export * from './discord/channel.js'; +export * from './discord/components.js'; +export * from './discord/emoji.js'; +export * from './discord/entitlement.js'; +export * from './discord/gateway.js'; +export * from './discord/guild.js'; +export * from './discord/guildScheduledEvent.js'; +export * from './discord/guildTemplate.js'; +export * from './discord/interactions.js'; +export * from './discord/invite.js'; +export * from './discord/lobby.js'; +export * from './discord/message.js'; +export * from './discord/oauth2.js'; +export * from './discord/opcodes.js'; +export * from './discord/permissions.js'; +export * from './discord/poll.js'; +export * from './discord/reference.js'; +export * from './discord/sku.js'; +export * from './discord/soundboard.js'; +export * from './discord/stageInstance.js'; +export * from './discord/sticker.js'; +export * from './discord/subscription.js'; +export * from './discord/teams.js'; +export * from './discord/user.js'; +export * from './discord/voice.js'; +export * from './discord/webhook.js'; +export * from './discord/webhookEvents.js'; +export * from './discordeno/application.js'; +export * from './discordeno/auditLog.js'; +export * from './discordeno/autoModeration.js'; +export * from './discordeno/channel.js'; +export * from './discordeno/components.js'; +export * from './discordeno/emoji.js'; +export * from './discordeno/entitlement.js'; +export * from './discordeno/gateway.js'; +export * from './discordeno/guild.js'; +export * from './discordeno/guildScheduledEvent.js'; +export * from './discordeno/guildTemplate.js'; +export * from './discordeno/interactions.js'; +export * from './discordeno/invite.js'; +export * from './discordeno/lobby.js'; +export * from './discordeno/message.js'; +export * from './discordeno/permissions.js'; +export * from './discordeno/poll.js'; +export * from './discordeno/reference.js'; +export * from './discordeno/soundboard.js'; +export * from './discordeno/stageInstance.js'; +export * from './discordeno/sticker.js'; +export * from './discordeno/subscription.js'; +export * from './discordeno/user.js'; +export * from './discordeno/voice.js'; +export * from './discordeno/webhook.js'; +export * from './shared.js'; diff --git a/packages/types/src/shared.ts b/packages/types/src/shared.ts index c958fc769..d4c0562c3 100644 --- a/packages/types/src/shared.ts +++ b/packages/types/src/shared.ts @@ -1,8 +1,8 @@ -export type BigString = bigint | string +export type BigString = bigint | string; -export type AtLeastOne }> = Partial & U[keyof U] -export type CamelCase = S extends `${infer T}_${infer U}` ? `${T}${Capitalize>}` : S -export type SnakeCase = S extends `${infer T}${infer U}` ? `${T extends Lowercase ? '' : '_'}${Lowercase}${SnakeCase}` : S +export type AtLeastOne }> = Partial & U[keyof U]; +export type CamelCase = S extends `${infer T}_${infer U}` ? `${T}${Capitalize>}` : S; +export type SnakeCase = S extends `${infer T}${infer U}` ? `${T extends Lowercase ? '' : '_'}${Lowercase}${SnakeCase}` : S; export type Camelize = T extends any[] ? T extends Record[] @@ -10,7 +10,7 @@ export type Camelize = T extends any[] : T : T extends Record ? { [K in keyof T as CamelCase]: Camelize } - : T + : T; export type Snakelize = T extends any[] ? T extends Record[] @@ -18,11 +18,11 @@ export type Snakelize = T extends any[] : T : T extends Record ? { [K in keyof T as SnakeCase]: Snakelize } - : T + : T; -export type PickPartial = { [P in keyof T]?: T[P] | undefined } & { [P in K]: T[P] } +export type PickPartial = { [P in keyof T]?: T[P] | undefined } & { [P in K]: T[P] }; // Functions are objects for TS, so we need to check for them explicitly -export type RecursivePartial = T extends object ? (T extends (...args: never[]) => unknown ? T : { [K in keyof T]?: RecursivePartial }) : T +export type RecursivePartial = T extends object ? (T extends (...args: never[]) => unknown ? T : { [K in keyof T]?: RecursivePartial }) : T; -export type Require = Omit & { [P in K]-?: T[P] } +export type Require = Omit & { [P in K]-?: T[P] }; diff --git a/packages/types/tests/index.spec.ts b/packages/types/tests/index.spec.ts index 4cc609818..cf4daa90a 100644 --- a/packages/types/tests/index.spec.ts +++ b/packages/types/tests/index.spec.ts @@ -1,7 +1,7 @@ -import { describe, it } from 'mocha' +import { describe, it } from 'mocha'; describe('index.ts', () => { it('will import without error', async () => { - await import('../src/index.js') - }) -}) + await import('../src/index.js'); + }); +}); diff --git a/packages/utils/src/Collection.ts b/packages/utils/src/Collection.ts index 095b3416c..5a74ef946 100644 --- a/packages/utils/src/Collection.ts +++ b/packages/utils/src/Collection.ts @@ -5,162 +5,162 @@ export class Collection extends Map { * The maximum amount of items allowed in this collection. To disable cache, set it 0, set to undefined to make it infinite. * @default undefined */ - maxSize: number | undefined + maxSize: number | undefined; /** Handler to remove items from the collection every so often. */ - sweeper: (CollectionSweeper & { intervalId?: NodeJS.Timeout }) | undefined + sweeper: (CollectionSweeper & { intervalId?: NodeJS.Timeout }) | undefined; constructor(entries?: (ReadonlyArray | null) | Map, options?: CollectionOptions) { - super(entries ?? []) + super(entries ?? []); - this.maxSize = options?.maxSize + this.maxSize = options?.maxSize; - if (!options?.sweeper) return + if (!options?.sweeper) return; - this.startSweeper(options.sweeper) + this.startSweeper(options.sweeper); } startSweeper(options: CollectionSweeper): NodeJS.Timeout { - if (this.sweeper?.intervalId) clearInterval(this.sweeper.intervalId) + if (this.sweeper?.intervalId) clearInterval(this.sweeper.intervalId); - this.sweeper = options + this.sweeper = options; this.sweeper.intervalId = setInterval(() => { this.forEach((value, key) => { - if (!this.sweeper?.filter(value, key, options.bot)) return + if (!this.sweeper?.filter(value, key, options.bot)) return; - this.delete(key) - return key - }) - }, options.interval) + this.delete(key); + return key; + }); + }, options.interval); - return this.sweeper.intervalId + return this.sweeper.intervalId; } stopSweeper(): void { - return clearInterval(this.sweeper?.intervalId) + return clearInterval(this.sweeper?.intervalId); } changeSweeperInterval(newInterval: number): void { - if (this.sweeper == null) return + if (this.sweeper == null) return; - this.startSweeper({ filter: this.sweeper.filter, interval: newInterval }) + this.startSweeper({ filter: this.sweeper.filter, interval: newInterval }); } changeSweeperFilter(newFilter: (value: V, key: K, bot: PlaceHolderBot) => boolean): void { - if (this.sweeper == null) return + if (this.sweeper == null) return; - this.startSweeper({ filter: newFilter, interval: this.sweeper.interval }) + this.startSweeper({ filter: newFilter, interval: this.sweeper.interval }); } /** Add an item to the collection. Makes sure not to go above the maxSize. */ set(key: K, value: V): this { // When this collection is maxSized make sure we can add first if ((this.maxSize !== undefined || this.maxSize === 0) && this.size >= this.maxSize) { - return this + return this; } - return super.set(key, value) + return super.set(key, value); } /** Add an item to the collection, no matter what the maxSize is. */ forceSet(key: K, value: V): this { - return super.set(key, value) + return super.set(key, value); } /** Convert the collection to an array. */ array(): V[] { - return [...this.values()] + return [...this.values()]; } /** Retrieve the value of the first element in this collection. */ first(): V | undefined { - return this.values().next().value + return this.values().next().value; } /** Retrieve the value of the last element in this collection. */ last(): V | undefined { - return [...this.values()][this.size - 1] + return [...this.values()][this.size - 1]; } /** Retrieve the value of a random element in this collection. */ random(): V | undefined { - const array = [...this.values()] - return array[Math.floor(Math.random() * array.length)] + const array = [...this.values()]; + return array[Math.floor(Math.random() * array.length)]; } /** Find a specific element in this collection. */ find(callback: (value: V, key: K) => boolean): NonNullable | undefined { for (const key of this.keys()) { - const value = this.get(key)! - if (callback(value, key)) return value + const value = this.get(key)!; + if (callback(value, key)) return value; } // If nothing matched } /** Find all elements in this collection that match the given pattern. */ filter(callback: (value: V, key: K) => boolean): Collection { - const relevant = new Collection() + const relevant = new Collection(); this.forEach((value, key) => { - if (callback(value, key)) relevant.set(key, value) - }) + if (callback(value, key)) relevant.set(key, value); + }); - return relevant + return relevant; } /** Converts the collection into an array by running a callback on all items in the collection. */ map(callback: (value: V, key: K) => T): T[] { - const results = [] + const results = []; for (const key of this.keys()) { - const value = this.get(key)! - results.push(callback(value, key)) + const value = this.get(key)!; + results.push(callback(value, key)); } - return results + return results; } /** Check if one of the items in the collection matches the pattern. */ some(callback: (value: V, key: K) => boolean): boolean { for (const key of this.keys()) { - const value = this.get(key)! - if (callback(value, key)) return true + const value = this.get(key)!; + if (callback(value, key)) return true; } - return false + return false; } /** Check if all of the items in the collection matches the pattern. */ every(callback: (value: V, key: K) => boolean): boolean { for (const key of this.keys()) { - const value = this.get(key)! - if (!callback(value, key)) return false + const value = this.get(key)!; + if (!callback(value, key)) return false; } - return true + return true; } /** Runs a callback on all items in the collection, merging them into a single value. */ reduce(callback: (accumulator: T, value: V, key: K) => T, initialValue?: T): T { - let accumulator: T = initialValue! + let accumulator: T = initialValue!; for (const key of this.keys()) { - const value = this.get(key)! - accumulator = callback(accumulator, value, key) + const value = this.get(key)!; + accumulator = callback(accumulator, value, key); } - return accumulator + return accumulator; } } export interface CollectionOptions { /** Handler to clean out the items in the collection every so often. */ - sweeper?: CollectionSweeper + sweeper?: CollectionSweeper; /** The maximum number of items allowed in the collection. */ - maxSize?: number + maxSize?: number; } export interface CollectionSweeper { /** The filter to determine whether an element should be deleted or not */ - filter: (value: V, key: K, ...args: any[]) => boolean + filter: (value: V, key: K, ...args: any[]) => boolean; /** The interval in which the sweeper should run */ - interval: number + interval: number; /** The bot object itself */ - bot?: PlaceHolderBot + bot?: PlaceHolderBot; } diff --git a/packages/utils/src/base64.ts b/packages/utils/src/base64.ts index 4c6232632..7260d0426 100644 --- a/packages/utils/src/base64.ts +++ b/packages/utils/src/base64.ts @@ -4,8 +4,8 @@ * @param data */ export function encode(data: Uint8Array | ArrayBuffer | string): string { - const uint8 = typeof data === 'string' ? new TextEncoder().encode(data) : data instanceof Uint8Array ? data : new Uint8Array(data) - return _encode(uint8, base64abc, false) + const uint8 = typeof data === 'string' ? new TextEncoder().encode(data) : data instanceof Uint8Array ? data : new Uint8Array(data); + return _encode(uint8, base64abc, false); } /** @@ -14,35 +14,35 @@ export function encode(data: Uint8Array | ArrayBuffer | string): string { * @returns The base64url encoded string */ export function encodeBase64Url(data: Uint8Array | ArrayBuffer | string): string { - const uint8 = typeof data === 'string' ? new TextEncoder().encode(data) : data instanceof Uint8Array ? data : new Uint8Array(data) - return _encode(uint8, base64urlAbc, true) + const uint8 = typeof data === 'string' ? new TextEncoder().encode(data) : data instanceof Uint8Array ? data : new Uint8Array(data); + return _encode(uint8, base64urlAbc, true); } /** @private */ function _encode(data: Uint8Array, alpha: string[], skipPadding: boolean): string { - let result = '' - let i - const l = data.length + let result = ''; + let i; + const l = data.length; for (i = 2; i < l; i += 3) { - result += alpha[data[i - 2] >> 2] - result += alpha[((data[i - 2] & 0x03) << 4) | (data[i - 1] >> 4)] - result += alpha[((data[i - 1] & 0x0f) << 2) | (data[i] >> 6)] - result += alpha[data[i] & 0x3f] + result += alpha[data[i - 2] >> 2]; + result += alpha[((data[i - 2] & 0x03) << 4) | (data[i - 1] >> 4)]; + result += alpha[((data[i - 1] & 0x0f) << 2) | (data[i] >> 6)]; + result += alpha[data[i] & 0x3f]; } if (i === l + 1) { // 1 octet yet to write - result += alpha[data[i - 2] >> 2] - result += alpha[(data[i - 2] & 0x03) << 4] - if (!skipPadding) result += '==' + result += alpha[data[i - 2] >> 2]; + result += alpha[(data[i - 2] & 0x03) << 4]; + if (!skipPadding) result += '=='; } if (i === l) { // 2 octets yet to write - result += alpha[data[i - 2] >> 2] - result += alpha[((data[i - 2] & 0x03) << 4) | (data[i - 1] >> 4)] - result += alpha[(data[i - 1] & 0x0f) << 2] - if (!skipPadding) result += '=' + result += alpha[data[i - 2] >> 2]; + result += alpha[((data[i - 2] & 0x03) << 4) | (data[i - 1] >> 4)]; + result += alpha[(data[i - 1] & 0x0f) << 2]; + if (!skipPadding) result += '='; } - return result + return result; } /** @@ -52,27 +52,27 @@ function _encode(data: Uint8Array, alpha: string[], skipPadding: boolean): strin */ export function decode(data: string): Uint8Array { if (data.length % 4 !== 0) { - throw new Error('Unable to parse base64 string.') + throw new Error('Unable to parse base64 string.'); } - const index = data.indexOf('=') + const index = data.indexOf('='); if (index !== -1 && index < data.length - 2) { - throw new Error('Unable to parse base64 string.') + throw new Error('Unable to parse base64 string.'); } - const missingOctets = data.endsWith('==') ? 2 : data.endsWith('=') ? 1 : 0 - const n = data.length - const result = new Uint8Array(3 * (n / 4)) - let buffer + const missingOctets = data.endsWith('==') ? 2 : data.endsWith('=') ? 1 : 0; + const n = data.length; + const result = new Uint8Array(3 * (n / 4)); + let buffer; for (let i = 0, j = 0; i < n; i += 4, j += 3) { buffer = (getBase64Code(data.charCodeAt(i)) << 18) | (getBase64Code(data.charCodeAt(i + 1)) << 12) | (getBase64Code(data.charCodeAt(i + 2)) << 6) | - getBase64Code(data.charCodeAt(i + 3)) - result[j] = buffer >> 16 - result[j + 1] = (buffer >> 8) & 0xff - result[j + 2] = buffer & 0xff + getBase64Code(data.charCodeAt(i + 3)); + result[j] = buffer >> 16; + result[j + 1] = (buffer >> 8) & 0xff; + result[j + 2] = buffer & 0xff; } - return result.subarray(0, result.length - missingOctets) + return result.subarray(0, result.length - missingOctets); } /** @@ -81,13 +81,13 @@ export function decode(data: string): Uint8Array { */ function getBase64Code(charCode: number): number { if (charCode >= base64codes.length) { - throw new Error('Unable to parse base64 string.') + throw new Error('Unable to parse base64 string.'); } - const code = base64codes[charCode] + const code = base64codes[charCode]; if (code === 255) { - throw new Error('Unable to parse base64 string.') + throw new Error('Unable to parse base64 string.'); } - return code + return code; } // Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. @@ -156,7 +156,7 @@ const base64abc = [ '9', '+', '/', -] +]; const base64urlAbc = [ 'A', @@ -223,7 +223,7 @@ const base64urlAbc = [ '9', '-', '_', -] +]; // CREDIT: https://gist.github.com/enepomnyaschih/72c423f727d395eeaa09697058238727 const base64codes = [ @@ -231,4 +231,4 @@ const base64codes = [ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, 255, 0, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255, 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -] +]; diff --git a/packages/utils/src/bucket.ts b/packages/utils/src/bucket.ts index 23ee83209..48c29c526 100644 --- a/packages/utils/src/bucket.ts +++ b/packages/utils/src/bucket.ts @@ -1,118 +1,118 @@ -import logger from './logger.js' -import { delay } from './utils.js' +import logger from './logger.js'; +import { delay } from './utils.js'; export class LeakyBucket implements LeakyBucketOptions { - max: number - refillInterval: number - refillAmount: number + max: number; + refillInterval: number; + refillAmount: number; /** The amount of requests that have been used up already. */ - used: number = 0 + used: number = 0; /** The queue of requests to acquire an available request. Mapped by */ - queue: Array<(value: void | PromiseLike) => void> = [] + queue: Array<(value: void | PromiseLike) => void> = []; /** Whether or not the queue is already processing. */ - processing: boolean = false + processing: boolean = false; /** The timeout id for the timer to reduce the used amount by the refill amount. */ - timeoutId?: NodeJS.Timeout + timeoutId?: NodeJS.Timeout; /** The timestamp in milliseconds when the next refill is scheduled. */ - refillsAt?: number + refillsAt?: number; /** Logger used in the leaky bucket */ - logger: Pick + logger: Pick; constructor(options?: LeakyBucketOptions) { - this.max = options?.max ?? 1 - this.refillAmount = options?.refillAmount ? (options.refillAmount > this.max ? this.max : options.refillAmount) : 1 - this.refillInterval = options?.refillInterval ?? 5000 - this.logger = options?.logger ?? logger + this.max = options?.max ?? 1; + this.refillAmount = options?.refillAmount ? (options.refillAmount > this.max ? this.max : options.refillAmount) : 1; + this.refillInterval = options?.refillInterval ?? 5000; + this.logger = options?.logger ?? logger; } /** The amount of requests that still remain. */ get remaining(): number { - return this.max < this.used ? 0 : this.max - this.used + return this.max < this.used ? 0 : this.max - this.used; } /** Refills the bucket as needed. */ refillBucket(): void { - this.logger.debug(`[LeakyBucket] Timeout for leaky bucket requests executed. Refilling bucket.`) + this.logger.debug(`[LeakyBucket] Timeout for leaky bucket requests executed. Refilling bucket.`); // Lower the used amount by the refill amount - this.used = this.refillAmount > this.used ? 0 : this.used - this.refillAmount + this.used = this.refillAmount > this.used ? 0 : this.used - this.refillAmount; // Reset the refillsAt timestamp since it just got refilled - this.refillsAt = undefined + this.refillsAt = undefined; // Reset the timeoutId - clearTimeout(this.timeoutId) - this.timeoutId = undefined + clearTimeout(this.timeoutId); + this.timeoutId = undefined; if (this.used > 0) { this.timeoutId = setTimeout(() => { - this.refillBucket() - }, this.refillInterval) - this.refillsAt = Date.now() + this.refillInterval + this.refillBucket(); + }, this.refillInterval); + this.refillsAt = Date.now() + this.refillInterval; } } /** Begin processing the queue. */ async processQueue(): Promise { - this.logger.debug('[LeakyBucket] Processing queue') + this.logger.debug('[LeakyBucket] Processing queue'); // There is already a queue that is processing - if (this.processing) return this.logger.debug('[LeakyBucket] Queue is already processing.') + if (this.processing) return this.logger.debug('[LeakyBucket] Queue is already processing.'); - this.processing = true + this.processing = true; // Begin going through the queue. while (this.queue.length) { if (this.remaining) { - this.logger.debug(`[LeakyBucket] Processing queue. Remaining: ${this.remaining} Length: ${this.queue.length}`) + this.logger.debug(`[LeakyBucket] Processing queue. Remaining: ${this.remaining} Length: ${this.queue.length}`); // Resolves the promise allowing the paused execution of this request to resolve and continue. - this.queue.shift()?.() + this.queue.shift()?.(); // A request can be made - this.used++ + this.used++; // Create a new timeout for this request if none exists. if (!this.timeoutId) { - this.logger.debug(`[LeakyBucket] Creating new timeout for leaky bucket requests.`) + this.logger.debug(`[LeakyBucket] Creating new timeout for leaky bucket requests.`); this.timeoutId = setTimeout(() => { - this.refillBucket() - }, this.refillInterval) + this.refillBucket(); + }, this.refillInterval); // Set the time for when this refill will occur. - this.refillsAt = Date.now() + this.refillInterval + this.refillsAt = Date.now() + this.refillInterval; } } // Check if a refill is scheduled, since we have used up all available requests else if (this.refillsAt) { - const now = Date.now() + const now = Date.now(); // If there is time left until next refill, just delay execution. if (this.refillsAt > now) { - this.logger.debug(`[LeakyBucket] Delaying execution of leaky bucket requests for ${this.refillsAt - now}ms`) - await delay(this.refillsAt - now) - this.logger.debug(`[LeakyBucket] Resuming execution`) + this.logger.debug(`[LeakyBucket] Delaying execution of leaky bucket requests for ${this.refillsAt - now}ms`); + await delay(this.refillsAt - now); + this.logger.debug(`[LeakyBucket] Resuming execution`); } // If the refillsAt has passed but the timeout didn't yet execute delay the execution else { - this.logger.debug(`[LeakyBucket] Delaying execution of leaky bucket requests for 1000ms`) - await delay(1000) + this.logger.debug(`[LeakyBucket] Delaying execution of leaky bucket requests for 1000ms`); + await delay(1000); } } } // Loop has ended mark false so it can restart later when needed - this.processing = false + this.processing = false; } /** Pauses the execution until the request is available to be made. */ async acquire(highPriority?: boolean): Promise { return await new Promise((resolve) => { // High priority requests get added to the start of the queue - if (highPriority) this.queue.unshift(resolve) + if (highPriority) this.queue.unshift(resolve); // All other requests get pushed to the end. - else this.queue.push(resolve) + else this.queue.push(resolve); // Each request should trigger the queue to be processed. - void this.processQueue() - }) + void this.processQueue(); + }); } } @@ -121,20 +121,20 @@ export interface LeakyBucketOptions { * Max requests allowed at once. * @default 1 */ - max?: number + max?: number; /** * Interval in milliseconds between refills. * @default 5000 */ - refillInterval?: number + refillInterval?: number; /** * Amount of requests to refill at each interval. * @default 1 */ - refillAmount?: number + refillAmount?: number; /** * The logger that the leaky bucket will use * @default logger // The logger exported by `@discordeno/utils` */ - logger?: Pick + logger?: Pick; } diff --git a/packages/utils/src/builders.ts b/packages/utils/src/builders.ts index d0a6e2754..341277cbf 100644 --- a/packages/utils/src/builders.ts +++ b/packages/utils/src/builders.ts @@ -1,5 +1,5 @@ -import { EmbedsBuilder } from './builders/embeds.js' +import { EmbedsBuilder } from './builders/embeds.js'; -export * from './builders/embeds.js' +export * from './builders/embeds.js'; -export const createEmbeds = (): EmbedsBuilder => new EmbedsBuilder() +export const createEmbeds = (): EmbedsBuilder => new EmbedsBuilder(); diff --git a/packages/utils/src/builders/embeds.ts b/packages/utils/src/builders/embeds.ts index 526976a10..4924999b8 100644 --- a/packages/utils/src/builders/embeds.ts +++ b/packages/utils/src/builders/embeds.ts @@ -6,7 +6,7 @@ import type { DiscordEmbedImage, DiscordEmbedThumbnail, DiscordEmbedVideo, -} from '@discordeno/types' +} from '@discordeno/types'; /** * A builder to help create Discord embeds. @@ -19,7 +19,7 @@ import type { * .setTitle('My Second Embed') */ export class EmbedsBuilder extends Array { - #currentEmbedIndex: number = 0 + #currentEmbedIndex: number = 0; /** * Adds a new field to the current embed. @@ -31,16 +31,16 @@ export class EmbedsBuilder extends Array { */ addField(name: string, value: string, inline?: boolean): this { if (this.#currentEmbed.fields === undefined) { - this.#currentEmbed.fields = [] + this.#currentEmbed.fields = []; } this.#currentEmbed.fields.push({ name, value, inline, - }) + }); - return this + return this; } /** @@ -51,12 +51,12 @@ export class EmbedsBuilder extends Array { */ addFields(fields: DiscordEmbedField[]): this { if (this.#currentEmbed.fields === undefined) { - this.#currentEmbed.fields = [] + this.#currentEmbed.fields = []; } - this.#currentEmbed.fields.push(...fields) + this.#currentEmbed.fields.push(...fields); - return this + return this; } /** @@ -66,13 +66,13 @@ export class EmbedsBuilder extends Array { */ newEmbed(): this { if (this.length >= 10) { - throw new Error('Maximum embed count exceeded. You can not have more than 10 embeds.') + throw new Error('Maximum embed count exceeded. You can not have more than 10 embeds.'); } - this.push({}) - this.setCurrentEmbed() + this.push({}); + this.setCurrentEmbed(); - return this + return this; } /** @@ -87,9 +87,9 @@ export class EmbedsBuilder extends Array { ...this.#currentEmbed.author, ...options, name, - } + }; - return this + return this; } /** @@ -101,16 +101,16 @@ export class EmbedsBuilder extends Array { setColor(color: number | string): this { if (typeof color === 'string') { if (color.toLowerCase() === 'random') { - return this.setRandomColor() + return this.setRandomColor(); } - const convertedValue = parseInt(color.replace('#', ''), 16) - color = Number.isNaN(convertedValue) ? 0 : convertedValue + const convertedValue = parseInt(color.replace('#', ''), 16); + color = Number.isNaN(convertedValue) ? 0 : convertedValue; } - this.#currentEmbed.color = color + this.#currentEmbed.color = color; - return this + return this; } /** @@ -123,18 +123,18 @@ export class EmbedsBuilder extends Array { */ setCurrentEmbed(index?: number): this { if (index === undefined) { - this.#currentEmbedIndex = this.length - 1 + this.#currentEmbedIndex = this.length - 1; - return this + return this; } if (index >= this.length || index < 0) { - throw new Error('Can not set the current embed to a index out of bounds.') + throw new Error('Can not set the current embed to a index out of bounds.'); } - this.#currentEmbedIndex = index + this.#currentEmbedIndex = index; - return this + return this; } /** @@ -144,9 +144,9 @@ export class EmbedsBuilder extends Array { * @returns {EmbedsBuilder} */ setDescription(description: string): this { - this.#currentEmbed.description = description + this.#currentEmbed.description = description; - return this + return this; } /** @@ -156,9 +156,9 @@ export class EmbedsBuilder extends Array { * @returns {EmbedsBuilder} */ setFields(fields: DiscordEmbedField[]): this { - this.#currentEmbed.fields = fields + this.#currentEmbed.fields = fields; - return this + return this; } /** @@ -173,9 +173,9 @@ export class EmbedsBuilder extends Array { ...this.#currentEmbed.footer, ...options, text, - } + }; - return this + return this; } /** @@ -190,9 +190,9 @@ export class EmbedsBuilder extends Array { ...this.#currentEmbed.image, ...options, url, - } + }; - return this + return this; } /** @@ -206,9 +206,9 @@ export class EmbedsBuilder extends Array { this.#currentEmbed.provider = { name, url, - } + }; - return this + return this; } /** @@ -217,7 +217,7 @@ export class EmbedsBuilder extends Array { * @returns {EmbedsBuilder} */ setRandomColor(): this { - return this.setColor(Math.floor(Math.random() * (0xffffff + 1))) + return this.setColor(Math.floor(Math.random() * (0xffffff + 1))); } /** @@ -228,13 +228,13 @@ export class EmbedsBuilder extends Array { * @returns {EmbedsBuilder} */ setTitle(title: string, url?: string): this { - this.#currentEmbed.title = title + this.#currentEmbed.title = title; if (url) { - this.setUrl(url) + this.setUrl(url); } - return this + return this; } /** @@ -244,9 +244,9 @@ export class EmbedsBuilder extends Array { * @returns {EmbedsBuilder} */ setTimestamp(timestamp?: string | number | Date): this { - this.#currentEmbed.timestamp = new Date(timestamp ?? Date.now()).toISOString() + this.#currentEmbed.timestamp = new Date(timestamp ?? Date.now()).toISOString(); - return this + return this; } /** @@ -261,9 +261,9 @@ export class EmbedsBuilder extends Array { ...this.#currentEmbed.thumbnail, ...options, url, - } + }; - return this + return this; } /** @@ -273,9 +273,9 @@ export class EmbedsBuilder extends Array { * @returns {EmbedsBuilder} */ setUrl(url: string): this { - this.#currentEmbed.url = url + this.#currentEmbed.url = url; - return this + return this; } /** @@ -290,9 +290,9 @@ export class EmbedsBuilder extends Array { ...this.#currentEmbed.video, ...options, url, - } + }; - return this + return this; } /** @@ -301,81 +301,81 @@ export class EmbedsBuilder extends Array { * @returns {EmbedsBuilder} */ validate(): this { - let totalCharacters = 0 + let totalCharacters = 0; if (this.length > 10) { - throw new Error('You can not have more than 10 embeds on a single message.') + throw new Error('You can not have more than 10 embeds on a single message.'); } this.forEach(({ author, description, fields, footer, title }, index) => { if (title) { - const trimmedTitle = title.trim() + const trimmedTitle = title.trim(); if (trimmedTitle.length > 256) { - throw new Error(`Title of embed ${index} can not be longer than 256 characters.`) + throw new Error(`Title of embed ${index} can not be longer than 256 characters.`); } - totalCharacters += trimmedTitle.length + totalCharacters += trimmedTitle.length; } if (description) { - const trimmedDescription = description.trim() + const trimmedDescription = description.trim(); if (trimmedDescription.length > 4096) { - throw new Error(`Description of embed ${index} can not be longer than 4096 characters.`) + throw new Error(`Description of embed ${index} can not be longer than 4096 characters.`); } - totalCharacters += trimmedDescription.length + totalCharacters += trimmedDescription.length; } if (fields) { if (fields.length > 25) { - throw new Error(`embed ${index} can not have more than 25 fields.`) + throw new Error(`embed ${index} can not have more than 25 fields.`); } fields.forEach(({ name, value }, fieldIndex) => { - const trimmedName = name.trim() - const trimmedValue = value.trim() + const trimmedName = name.trim(); + const trimmedValue = value.trim(); if (trimmedName.length > 256) { - throw new Error(`Name of field ${fieldIndex} on embed ${index} can not be longer than 256 characters.`) + throw new Error(`Name of field ${fieldIndex} on embed ${index} can not be longer than 256 characters.`); } if (trimmedValue.length > 4096) { - throw new Error(`Value of field ${fieldIndex} on embed ${index} can not be longer than 1024 characters.`) + throw new Error(`Value of field ${fieldIndex} on embed ${index} can not be longer than 1024 characters.`); } - totalCharacters += trimmedName.length - totalCharacters += trimmedValue.length - }) + totalCharacters += trimmedName.length; + totalCharacters += trimmedValue.length; + }); } if (footer) { - const trimmedFooterText = footer.text.trim() + const trimmedFooterText = footer.text.trim(); if (trimmedFooterText.length > 2048) { - throw new Error(`Footer text of embed ${index} can not be longer than 2048 characters.`) + throw new Error(`Footer text of embed ${index} can not be longer than 2048 characters.`); } - totalCharacters += trimmedFooterText.length + totalCharacters += trimmedFooterText.length; } if (author) { - const trimmedAuthorName = author.name.trim() + const trimmedAuthorName = author.name.trim(); if (trimmedAuthorName.length > 256) { - throw new Error(`Author name of embed ${index} can not be longer than 256 characters.`) + throw new Error(`Author name of embed ${index} can not be longer than 256 characters.`); } - totalCharacters += trimmedAuthorName.length + totalCharacters += trimmedAuthorName.length; } - }) + }); if (totalCharacters > 6000) { - throw new Error('Total character length of all embeds can not exceed 6000 characters.') + throw new Error('Total character length of all embeds can not exceed 6000 characters.'); } - return this + return this; } /** @@ -386,10 +386,10 @@ export class EmbedsBuilder extends Array { */ get #currentEmbed(): DiscordEmbed { if (this.length === 0) { - this.newEmbed() - this.setCurrentEmbed() + this.newEmbed(); + this.setCurrentEmbed(); } - return this[this.#currentEmbedIndex] + return this[this.#currentEmbedIndex]; } } diff --git a/packages/utils/src/casing.ts b/packages/utils/src/casing.ts index 916aed1e2..219b401f5 100644 --- a/packages/utils/src/casing.ts +++ b/packages/utils/src/casing.ts @@ -1,65 +1,65 @@ -import type { Camelize, Snakelize } from '@discordeno/types' +import type { Camelize, Snakelize } from '@discordeno/types'; export function camelize(object: T): Camelize { if (Array.isArray(object)) { - return object.map((element) => camelize(element)) as Camelize + return object.map((element) => camelize(element)) as Camelize; } if (typeof object === 'object' && object !== null) { - const obj = {} as Camelize - ;(Object.keys(object) as Array).forEach((key) => { + const obj = {} as Camelize; + (Object.keys(object) as Array).forEach((key) => { // @ts-expect-error js hack - ;(obj[snakeToCamelCase(key)] as Camelize<(T & object)[keyof T]>) = camelize(object[key]) - }) - return obj + (obj[snakeToCamelCase(key)] as Camelize<(T & object)[keyof T]>) = camelize(object[key]); + }); + return obj; } - return object as Camelize + return object as Camelize; } export function snakelize(object: T): Snakelize { if (Array.isArray(object)) { - return object.map((element) => snakelize(element)) as Snakelize + return object.map((element) => snakelize(element)) as Snakelize; } if (typeof object === 'object' && object !== null) { - const obj = {} as Snakelize - ;(Object.keys(object) as Array).forEach((key) => { + const obj = {} as Snakelize; + (Object.keys(object) as Array).forEach((key) => { // @ts-expect-error js hack - ;(obj[camelToSnakeCase(key)] as Snakelize<(T & object)[keyof T]>) = snakelize(object[key]) - }) - return obj + (obj[camelToSnakeCase(key)] as Snakelize<(T & object)[keyof T]>) = snakelize(object[key]); + }); + return obj; } - return object as Snakelize + return object as Snakelize; } export function snakeToCamelCase(str: string): string { - if (!str.includes('_')) return str + if (!str.includes('_')) return str; - let result = '' + let result = ''; for (let i = 0, len = str.length; i < len; ++i) { if (str[i] === '_') { - result += str[++i].toUpperCase() + result += str[++i].toUpperCase(); - continue + continue; } - result += str[i] + result += str[i]; } - return result + return result; } export function camelToSnakeCase(str: string): string { - let result = '' + let result = ''; for (let i = 0, len = str.length; i < len; ++i) { if (str[i] >= 'A' && str[i] <= 'Z') { - result += `_${str[i].toLowerCase()}` + result += `_${str[i].toLowerCase()}`; - continue + continue; } - result += str[i] + result += str[i]; } - return result + return result; } diff --git a/packages/utils/src/colors.ts b/packages/utils/src/colors.ts index ef31c1c54..9e778ad22 100644 --- a/packages/utils/src/colors.ts +++ b/packages/utils/src/colors.ts @@ -4,31 +4,31 @@ // https://deno.land/std@0.153.0/fmt/colors.ts?source export interface Code { - open: string - close: string - regexp: RegExp + open: string; + close: string; + regexp: RegExp; } /** RGB 8-bits per channel. Each in range `0->255` or `0x00->0xff` */ export interface Rgb { - r: number - g: number - b: number + r: number; + g: number; + b: number; } -let enabled = true +let enabled = true; /** * Set changing text color to enabled or disabled * @param value */ export function setColorEnabled(value: boolean) { - enabled = value + enabled = value; } /** Get whether text color change is enabled or disabled. */ export function getColorEnabled(): boolean { - return enabled + return enabled; } /** @@ -41,7 +41,7 @@ function code(open: number[], close: number): Code { open: `\x1b[${open.join(';')}m`, close: `\x1b[${close}m`, regexp: new RegExp(`\\x1b\\[${close}m`, 'g'), - } + }; } /** @@ -50,7 +50,7 @@ function code(open: number[], close: number): Code { * @param code color code to apply */ function run(str: string, code: Code): string { - return enabled ? `${code.open}${str.replace(code.regexp, code.open)}${code.close}` : str + return enabled ? `${code.open}${str.replace(code.regexp, code.open)}${code.close}` : str; } /** @@ -58,7 +58,7 @@ function run(str: string, code: Code): string { * @param str text to reset */ export function reset(str: string): string { - return run(str, code([0], 0)) + return run(str, code([0], 0)); } /** @@ -66,7 +66,7 @@ export function reset(str: string): string { * @param str text to make bold */ export function bold(str: string): string { - return run(str, code([1], 22)) + return run(str, code([1], 22)); } /** @@ -74,7 +74,7 @@ export function bold(str: string): string { * @param str text to dim */ export function dim(str: string): string { - return run(str, code([2], 22)) + return run(str, code([2], 22)); } /** @@ -82,7 +82,7 @@ export function dim(str: string): string { * @param str text to make italic */ export function italic(str: string): string { - return run(str, code([3], 23)) + return run(str, code([3], 23)); } /** @@ -90,7 +90,7 @@ export function italic(str: string): string { * @param str text to underline */ export function underline(str: string): string { - return run(str, code([4], 24)) + return run(str, code([4], 24)); } /** @@ -98,7 +98,7 @@ export function underline(str: string): string { * @param str text to invert its color */ export function inverse(str: string): string { - return run(str, code([7], 27)) + return run(str, code([7], 27)); } /** @@ -106,7 +106,7 @@ export function inverse(str: string): string { * @param str text to hide */ export function hidden(str: string): string { - return run(str, code([8], 28)) + return run(str, code([8], 28)); } /** @@ -114,7 +114,7 @@ export function hidden(str: string): string { * @param str text to strike through */ export function strikethrough(str: string): string { - return run(str, code([9], 29)) + return run(str, code([9], 29)); } /** @@ -122,7 +122,7 @@ export function strikethrough(str: string): string { * @param str text to make black */ export function black(str: string): string { - return run(str, code([30], 39)) + return run(str, code([30], 39)); } /** @@ -130,7 +130,7 @@ export function black(str: string): string { * @param str text to make red */ export function red(str: string): string { - return run(str, code([31], 39)) + return run(str, code([31], 39)); } /** @@ -138,7 +138,7 @@ export function red(str: string): string { * @param str text to make green */ export function green(str: string): string { - return run(str, code([32], 39)) + return run(str, code([32], 39)); } /** @@ -146,7 +146,7 @@ export function green(str: string): string { * @param str text to make yellow */ export function yellow(str: string): string { - return run(str, code([33], 39)) + return run(str, code([33], 39)); } /** @@ -154,7 +154,7 @@ export function yellow(str: string): string { * @param str text to make blue */ export function blue(str: string): string { - return run(str, code([34], 39)) + return run(str, code([34], 39)); } /** @@ -162,7 +162,7 @@ export function blue(str: string): string { * @param str text to make magenta */ export function magenta(str: string): string { - return run(str, code([35], 39)) + return run(str, code([35], 39)); } /** @@ -170,7 +170,7 @@ export function magenta(str: string): string { * @param str text to make cyan */ export function cyan(str: string): string { - return run(str, code([36], 39)) + return run(str, code([36], 39)); } /** @@ -178,7 +178,7 @@ export function cyan(str: string): string { * @param str text to make white */ export function white(str: string): string { - return run(str, code([37], 39)) + return run(str, code([37], 39)); } /** @@ -186,7 +186,7 @@ export function white(str: string): string { * @param str text to make gray */ export function gray(str: string): string { - return brightBlack(str) + return brightBlack(str); } /** @@ -194,7 +194,7 @@ export function gray(str: string): string { * @param str text to make bright-black */ export function brightBlack(str: string): string { - return run(str, code([90], 39)) + return run(str, code([90], 39)); } /** @@ -202,7 +202,7 @@ export function brightBlack(str: string): string { * @param str text to make bright-red */ export function brightRed(str: string): string { - return run(str, code([91], 39)) + return run(str, code([91], 39)); } /** @@ -210,7 +210,7 @@ export function brightRed(str: string): string { * @param str text to make bright-green */ export function brightGreen(str: string): string { - return run(str, code([92], 39)) + return run(str, code([92], 39)); } /** @@ -218,7 +218,7 @@ export function brightGreen(str: string): string { * @param str text to make bright-yellow */ export function brightYellow(str: string): string { - return run(str, code([93], 39)) + return run(str, code([93], 39)); } /** @@ -226,7 +226,7 @@ export function brightYellow(str: string): string { * @param str text to make bright-blue */ export function brightBlue(str: string): string { - return run(str, code([94], 39)) + return run(str, code([94], 39)); } /** @@ -234,7 +234,7 @@ export function brightBlue(str: string): string { * @param str text to make bright-magenta */ export function brightMagenta(str: string): string { - return run(str, code([95], 39)) + return run(str, code([95], 39)); } /** @@ -242,7 +242,7 @@ export function brightMagenta(str: string): string { * @param str text to make bright-cyan */ export function brightCyan(str: string): string { - return run(str, code([96], 39)) + return run(str, code([96], 39)); } /** @@ -250,7 +250,7 @@ export function brightCyan(str: string): string { * @param str text to make bright-white */ export function brightWhite(str: string): string { - return run(str, code([97], 39)) + return run(str, code([97], 39)); } /** @@ -258,7 +258,7 @@ export function brightWhite(str: string): string { * @param str text to make its background black */ export function bgBlack(str: string): string { - return run(str, code([40], 49)) + return run(str, code([40], 49)); } /** @@ -266,7 +266,7 @@ export function bgBlack(str: string): string { * @param str text to make its background red */ export function bgRed(str: string): string { - return run(str, code([41], 49)) + return run(str, code([41], 49)); } /** @@ -274,7 +274,7 @@ export function bgRed(str: string): string { * @param str text to make its background green */ export function bgGreen(str: string): string { - return run(str, code([42], 49)) + return run(str, code([42], 49)); } /** @@ -282,7 +282,7 @@ export function bgGreen(str: string): string { * @param str text to make its background yellow */ export function bgYellow(str: string): string { - return run(str, code([43], 49)) + return run(str, code([43], 49)); } /** @@ -290,7 +290,7 @@ export function bgYellow(str: string): string { * @param str text to make its background blue */ export function bgBlue(str: string): string { - return run(str, code([44], 49)) + return run(str, code([44], 49)); } /** @@ -298,7 +298,7 @@ export function bgBlue(str: string): string { * @param str text to make its background magenta */ export function bgMagenta(str: string): string { - return run(str, code([45], 49)) + return run(str, code([45], 49)); } /** @@ -306,7 +306,7 @@ export function bgMagenta(str: string): string { * @param str text to make its background cyan */ export function bgCyan(str: string): string { - return run(str, code([46], 49)) + return run(str, code([46], 49)); } /** @@ -314,7 +314,7 @@ export function bgCyan(str: string): string { * @param str text to make its background white */ export function bgWhite(str: string): string { - return run(str, code([47], 49)) + return run(str, code([47], 49)); } /** @@ -322,7 +322,7 @@ export function bgWhite(str: string): string { * @param str text to make its background bright-black */ export function bgBrightBlack(str: string): string { - return run(str, code([100], 49)) + return run(str, code([100], 49)); } /** @@ -330,7 +330,7 @@ export function bgBrightBlack(str: string): string { * @param str text to make its background bright-red */ export function bgBrightRed(str: string): string { - return run(str, code([101], 49)) + return run(str, code([101], 49)); } /** @@ -338,7 +338,7 @@ export function bgBrightRed(str: string): string { * @param str text to make its background bright-green */ export function bgBrightGreen(str: string): string { - return run(str, code([102], 49)) + return run(str, code([102], 49)); } /** @@ -346,7 +346,7 @@ export function bgBrightGreen(str: string): string { * @param str text to make its background bright-yellow */ export function bgBrightYellow(str: string): string { - return run(str, code([103], 49)) + return run(str, code([103], 49)); } /** @@ -354,7 +354,7 @@ export function bgBrightYellow(str: string): string { * @param str text to make its background bright-blue */ export function bgBrightBlue(str: string): string { - return run(str, code([104], 49)) + return run(str, code([104], 49)); } /** @@ -362,7 +362,7 @@ export function bgBrightBlue(str: string): string { * @param str text to make its background bright-magenta */ export function bgBrightMagenta(str: string): string { - return run(str, code([105], 49)) + return run(str, code([105], 49)); } /** @@ -370,7 +370,7 @@ export function bgBrightMagenta(str: string): string { * @param str text to make its background bright-cyan */ export function bgBrightCyan(str: string): string { - return run(str, code([106], 49)) + return run(str, code([106], 49)); } /** @@ -378,7 +378,7 @@ export function bgBrightCyan(str: string): string { * @param str text to make its background bright-white */ export function bgBrightWhite(str: string): string { - return run(str, code([107], 49)) + return run(str, code([107], 49)); } /* Special Color Sequences */ @@ -390,7 +390,7 @@ export function bgBrightWhite(str: string): string { * @param min number to truncate from */ function clampAndTruncate(n: number, max = 255, min = 0): number { - return Math.trunc(Math.max(Math.min(n, max), min)) + return Math.trunc(Math.max(Math.min(n, max), min)); } /** @@ -400,7 +400,7 @@ function clampAndTruncate(n: number, max = 255, min = 0): number { * @param color code */ export function rgb8(str: string, color: number): string { - return run(str, code([38, 5, clampAndTruncate(color)], 39)) + return run(str, code([38, 5, clampAndTruncate(color)], 39)); } /** @@ -410,7 +410,7 @@ export function rgb8(str: string, color: number): string { * @param color code */ export function bgRgb8(str: string, color: number): string { - return run(str, code([48, 5, clampAndTruncate(color)], 49)) + return run(str, code([48, 5, clampAndTruncate(color)], 49)); } /** @@ -430,9 +430,9 @@ export function bgRgb8(str: string, color: number): string { */ export function rgb24(str: string, color: number | Rgb): string { if (typeof color === 'number') { - return run(str, code([38, 2, (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff], 39)) + return run(str, code([38, 2, (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff], 39)); } - return run(str, code([38, 2, clampAndTruncate(color.r), clampAndTruncate(color.g), clampAndTruncate(color.b)], 39)) + return run(str, code([38, 2, clampAndTruncate(color.r), clampAndTruncate(color.g), clampAndTruncate(color.b)], 39)); } /** @@ -452,9 +452,9 @@ export function rgb24(str: string, color: number | Rgb): string { */ export function bgRgb24(str: string, color: number | Rgb): string { if (typeof color === 'number') { - return run(str, code([48, 2, (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff], 49)) + return run(str, code([48, 2, (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff], 49)); } - return run(str, code([48, 2, clampAndTruncate(color.r), clampAndTruncate(color.g), clampAndTruncate(color.b)], 49)) + return run(str, code([48, 2, clampAndTruncate(color.r), clampAndTruncate(color.g), clampAndTruncate(color.b)], 49)); } // https://github.com/chalk/ansi-regex/blob/02fa893d619d3da85411acc8fd4e2eea0e95a9d9/index.js @@ -464,12 +464,12 @@ const ANSI_PATTERN = new RegExp( '(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))', ].join('|'), 'g', -) +); /** * Remove ANSI escape codes from the string. * @param string to remove ANSI escape codes from */ export function stripColor(string: string): string { - return string.replace(ANSI_PATTERN, '') + return string.replace(ANSI_PATTERN, ''); } diff --git a/packages/utils/src/constants.ts b/packages/utils/src/constants.ts index 568731ace..9a09f381a 100644 --- a/packages/utils/src/constants.ts +++ b/packages/utils/src/constants.ts @@ -1 +1 @@ -export const DISCORDENO_VERSION = '22.0.0-beta.1' +export const DISCORDENO_VERSION = '22.0.0-beta.1'; diff --git a/packages/utils/src/hash.ts b/packages/utils/src/hash.ts index 68df5ee7f..6491043f1 100644 --- a/packages/utils/src/hash.ts +++ b/packages/utils/src/hash.ts @@ -2,18 +2,18 @@ export function iconHashToBigInt(hash: string): bigint { // The icon is animated so it needs special handling if (hash.startsWith('a_')) { // Change the `a_` to just be `a` - hash = `a${hash.substring(2)}` + hash = `a${hash.substring(2)}`; } else { // The icon is not animated but it could be that it starts with a 0 so we just put a `b` in front so nothing breaks - hash = `b${hash}` + hash = `b${hash}`; } - return BigInt(`0x${hash}`) + return BigInt(`0x${hash}`); } export function iconBigintToHash(icon: bigint): string { // Convert the bigint back to a hash - const hash = icon.toString(16) + const hash = icon.toString(16); // Hashes starting with a are animated and with b are not so need to handle that - return hash.startsWith('a') ? `a_${hash.substring(1)}` : hash.substring(1) + return hash.startsWith('a') ? `a_${hash.substring(1)}` : hash.substring(1); } diff --git a/packages/utils/src/images.ts b/packages/utils/src/images.ts index d4f0f65a4..3d921f7d3 100644 --- a/packages/utils/src/images.ts +++ b/packages/utils/src/images.ts @@ -1,14 +1,14 @@ -import { type BigString, type GetGuildWidgetImageQuery, type ImageFormat, type ImageSize, StickerFormatTypes } from '@discordeno/types' -import { iconBigintToHash } from './hash.js' +import { type BigString, type GetGuildWidgetImageQuery, type ImageFormat, type ImageSize, StickerFormatTypes } from '@discordeno/types'; +import { iconBigintToHash } from './hash.js'; export interface ImageOptions { - size?: ImageSize - format?: ImageFormat + size?: ImageSize; + format?: ImageFormat; } /** Help format an image url. */ export function formatImageUrl(url: string, size: ImageSize = 128, format?: ImageFormat): string { - return `${url}.${format ?? (url.includes('/a_') ? 'gif' : 'webp')}?size=${size}` + return `${url}.${format ?? (url.includes('/a_') ? 'gif' : 'webp')}?size=${size}`; } /** @@ -23,7 +23,7 @@ export function formatImageUrl(url: string, size: ImageSize = 128, format?: Imag * The animated parameter is used to specify the animated query parameter valid for webp images or to force the gif if the format is not set to webp. */ export function emojiUrl(emojiId: BigString, animated = false, format: ImageFormat = 'png'): string { - return `https://cdn.discordapp.com/emojis/${emojiId}.${animated ? (format === 'webp' ? 'webp' : 'gif') : format}${animated && format === 'webp' ? '?animated=true' : ''}` + return `https://cdn.discordapp.com/emojis/${emojiId}.${animated ? (format === 'webp' ? 'webp' : 'gif') : format}${animated && format === 'webp' ? '?animated=true' : ''}`; } /** @@ -39,7 +39,7 @@ export function avatarUrl(userId: BigString, avatar: BigString, options?: ImageO `https://cdn.discordapp.com/avatars/${userId}/${typeof avatar === 'string' ? avatar : iconBigintToHash(avatar)}`, options?.size ?? 128, options?.format, - ) + ); } /** @@ -50,10 +50,10 @@ export function avatarUrl(userId: BigString, avatar: BigString, options?: ImageO * @returns The user default avatar as an URL. */ export function defaultAvatarUrl(userId: BigString, discriminator: string) { - const isLegacy = discriminator === '0' || discriminator === '0000' - const index = isLegacy ? (BigInt(userId) >> 22n) % 6n : Number(discriminator) % 5 + const isLegacy = discriminator === '0' || discriminator === '0000'; + const index = isLegacy ? (BigInt(userId) >> 22n) % 6n : Number(discriminator) % 5; - return `https://cdn.discordapp.com/embed/avatars/${index}.png` + return `https://cdn.discordapp.com/embed/avatars/${index}.png`; } /** @@ -66,13 +66,13 @@ export function defaultAvatarUrl(userId: BigString, discriminator: string) { * @returns The user display avatar as an URL. */ export function displayAvatarUrl(userId: BigString, discriminator: string, avatar: BigString | undefined, options?: ImageOptions): string { - return avatar ? avatarUrl(userId, avatar, options) : defaultAvatarUrl(userId, discriminator) + return avatar ? avatarUrl(userId, avatar, options) : defaultAvatarUrl(userId, discriminator); } export function avatarDecorationUrl(avatarDecoration: BigString): string { return `https://cdn.discordapp.com/avatar-decoration-presets/${ typeof avatarDecoration === 'string' ? avatarDecoration : iconBigintToHash(avatarDecoration) - }.png` + }.png`; } /** @@ -89,7 +89,7 @@ export function bannerUrl(userId: BigString, options?: ImageOptions & { banner?: options?.size ?? 128, options?.format, ) - : undefined + : undefined; } /** @@ -106,7 +106,7 @@ export function guildBannerUrl(guildId: BigString, options: ImageOptions & { ban options.size ?? 128, options.format, ) - : undefined + : undefined; } /** @@ -124,7 +124,7 @@ export function guildIconUrl(guildId: BigString, imageHash: BigString | undefine options?.size ?? 128, options?.format, ) - : undefined + : undefined; } /** @@ -142,7 +142,7 @@ export function guildSplashUrl(guildId: BigString, imageHash: BigString | undefi options?.size ?? 128, options?.format, ) - : undefined + : undefined; } /** @@ -160,7 +160,7 @@ export function guildDiscoverySplashUrl(guildId: BigString, imageHash: BigString options?.size ?? 128, options?.format, ) - : undefined + : undefined; } /** @@ -177,7 +177,7 @@ export function guildScheduledEventCoverUrl(eventId: BigString, options: ImageOp options.size ?? 128, options.format, ) - : undefined + : undefined; } /** @@ -188,13 +188,13 @@ export function guildScheduledEventCoverUrl(eventId: BigString, options: ImageOp * @returns The link to the resource. */ export function getWidgetImageUrl(guildId: BigString, options?: GetGuildWidgetImageQuery): string { - let url = `https://discordapp.com/api/guilds/${guildId}/widget.png` + let url = `https://discordapp.com/api/guilds/${guildId}/widget.png`; if (options?.style) { - url += `?style=${options.style}` + url += `?style=${options.style}`; } - return url + return url; } /** @@ -214,7 +214,7 @@ export function memberAvatarUrl(guildId: BigString, userId: BigString, options?: options?.size ?? 128, options?.format, ) - : undefined + : undefined; } /** @@ -234,7 +234,7 @@ export function memberBannerUrl(guildId: BigString, userId: BigString, options?: options?.size ?? 128, options?.format, ) - : undefined + : undefined; } /** @@ -252,7 +252,7 @@ export function applicationIconUrl(applicationId: BigString, iconHash: BigString options?.size ?? 128, options?.format, ) - : undefined + : undefined; } /** @@ -270,7 +270,7 @@ export function applicationCoverUrl(applicationId: BigString, coverHash: BigStri options?.size ?? 128, options?.format, ) - : undefined + : undefined; } /** @@ -288,7 +288,7 @@ export function applicationAssetUrl(applicationId: BigString, assetId: BigString options?.size ?? 128, options?.format, ) - : undefined + : undefined; } /** @@ -307,7 +307,7 @@ export function stickerPackBannerUrl(bannerAssetId: BigString | undefined, optio options?.size ?? 128, options?.format, ) - : undefined + : undefined; } /** @@ -318,14 +318,14 @@ export function stickerPackBannerUrl(bannerAssetId: BigString | undefined, optio * @returns The link to the resource or `undefined`. */ export function stickerUrl(stickerId: BigString | number, options?: ImageOptions & { type?: StickerFormatTypes }): string | undefined { - if (!stickerId) return + if (!stickerId) return; const url = options?.type === StickerFormatTypes.Gif ? `https://media.discordapp.net/stickers/${stickerId}` - : `https://cdn.discordapp.com/stickers/${stickerId}` + : `https://cdn.discordapp.com/stickers/${stickerId}`; - return formatImageUrl(url, options?.size ?? 128, options?.format) + return formatImageUrl(url, options?.size ?? 128, options?.format); } /** @@ -343,7 +343,7 @@ export function teamIconUrl(teamId: BigString, iconHash: BigString | undefined, options?.size ?? 128, options?.format, ) - : undefined + : undefined; } /** @@ -361,7 +361,7 @@ export function roleIconUrl(roleId: BigString, iconHash: BigString | undefined, options?.size ?? 128, options?.format, ) - : undefined + : undefined; } /** @@ -373,7 +373,7 @@ export function roleIconUrl(roleId: BigString, iconHash: BigString | undefined, * @returns The link to the resource or `undefined` if no badge has been set. */ export function guildTagBadgeUrl(guildId: BigString, badgeHash: BigString | undefined, options?: ImageOptions): string | undefined { - if (badgeHash === undefined) return undefined + if (badgeHash === undefined) return undefined; - return formatImageUrl(`https://cdn.discordapp.com/guild-tag-badges/${guildId}/${badgeHash}`, options?.size ?? 128, options?.format) + return formatImageUrl(`https://cdn.discordapp.com/guild-tag-badges/${guildId}/${badgeHash}`, options?.size ?? 128, options?.format); } diff --git a/packages/utils/src/index.ts b/packages/utils/src/index.ts index b2a574e8b..8d86a15a6 100644 --- a/packages/utils/src/index.ts +++ b/packages/utils/src/index.ts @@ -1,19 +1,19 @@ -export * from './base64.js' -export * from './bucket.js' -export * from './builders.js' -export * from './Collection.js' -export * from './casing.js' -export * from './colors.js' -export * from './constants.js' -export * from './hash.js' -export * from './images.js' -export * from './logger.js' -export * from './oauth2.js' -export * from './permissions.js' -export * from './reactions.js' -export * from './snowflakes.js' -export * from './token.js' -export * from './typeguards.js' -export * from './urls.js' -export * from './urlToBase64.js' -export * from './utils.js' +export * from './base64.js'; +export * from './bucket.js'; +export * from './builders.js'; +export * from './Collection.js'; +export * from './casing.js'; +export * from './colors.js'; +export * from './constants.js'; +export * from './hash.js'; +export * from './images.js'; +export * from './logger.js'; +export * from './oauth2.js'; +export * from './permissions.js'; +export * from './reactions.js'; +export * from './snowflakes.js'; +export * from './token.js'; +export * from './typeguards.js'; +export * from './urls.js'; +export * from './urlToBase64.js'; +export * from './utils.js'; diff --git a/packages/utils/src/logger.ts b/packages/utils/src/logger.ts index 6b26b104c..e7e5d4141 100644 --- a/packages/utils/src/logger.ts +++ b/packages/utils/src/logger.ts @@ -1,4 +1,4 @@ -import { bgBrightMagenta, black, bold, cyan, gray, italic, red, yellow } from './colors.js' +import { bgBrightMagenta, black, bold, cyan, gray, italic, red, yellow } from './colors.js'; export enum LogLevels { Debug, @@ -14,70 +14,70 @@ const prefixes = new Map([ [LogLevels.Warn, 'WARN'], [LogLevels.Error, 'ERROR'], [LogLevels.Fatal, 'FATAL'], -]) +]); -const noColor: (str: string) => string = (msg) => msg +const noColor: (str: string) => string = (msg) => msg; const colorFunctions = new Map string>([ [LogLevels.Debug, gray], [LogLevels.Info, cyan], [LogLevels.Warn, yellow], [LogLevels.Error, (str: string) => red(str)], [LogLevels.Fatal, (str: string) => red(bold(italic(str)))], -]) +]); export function createLogger({ logLevel = LogLevels.Info, name }: { logLevel?: LogLevels; name?: string } = {}) { function log(level: LogLevels, ...args: any[]) { - if (level < logLevel) return + if (level < logLevel) return; - let color = colorFunctions.get(level) - if (!color) color = noColor + let color = colorFunctions.get(level); + if (!color) color = noColor; - const date = new Date() + const date = new Date(); const log = [ bgBrightMagenta(black(`[${date.toLocaleDateString()} ${date.toLocaleTimeString()}]`)), color(prefixes.get(level) ?? 'DEBUG'), name ? `${name} >` : '>', ...args, - ] + ]; switch (level) { case LogLevels.Debug: - return console.debug(...log) + return console.debug(...log); case LogLevels.Info: - return console.info(...log) + return console.info(...log); case LogLevels.Warn: - return console.warn(...log) + return console.warn(...log); case LogLevels.Error: - return console.error(...log) + return console.error(...log); case LogLevels.Fatal: - return console.error(...log) + return console.error(...log); default: - return console.log(...log) + return console.log(...log); } } function setLevel(level: LogLevels) { - logLevel = level + logLevel = level; } function debug(...args: any[]) { - log(LogLevels.Debug, ...args) + log(LogLevels.Debug, ...args); } function info(...args: any[]) { - log(LogLevels.Info, ...args) + log(LogLevels.Info, ...args); } function warn(...args: any[]) { - log(LogLevels.Warn, ...args) + log(LogLevels.Warn, ...args); } function error(...args: any[]) { - log(LogLevels.Error, ...args) + log(LogLevels.Error, ...args); } function fatal(...args: any[]) { - log(LogLevels.Fatal, ...args) + log(LogLevels.Fatal, ...args); } return { @@ -88,8 +88,8 @@ export function createLogger({ logLevel = LogLevels.Info, name }: { logLevel?: L warn, error, fatal, - } + }; } -export const logger = createLogger({ name: 'Discordeno' }) -export default logger +export const logger = createLogger({ name: 'Discordeno' }); +export default logger; diff --git a/packages/utils/src/oauth2.ts b/packages/utils/src/oauth2.ts index 8bfae2d57..cd75412ca 100644 --- a/packages/utils/src/oauth2.ts +++ b/packages/utils/src/oauth2.ts @@ -1,26 +1,26 @@ -import type { BigString, DiscordApplicationIntegrationType, OAuth2Scope, PermissionStrings } from '@discordeno/types' -import { encodeBase64Url } from './base64.js' -import { calculateBits } from './permissions.js' +import type { BigString, DiscordApplicationIntegrationType, OAuth2Scope, PermissionStrings } from '@discordeno/types'; +import { encodeBase64Url } from './base64.js'; +import { calculateBits } from './permissions.js'; export function createOAuth2Link(options: CreateOAuth2LinkOptions): string { - const joinedScopeString = options.scope.join('%20') + const joinedScopeString = options.scope.join('%20'); - let url = `https://discord.com/oauth2/authorize?client_id=${options.clientId}&scope=${joinedScopeString}` + let url = `https://discord.com/oauth2/authorize?client_id=${options.clientId}&scope=${joinedScopeString}`; - if (options.responseType) url += `&response_type=${options.responseType}` - if (options.state) url += `&state=${encodeURIComponent(options.state)}` - if (options.redirectUri) url += `&redirect_uri=${encodeURIComponent(options.redirectUri)}` - if (options.prompt) url += `&prompt=${options.prompt}` - if (options.permissions) url += `&permissions=${Array.isArray(options.permissions) ? calculateBits(options.permissions) : options.permissions}` - if (options.guildId) url += `&guild_id=${options.guildId}` - if (options.disableGuildSelect !== undefined) url += `&disable_guild_select=${options.disableGuildSelect}` - if (options.integrationType) url += `&integration_type=${options.integrationType}` + if (options.responseType) url += `&response_type=${options.responseType}`; + if (options.state) url += `&state=${encodeURIComponent(options.state)}`; + if (options.redirectUri) url += `&redirect_uri=${encodeURIComponent(options.redirectUri)}`; + if (options.prompt) url += `&prompt=${options.prompt}`; + if (options.permissions) url += `&permissions=${Array.isArray(options.permissions) ? calculateBits(options.permissions) : options.permissions}`; + if (options.guildId) url += `&guild_id=${options.guildId}`; + if (options.disableGuildSelect !== undefined) url += `&disable_guild_select=${options.disableGuildSelect}`; + if (options.integrationType) url += `&integration_type=${options.integrationType}`; // Options defined by RFC 7636 (https://datatracker.ietf.org/doc/html/rfc7636) - if (options.codeChallenge) url += `&code_challenge=${options.codeChallenge}` - if (options.codeChallengeMethod) url += `&code_challenge_method=${options.codeChallengeMethod}` + if (options.codeChallenge) url += `&code_challenge=${options.codeChallenge}`; + if (options.codeChallengeMethod) url += `&code_challenge_method=${options.codeChallengeMethod}`; - return url + return url; } /** @@ -36,9 +36,9 @@ export function createOAuth2Link(options: CreateOAuth2LinkOptions): string { * @see https://datatracker.ietf.org/doc/html/rfc7636#section-4.1 for why 32 octets is the default */ export function generateCodeVerifier(octetLength: number = 32) { - const randomBytes = new Uint8Array(octetLength) - crypto.getRandomValues(randomBytes) - return encodeBase64Url(randomBytes) + const randomBytes = new Uint8Array(octetLength); + crypto.getRandomValues(randomBytes); + return encodeBase64Url(randomBytes); } /** @@ -51,8 +51,8 @@ export function generateCodeVerifier(octetLength: number = 32) { * This performs a SHA-256 hash on the verifier and encodes it using base64url encoding. Discord only supports 'S256' as the code challenge method. */ export async function createCodeChallenge(verifier: string) { - const hashed = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(verifier)) - return encodeBase64Url(hashed) + const hashed = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(verifier)); + return encodeBase64Url(hashed); } export interface CreateOAuth2LinkOptions { @@ -62,24 +62,24 @@ export interface CreateOAuth2LinkOptions { * @remarks * Should be defined only if using either OAuth2 authorization, implicit or not, or [advanced bot authorization](https://discord.com/developers/docs/topics/oauth2#advanced-bot-authorization) */ - responseType?: 'code' | 'token' + responseType?: 'code' | 'token'; /** The id of the application */ - clientId: BigString + clientId: BigString; /** The scopes for the application */ - scope: OAuth2Scope[] + scope: OAuth2Scope[]; /** * The optional state for security * * @see https://discord.com/developers/docs/topics/oauth2#state-and-security */ - state?: string + state?: string; /** * The redirect uri for after the authentication * * @remarks * Should be defined only if using either OAuth2 authorization, implicit or not, or [advanced bot authorization](https://discord.com/developers/docs/topics/oauth2#advanced-bot-authorization) */ - redirectUri?: string + redirectUri?: string; /** * The type of prompt to give to the user * @@ -87,28 +87,28 @@ export interface CreateOAuth2LinkOptions { * If set to `none`, it will skip the authorization screen and redirect them back to your redirect URI without requesting their authorization. * For passthrough scopes, like bot and webhook.incoming, authorization is always required. */ - prompt?: 'consent' | 'none' + prompt?: 'consent' | 'none'; /** * The permissions of the invited bot * * @remarks * Should be defined only in a [bot authorization flow](https://discord.com/developers/docs/topics/oauth2#bot-authorization-flow) or with [advanced bot authorization](https://discord.com/developers/docs/topics/oauth2#advanced-bot-authorization) */ - permissions?: BigString | PermissionStrings[] + permissions?: BigString | PermissionStrings[]; /** * Pre-fills the dropdown picker with a guild for the user * * @remarks * Should be defined only in a [bot authorization flow](https://discord.com/developers/docs/topics/oauth2#bot-authorization-flow) or with [advanced bot authorization](https://discord.com/developers/docs/topics/oauth2#advanced-bot-authorization) or with the `webhook.incoming` scope */ - guildId?: BigString + guildId?: BigString; /** * Disallows the user from changing the guild dropdown if set to true * * @remarks * Should be defined only in a [bot authorization flow](https://discord.com/developers/docs/topics/oauth2#bot-authorization-flow), with [advanced bot authorization](https://discord.com/developers/docs/topics/oauth2#advanced-bot-authorization) or with the `webhook.incoming` scope */ - disableGuildSelect?: boolean + disableGuildSelect?: boolean; /** * Specifies the installation context for the authorization * @@ -119,13 +119,13 @@ export interface CreateOAuth2LinkOptions { * * The application must be configured in the Developer Portal to support the provided `integrationType`. */ - integrationType?: DiscordApplicationIntegrationType + integrationType?: DiscordApplicationIntegrationType; /** * The code challenge used to verify the authorization request * * @see https://datatracker.ietf.org/doc/html/rfc7636#section-4.1 */ - codeChallenge?: string + codeChallenge?: string; /** * The challenge method used to generate the code challenge * @@ -134,5 +134,5 @@ export interface CreateOAuth2LinkOptions { * * @see https://datatracker.ietf.org/doc/html/rfc7636#section-4.2 */ - codeChallengeMethod?: 'S256' + codeChallengeMethod?: 'S256'; } diff --git a/packages/utils/src/permissions.ts b/packages/utils/src/permissions.ts index 4ac43145d..639ead589 100644 --- a/packages/utils/src/permissions.ts +++ b/packages/utils/src/permissions.ts @@ -1,22 +1,22 @@ -import type { PermissionStrings } from '@discordeno/types' -import { BitwisePermissionFlags } from '@discordeno/types' +import type { PermissionStrings } from '@discordeno/types'; +import { BitwisePermissionFlags } from '@discordeno/types'; /** This function converts a bitwise string to permission strings */ export function calculatePermissions(permissionBits: bigint): PermissionStrings[] { return Object.keys(BitwisePermissionFlags).filter((permission) => { // Since Object.keys() not only returns the permission names but also the bit values we need to return false if it is a Number - if (Number(permission)) return false + if (Number(permission)) return false; // Check if permissionBits has this permission - return permissionBits & BitwisePermissionFlags[permission as PermissionStrings] - }) as PermissionStrings[] + return permissionBits & BitwisePermissionFlags[permission as PermissionStrings]; + }) as PermissionStrings[]; } /** This function converts an array of permissions into the bitwise string. */ export function calculateBits(permissions: PermissionStrings[]): string { return permissions .reduce((bits, perm) => { - bits |= BitwisePermissionFlags[perm] - return bits + bits |= BitwisePermissionFlags[perm]; + return bits; }, 0n) - .toString() + .toString(); } diff --git a/packages/utils/src/reactions.ts b/packages/utils/src/reactions.ts index d99033908..478def9a8 100644 --- a/packages/utils/src/reactions.ts +++ b/packages/utils/src/reactions.ts @@ -1,12 +1,12 @@ /** Converts an reaction emoji unicode string to the discord required form of name:id */ export function processReactionString(reaction: string): string { if (reaction.startsWith('<:')) { - return reaction.substring(2, reaction.length - 1) + return reaction.substring(2, reaction.length - 1); } if (reaction.startsWith('> 22n) + 1420070400000 + return Number(BigInt(snowflake) >> 22n) + 1420070400000; } diff --git a/packages/utils/src/token.ts b/packages/utils/src/token.ts index 79bf2e58a..0a4ebba6c 100644 --- a/packages/utils/src/token.ts +++ b/packages/utils/src/token.ts @@ -1,21 +1,21 @@ -const validTokenPrefixes = ['Bot', 'Bearer'] +const validTokenPrefixes = ['Bot', 'Bearer']; /** Removes the Bot/Bearer before the token. */ export function removeTokenPrefix(token?: string, type: 'GATEWAY' | 'REST' = 'REST'): string { // If no token is provided, throw an error if (token === undefined) { - throw new Error(`The ${type} was not given a token. Please provide a token and try again.`) + throw new Error(`The ${type} was not given a token. Please provide a token and try again.`); } - const splittedToken = token.split(' ') + const splittedToken = token.split(' '); // If the token does not have a prefix just return token - if (splittedToken.length < 2 || !validTokenPrefixes.includes(splittedToken[0])) return token + if (splittedToken.length < 2 || !validTokenPrefixes.includes(splittedToken[0])) return token; // Remove the prefix and return only the token. - return splittedToken.splice(1).join(' ') + return splittedToken.splice(1).join(' '); } /** Get the bot id from the bot token. WARNING: Discord staff has mentioned this may not be stable forever. Use at your own risk. However, note for over 5 years this has never broken. */ export function getBotIdFromToken(token: string): bigint { - return BigInt(atob(token.split('.')[0])) + return BigInt(atob(token.split('.')[0])); } diff --git a/packages/utils/src/typeguards.ts b/packages/utils/src/typeguards.ts index d7d3fdb94..553c0f994 100644 --- a/packages/utils/src/typeguards.ts +++ b/packages/utils/src/typeguards.ts @@ -6,25 +6,25 @@ import type { GetMessagesBefore, GetMessagesLimit, GetMessagesOptions, -} from '@discordeno/types' -import { hasProperty } from './utils.js' +} from '@discordeno/types'; +import { hasProperty } from './utils.js'; export function isGetMessagesAfter(options: GetMessagesOptions): options is GetMessagesAfter { - return hasProperty(options, 'after') + return hasProperty(options, 'after'); } export function isGetMessagesBefore(options: GetMessagesOptions): options is GetMessagesBefore { - return hasProperty(options, 'before') + return hasProperty(options, 'before'); } export function isGetMessagesAround(options: GetMessagesOptions): options is GetMessagesAround { - return hasProperty(options, 'around') + return hasProperty(options, 'around'); } export function isGetMessagesLimit(options: GetMessagesOptions): options is GetMessagesLimit { - return hasProperty(options, 'limit') + return hasProperty(options, 'limit'); } export function isInviteWithMetadata(options: DiscordInviteCreate | DiscordInviteMetadata): options is DiscordInviteMetadata { - return !hasProperty(options, 'channel_id') + return !hasProperty(options, 'channel_id'); } diff --git a/packages/utils/src/urlToBase64.ts b/packages/utils/src/urlToBase64.ts index 68c54bd31..1ea19fff4 100644 --- a/packages/utils/src/urlToBase64.ts +++ b/packages/utils/src/urlToBase64.ts @@ -1,9 +1,9 @@ -import { encode } from './base64.js' +import { encode } from './base64.js'; /** Converts a url to base 64. Useful for example, uploading/creating server emojis. */ export async function urlToBase64(url: string): Promise { - const buffer = await fetch(url).then(async (res) => await res.arrayBuffer()) - const imageStr = encode(buffer) - const type = url.substring(url.lastIndexOf('.') + 1) - return `data:image/${type};base64,${imageStr}` + const buffer = await fetch(url).then(async (res) => await res.arrayBuffer()); + const imageStr = encode(buffer); + const type = url.substring(url.lastIndexOf('.') + 1); + return `data:image/${type};base64,${imageStr}`; } diff --git a/packages/utils/src/urls.ts b/packages/utils/src/urls.ts index 10f473741..dcc671f71 100644 --- a/packages/utils/src/urls.ts +++ b/packages/utils/src/urls.ts @@ -1,13 +1,13 @@ -import type { BigString } from '@discordeno/types' +import type { BigString } from '@discordeno/types'; export function skuLink(appId: BigString, skuId: BigString): string { - return `https://discord.com/application-directory/${appId}/store/${skuId}` + return `https://discord.com/application-directory/${appId}/store/${skuId}`; } export function storeLink(appId: BigString): string { - return `https://discord.com/application-directory/${appId}/store` + return `https://discord.com/application-directory/${appId}/store`; } export function soundLink(soundId: BigString): string { - return `https://cdn.discordapp.com/soundboard-sounds/${soundId}` + return `https://cdn.discordapp.com/soundboard-sounds/${soundId}`; } diff --git a/packages/utils/src/utils.ts b/packages/utils/src/utils.ts index a8211afac..ca6fed3a7 100644 --- a/packages/utils/src/utils.ts +++ b/packages/utils/src/utils.ts @@ -3,16 +3,16 @@ export async function delay(ms: number): Promise { return new Promise( (resolve): NodeJS.Timeout => setTimeout((): void => { - resolve() + resolve(); }, ms), - ) + ); } // Typescript is not so good as we developers so we need this little utility function to help it out // Taken from https://fettblog.eu/typescript-hasownproperty/ /** TS save way to check if a property exists in an object */ export function hasProperty(obj: T, prop: Y): obj is T & Record { - return obj.hasOwnProperty(prop) + return obj.hasOwnProperty(prop); } /** Convert `JSON.stringify`-unserializable record values for debugging purposes. */ @@ -20,8 +20,8 @@ export function jsonSafeReplacer(_key: string, value: unknown): unknown { switch (typeof value) { case 'bigint': // Bigints are unserializable by `JSON.stringify`. - return String(value) + return String(value); default: // Any other unhandled type that isn't supposed to require conversion. - return value + return value; } } diff --git a/packages/utils/tests/base64.spec.ts b/packages/utils/tests/base64.spec.ts index 2a7eb38c7..7baddfdbc 100644 --- a/packages/utils/tests/base64.spec.ts +++ b/packages/utils/tests/base64.spec.ts @@ -1,113 +1,113 @@ -import { Buffer } from 'node:buffer' -import { expect } from 'chai' -import { describe, it } from 'mocha' -import { decode, encode, encodeBase64Url } from '../src/base64.js' +import { Buffer } from 'node:buffer'; +import { expect } from 'chai'; +import { describe, it } from 'mocha'; +import { decode, encode, encodeBase64Url } from '../src/base64.js'; describe('base64.ts', () => { describe('encode', () => { it('can encode string to base64', () => { - expect(encode('Man Ё𤭢')).to.be.equal('TWFuINCB8KStog==') - }) + expect(encode('Man Ё𤭢')).to.be.equal('TWFuINCB8KStog=='); + }); it('can encode Uint8Array to base64', () => { - expect(encode(new Uint8Array([77, 97, 110, 32, 208, 129, 240, 164, 173, 162]))).to.be.equal('TWFuINCB8KStog==') - expect(encode(new Uint8Array([77, 97, 110, 32, 208, 129, 240, 164, 173]))).to.be.equal('TWFuINCB8KSt') - expect(encode(new Uint8Array([77, 97, 110, 32, 208, 129, 240, 164, 173, 162, 63]))).to.be.equal('TWFuINCB8KStoj8=') - expect(encode(new Uint8Array([199, 239, 242]))).to.be.equal('x+/y') + expect(encode(new Uint8Array([77, 97, 110, 32, 208, 129, 240, 164, 173, 162]))).to.be.equal('TWFuINCB8KStog=='); + expect(encode(new Uint8Array([77, 97, 110, 32, 208, 129, 240, 164, 173]))).to.be.equal('TWFuINCB8KSt'); + expect(encode(new Uint8Array([77, 97, 110, 32, 208, 129, 240, 164, 173, 162, 63]))).to.be.equal('TWFuINCB8KStoj8='); + expect(encode(new Uint8Array([199, 239, 242]))).to.be.equal('x+/y'); // From https://datatracker.ietf.org/doc/html/rfc4648#section-10 - expect(encode(new Uint8Array([]))).to.be.equal('') - expect(encode(new Uint8Array([102]))).to.be.equal('Zg==') - expect(encode(new Uint8Array([102, 111]))).to.be.equal('Zm8=') - expect(encode(new Uint8Array([102, 111, 111]))).to.be.equal('Zm9v') - expect(encode(new Uint8Array([102, 111, 111, 98]))).to.be.equal('Zm9vYg==') - expect(encode(new Uint8Array([102, 111, 111, 98, 97]))).to.be.equal('Zm9vYmE=') - expect(encode(new Uint8Array([102, 111, 111, 98, 97, 114]))).to.be.equal('Zm9vYmFy') - }) + expect(encode(new Uint8Array([]))).to.be.equal(''); + expect(encode(new Uint8Array([102]))).to.be.equal('Zg=='); + expect(encode(new Uint8Array([102, 111]))).to.be.equal('Zm8='); + expect(encode(new Uint8Array([102, 111, 111]))).to.be.equal('Zm9v'); + expect(encode(new Uint8Array([102, 111, 111, 98]))).to.be.equal('Zm9vYg=='); + expect(encode(new Uint8Array([102, 111, 111, 98, 97]))).to.be.equal('Zm9vYmE='); + expect(encode(new Uint8Array([102, 111, 111, 98, 97, 114]))).to.be.equal('Zm9vYmFy'); + }); it('can encode Buffer to base64', () => { - expect(encode(Buffer.from([77, 97, 110, 32, 208, 129, 240, 164, 173, 162]))).to.be.equal('TWFuINCB8KStog==') - expect(encode(Buffer.from([77, 97, 110, 32, 208, 129, 240, 164, 173]))).to.be.equal('TWFuINCB8KSt') - expect(encode(Buffer.from([77, 97, 110, 32, 208, 129, 240, 164, 173, 162, 63]))).to.be.equal('TWFuINCB8KStoj8=') - expect(encode(Buffer.from([199, 239, 242]))).to.be.equal('x+/y') + expect(encode(Buffer.from([77, 97, 110, 32, 208, 129, 240, 164, 173, 162]))).to.be.equal('TWFuINCB8KStog=='); + expect(encode(Buffer.from([77, 97, 110, 32, 208, 129, 240, 164, 173]))).to.be.equal('TWFuINCB8KSt'); + expect(encode(Buffer.from([77, 97, 110, 32, 208, 129, 240, 164, 173, 162, 63]))).to.be.equal('TWFuINCB8KStoj8='); + expect(encode(Buffer.from([199, 239, 242]))).to.be.equal('x+/y'); // From https://datatracker.ietf.org/doc/html/rfc4648#section-10 - expect(encode(Buffer.from([]))).to.be.equal('') - expect(encode(Buffer.from([102]))).to.be.equal('Zg==') - expect(encode(Buffer.from([102, 111]))).to.be.equal('Zm8=') - expect(encode(Buffer.from([102, 111, 111]))).to.be.equal('Zm9v') - expect(encode(Buffer.from([102, 111, 111, 98]))).to.be.equal('Zm9vYg==') - expect(encode(Buffer.from([102, 111, 111, 98, 97]))).to.be.equal('Zm9vYmE=') - expect(encode(Buffer.from([102, 111, 111, 98, 97, 114]))).to.be.equal('Zm9vYmFy') - }) - }) + expect(encode(Buffer.from([]))).to.be.equal(''); + expect(encode(Buffer.from([102]))).to.be.equal('Zg=='); + expect(encode(Buffer.from([102, 111]))).to.be.equal('Zm8='); + expect(encode(Buffer.from([102, 111, 111]))).to.be.equal('Zm9v'); + expect(encode(Buffer.from([102, 111, 111, 98]))).to.be.equal('Zm9vYg=='); + expect(encode(Buffer.from([102, 111, 111, 98, 97]))).to.be.equal('Zm9vYmE='); + expect(encode(Buffer.from([102, 111, 111, 98, 97, 114]))).to.be.equal('Zm9vYmFy'); + }); + }); describe('encode base64 url', () => { it('can encode string to base64 url', () => { - expect(encodeBase64Url('Man Ё𤭢')).to.be.equal('TWFuINCB8KStog') - }) + expect(encodeBase64Url('Man Ё𤭢')).to.be.equal('TWFuINCB8KStog'); + }); it('can encode Uint8Array to base64 url', () => { - expect(encodeBase64Url(new Uint8Array([77, 97, 110, 32, 208, 129, 240, 164, 173, 162]))).to.be.equal('TWFuINCB8KStog') - expect(encodeBase64Url(new Uint8Array([77, 97, 110, 32, 208, 129, 240, 164, 173]))).to.be.equal('TWFuINCB8KSt') - expect(encodeBase64Url(new Uint8Array([77, 97, 110, 32, 208, 129, 240, 164, 173, 162, 63]))).to.be.equal('TWFuINCB8KStoj8') - expect(encodeBase64Url(new Uint8Array([199, 239, 242]))).to.be.equal('x-_y') + expect(encodeBase64Url(new Uint8Array([77, 97, 110, 32, 208, 129, 240, 164, 173, 162]))).to.be.equal('TWFuINCB8KStog'); + expect(encodeBase64Url(new Uint8Array([77, 97, 110, 32, 208, 129, 240, 164, 173]))).to.be.equal('TWFuINCB8KSt'); + expect(encodeBase64Url(new Uint8Array([77, 97, 110, 32, 208, 129, 240, 164, 173, 162, 63]))).to.be.equal('TWFuINCB8KStoj8'); + expect(encodeBase64Url(new Uint8Array([199, 239, 242]))).to.be.equal('x-_y'); // From https://datatracker.ietf.org/doc/html/rfc4648#section-10 - expect(encodeBase64Url(new Uint8Array([]))).to.be.equal('') - expect(encodeBase64Url(new Uint8Array([102]))).to.be.equal('Zg') - expect(encodeBase64Url(new Uint8Array([102, 111]))).to.be.equal('Zm8') - expect(encodeBase64Url(new Uint8Array([102, 111, 111]))).to.be.equal('Zm9v') - expect(encodeBase64Url(new Uint8Array([102, 111, 111, 98]))).to.be.equal('Zm9vYg') - expect(encodeBase64Url(new Uint8Array([102, 111, 111, 98, 97]))).to.be.equal('Zm9vYmE') - expect(encodeBase64Url(new Uint8Array([102, 111, 111, 98, 97, 114]))).to.be.equal('Zm9vYmFy') - }) + expect(encodeBase64Url(new Uint8Array([]))).to.be.equal(''); + expect(encodeBase64Url(new Uint8Array([102]))).to.be.equal('Zg'); + expect(encodeBase64Url(new Uint8Array([102, 111]))).to.be.equal('Zm8'); + expect(encodeBase64Url(new Uint8Array([102, 111, 111]))).to.be.equal('Zm9v'); + expect(encodeBase64Url(new Uint8Array([102, 111, 111, 98]))).to.be.equal('Zm9vYg'); + expect(encodeBase64Url(new Uint8Array([102, 111, 111, 98, 97]))).to.be.equal('Zm9vYmE'); + expect(encodeBase64Url(new Uint8Array([102, 111, 111, 98, 97, 114]))).to.be.equal('Zm9vYmFy'); + }); it('can encode Buffer to base64 url', () => { - expect(encodeBase64Url(Buffer.from([77, 97, 110, 32, 208, 129, 240, 164, 173, 162]))).to.be.equal('TWFuINCB8KStog') - expect(encodeBase64Url(Buffer.from([77, 97, 110, 32, 208, 129, 240, 164, 173]))).to.be.equal('TWFuINCB8KSt') - expect(encodeBase64Url(Buffer.from([77, 97, 110, 32, 208, 129, 240, 164, 173, 162, 63]))).to.be.equal('TWFuINCB8KStoj8') - expect(encodeBase64Url(Buffer.from([199, 239, 242]))).to.be.equal('x-_y') + expect(encodeBase64Url(Buffer.from([77, 97, 110, 32, 208, 129, 240, 164, 173, 162]))).to.be.equal('TWFuINCB8KStog'); + expect(encodeBase64Url(Buffer.from([77, 97, 110, 32, 208, 129, 240, 164, 173]))).to.be.equal('TWFuINCB8KSt'); + expect(encodeBase64Url(Buffer.from([77, 97, 110, 32, 208, 129, 240, 164, 173, 162, 63]))).to.be.equal('TWFuINCB8KStoj8'); + expect(encodeBase64Url(Buffer.from([199, 239, 242]))).to.be.equal('x-_y'); // From https://datatracker.ietf.org/doc/html/rfc4648#section-10 - expect(encodeBase64Url(Buffer.from([]))).to.be.equal('') - expect(encodeBase64Url(Buffer.from([102]))).to.be.equal('Zg') - expect(encodeBase64Url(Buffer.from([102, 111]))).to.be.equal('Zm8') - expect(encodeBase64Url(Buffer.from([102, 111, 111]))).to.be.equal('Zm9v') - expect(encodeBase64Url(Buffer.from([102, 111, 111, 98]))).to.be.equal('Zm9vYg') - expect(encodeBase64Url(Buffer.from([102, 111, 111, 98, 97]))).to.be.equal('Zm9vYmE') - expect(encodeBase64Url(Buffer.from([102, 111, 111, 98, 97, 114]))).to.be.equal('Zm9vYmFy') - }) - }) + expect(encodeBase64Url(Buffer.from([]))).to.be.equal(''); + expect(encodeBase64Url(Buffer.from([102]))).to.be.equal('Zg'); + expect(encodeBase64Url(Buffer.from([102, 111]))).to.be.equal('Zm8'); + expect(encodeBase64Url(Buffer.from([102, 111, 111]))).to.be.equal('Zm9v'); + expect(encodeBase64Url(Buffer.from([102, 111, 111, 98]))).to.be.equal('Zm9vYg'); + expect(encodeBase64Url(Buffer.from([102, 111, 111, 98, 97]))).to.be.equal('Zm9vYmE'); + expect(encodeBase64Url(Buffer.from([102, 111, 111, 98, 97, 114]))).to.be.equal('Zm9vYmFy'); + }); + }); describe('decode', () => { it('can dencode string to Uint8Array', () => { - expect(new TextDecoder().decode(decode('TWFuINCB8KStog=='))).to.be.equal('Man Ё𤭢') - expect(new TextDecoder().decode(decode('TWFuINCB8KSt'))).to.be.equal('Man Ё\ufffd') - expect(new TextDecoder().decode(decode('TWFuINCB8KStoj8='))).to.be.equal('Man Ё𤭢?') - }) + expect(new TextDecoder().decode(decode('TWFuINCB8KStog=='))).to.be.equal('Man Ё𤭢'); + expect(new TextDecoder().decode(decode('TWFuINCB8KSt'))).to.be.equal('Man Ё\ufffd'); + expect(new TextDecoder().decode(decode('TWFuINCB8KStoj8='))).to.be.equal('Man Ё𤭢?'); + }); it('will throw an error with invalid string', () => { - expect(() => decode('=adw')).to.throw('Unable to parse base64 string.') - expect(() => decode('a')).to.throw('Unable to parse base64 string.') - expect(() => decode('$avs')).to.throw('Unable to parse base64 string.') - expect(() => decode('~daw')).to.throw('Unable to parse base64 string.') - }) - }) + expect(() => decode('=adw')).to.throw('Unable to parse base64 string.'); + expect(() => decode('a')).to.throw('Unable to parse base64 string.'); + expect(() => decode('$avs')).to.throw('Unable to parse base64 string.'); + expect(() => decode('~daw')).to.throw('Unable to parse base64 string.'); + }); + }); /** Old test */ it('[utils] encode some bytes to base64', () => { - expect(encode(new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]))).to.be.deep.equal('AQIDBAUGBwgJCg==') - }) + expect(encode(new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]))).to.be.deep.equal('AQIDBAUGBwgJCg=='); + }); it('[utils] decode some base64 to bytes', () => { - expect(decode('AQIDBAUGBwgJCg==')).to.be.deep.equal(new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])) - }) + expect(decode('AQIDBAUGBwgJCg==')).to.be.deep.equal(new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])); + }); it('[utils] encode/decode base64 roundtrip should work', () => { for (let i = 0; i < 10; i++) { - const bytes: number[] = [] + const bytes: number[] = []; for (let i = 0; i < 10000; i++) { - bytes.push(Math.floor(Math.random() * 256)) + bytes.push(Math.floor(Math.random() * 256)); } - const data = new Uint8Array(bytes) - expect(decode(encode(data))).to.be.deep.equal(data) + const data = new Uint8Array(bytes); + expect(decode(encode(data))).to.be.deep.equal(data); } - }) -}) + }); +}); diff --git a/packages/utils/tests/bucket.spec.ts b/packages/utils/tests/bucket.spec.ts index fb4b72709..ba0701625 100644 --- a/packages/utils/tests/bucket.spec.ts +++ b/packages/utils/tests/bucket.spec.ts @@ -1,27 +1,27 @@ -import { expect } from 'chai' -import { afterEach, beforeEach, describe, it } from 'mocha' -import sinon from 'sinon' -import { LeakyBucket } from '../src/bucket.js' +import { expect } from 'chai'; +import { afterEach, beforeEach, describe, it } from 'mocha'; +import sinon from 'sinon'; +import { LeakyBucket } from '../src/bucket.js'; async function promiseState(p: Promise): Promise { - const t = {} + const t = {}; return await Promise.race([p, t]).then( (v) => (v === t ? 'pending' : 'fulfilled'), () => 'rejected', - ) + ); } describe('bucket.ts', () => { - let clock: sinon.SinonFakeTimers + let clock: sinon.SinonFakeTimers; beforeEach(() => { - clock = sinon.useFakeTimers() - }) + clock = sinon.useFakeTimers(); + }); afterEach(() => { - sinon.restore() - clock.restore() - }) + sinon.restore(); + clock.restore(); + }); describe('LeakyBucket function', () => { it('will return bucket with given options', () => { @@ -33,12 +33,12 @@ describe('bucket.ts', () => { someThingElse: { thing: 'else', }, - } - const bucket = new LeakyBucket(options) - expect(bucket.max).to.equal(options.max) - expect(bucket.refillInterval).to.equal(options.refillInterval) - expect(bucket.refillAmount).to.equal(options.refillAmount) - }) + }; + const bucket = new LeakyBucket(options); + expect(bucket.max).to.equal(options.max); + expect(bucket.refillInterval).to.equal(options.refillInterval); + expect(bucket.refillAmount).to.equal(options.refillAmount); + }); it('will return bucket with refillAmount within max', () => { const options = { @@ -46,10 +46,10 @@ describe('bucket.ts', () => { refillInterval: 2002, refillAmount: 3003, tokens: 4004, - } - const bucket = new LeakyBucket(options) - expect(bucket.refillAmount).to.equal(options.max) - }) + }; + const bucket = new LeakyBucket(options); + expect(bucket.refillAmount).to.equal(options.max); + }); it('will return bucket with tokensState within max', () => { const options = { @@ -57,118 +57,118 @@ describe('bucket.ts', () => { refillInterval: 2002, refillAmount: 3003, tokens: 4004, - } - const bucket = new LeakyBucket(options) - expect(bucket.refillAmount).to.equal(options.max) - }) + }; + const bucket = new LeakyBucket(options); + expect(bucket.refillAmount).to.equal(options.max); + }); it('will return bucket with default property', () => { - const bucket = new LeakyBucket() - expect(bucket.max).equals(1) - expect(bucket.refillInterval).equals(5000) - expect(bucket.refillAmount).equals(1) - expect(bucket.queue).to.deep.equal([]) - }) + const bucket = new LeakyBucket(); + expect(bucket.max).equals(1); + expect(bucket.refillInterval).equals(5000); + expect(bucket.refillAmount).equals(1); + expect(bucket.queue).to.deep.equal([]); + }); it('will acquire a request', async () => { const bucket = new LeakyBucket({ max: 120, refillInterval: 60000, refillAmount: 120, - }) + }); - await bucket.acquire(true) - expect(bucket.remaining).to.be.equal(119) - expect(bucket.used).to.be.equal(1) - }) + await bucket.acquire(true); + expect(bucket.remaining).to.be.equal(119); + expect(bucket.used).to.be.equal(1); + }); it('will handle multiple requests at once', async () => { const bucket = new LeakyBucket({ max: 120, refillInterval: 60000, refillAmount: 120, - }) + }); for (let i = 0; i < 10; i++) { - bucket.acquire() + bucket.acquire(); } - }) + }); it('will handle too many requests', async () => { const bucket = new LeakyBucket({ max: 5, refillInterval: 10000, refillAmount: 5, - }) + }); for (let i = 0; i < 10; i++) { - bucket.acquire() + bucket.acquire(); } - }) + }); it('bucket refills are done properly', async () => { const bucket = new LeakyBucket({ max: 2, refillInterval: 500, refillAmount: 2, - }) + }); - await bucket.acquire() - expect(bucket.remaining).equals(1) - expect(bucket.used).equals(1) - await clock.tickAsync(1000) - expect(bucket.remaining).equals(2) - expect(bucket.used).equals(0) + await bucket.acquire(); + expect(bucket.remaining).equals(1); + expect(bucket.used).equals(1); + await clock.tickAsync(1000); + expect(bucket.remaining).equals(2); + expect(bucket.used).equals(0); - await bucket.acquire() - await clock.tickAsync(1000) - }) + await bucket.acquire(); + await clock.tickAsync(1000); + }); it('bucket refills when refill amount is < max', async () => { const bucket = new LeakyBucket({ max: 3, refillInterval: 800, refillAmount: 1, - }) + }); - await bucket.acquire() - await bucket.acquire() - expect(bucket.remaining).equals(1) - expect(bucket.used).equals(2) - await clock.tickAsync(1000) - expect(bucket.remaining).equals(2) - expect(bucket.used).equals(1) + await bucket.acquire(); + await bucket.acquire(); + expect(bucket.remaining).equals(1); + expect(bucket.used).equals(2); + await clock.tickAsync(1000); + expect(bucket.remaining).equals(2); + expect(bucket.used).equals(1); - await clock.tickAsync(2000) - expect(bucket.remaining).equals(3) - expect(bucket.used).equals(0) - }) + await clock.tickAsync(2000); + expect(bucket.remaining).equals(3); + expect(bucket.used).equals(0); + }); it('bucket refills when refill interval is slow', async () => { const bucket = new LeakyBucket({ max: 1, refillInterval: 500, refillAmount: 1, - }) + }); - const acquired1 = bucket.acquire() - const acquired2 = bucket.acquire() + const acquired1 = bucket.acquire(); + const acquired2 = bucket.acquire(); // js event loop - await (async () => {})() + await (async () => {})(); - expect(await promiseState(acquired1)).to.equal('fulfilled') - expect(await promiseState(acquired2)).to.equal('pending') + expect(await promiseState(acquired1)).to.equal('fulfilled'); + expect(await promiseState(acquired2)).to.equal('pending'); - await clock.tickAsync(499) - expect(await promiseState(acquired2)).to.equal('pending') + await clock.tickAsync(499); + expect(await promiseState(acquired2)).to.equal('pending'); - await clock.tickAsync(1) - expect(await promiseState(acquired2)).to.equal('fulfilled') + await clock.tickAsync(1); + expect(await promiseState(acquired2)).to.equal('fulfilled'); - expect(bucket.remaining).equals(0) - expect(bucket.used).equals(1) - }) + expect(bucket.remaining).equals(0); + expect(bucket.used).equals(1); + }); describe('remaining', () => { it('should be 0 even used too many', () => { @@ -176,23 +176,23 @@ describe('bucket.ts', () => { max: 1, refillInterval: 500, refillAmount: 1, - }) + }); // max is < used - bucket.used = 2 - expect(bucket.remaining).equals(0) - }) - }) + bucket.used = 2; + expect(bucket.remaining).equals(0); + }); + }); it("Don't process queue twice", () => { const bucket = new LeakyBucket({ max: 1, refillInterval: 500, refillAmount: 1, - }) + }); // fake processing - bucket.processing = true + bucket.processing = true; // request when already processing - bucket.processQueue() - }) - }) -}) + bucket.processQueue(); + }); + }); +}); diff --git a/packages/utils/tests/builders.spec.ts b/packages/utils/tests/builders.spec.ts index 9ab640507..d67243c61 100644 --- a/packages/utils/tests/builders.spec.ts +++ b/packages/utils/tests/builders.spec.ts @@ -1,34 +1,34 @@ -import { expect } from 'chai' -import { describe, it } from 'mocha' -import { EmbedsBuilder } from '../src/builders.js' +import { expect } from 'chai'; +import { describe, it } from 'mocha'; +import { EmbedsBuilder } from '../src/builders.js'; describe('builders/embeds.ts', () => { it('should create a new blank embed JSON', () => { - expect(new EmbedsBuilder().newEmbed()).to.eql([{}]) - }) + expect(new EmbedsBuilder().newEmbed()).to.eql([{}]); + }); it('should set the author name in the embed JSON', () => { - expect(new EmbedsBuilder().setAuthor('Author')).to.eql([{ author: { name: 'Author' } }]) - }) + expect(new EmbedsBuilder().setAuthor('Author')).to.eql([{ author: { name: 'Author' } }]); + }); it('should set the color in the embed JSON', () => { - expect(new EmbedsBuilder().setColor('#000000')).to.eql([{ color: 0 }]) - expect(new EmbedsBuilder().setColor('#21fa99')).to.eql([{ color: 2226841 }]) - expect(new EmbedsBuilder().setColor('#thisisnotacolor')).to.eql([{ color: 0 }]) - expect(new EmbedsBuilder().setColor(13530)).to.eql([{ color: 13530 }]) - }) + expect(new EmbedsBuilder().setColor('#000000')).to.eql([{ color: 0 }]); + expect(new EmbedsBuilder().setColor('#21fa99')).to.eql([{ color: 2226841 }]); + expect(new EmbedsBuilder().setColor('#thisisnotacolor')).to.eql([{ color: 0 }]); + expect(new EmbedsBuilder().setColor(13530)).to.eql([{ color: 13530 }]); + }); it('should set the description in the embed JSON', () => { - expect(new EmbedsBuilder().setDescription('My Description')).to.eql([{ description: 'My Description' }]) - }) + expect(new EmbedsBuilder().setDescription('My Description')).to.eql([{ description: 'My Description' }]); + }); it('should add a field in the embed JSON', () => { expect(new EmbedsBuilder().addField('firstname', 'firstvalue')).to.eql([ { fields: [{ name: 'firstname', value: 'firstvalue', inline: undefined }], }, - ]) - }) + ]); + }); it('should set the fields in the embed JSON', () => { expect( @@ -43,8 +43,8 @@ describe('builders/embeds.ts', () => { { name: 'secondname', value: 'secondvalue', inline: true }, ], }, - ]) - }) + ]); + }); it('should add the fields in the embed JSON', () => { expect( @@ -60,28 +60,28 @@ describe('builders/embeds.ts', () => { { name: 'thirdname', value: 'thirdvalue', inline: true }, ], }, - ]) - }) + ]); + }); it('should set the footer text in the embed JSON', () => { - expect(new EmbedsBuilder().setFooter('footer text')).to.eql([{ footer: { text: 'footer text' } }]) - }) + expect(new EmbedsBuilder().setFooter('footer text')).to.eql([{ footer: { text: 'footer text' } }]); + }); it('should set the set a random color in the embed JSON', () => { - expect(new EmbedsBuilder().setRandomColor()[0]).to.haveOwnProperty('color') - }) + expect(new EmbedsBuilder().setRandomColor()[0]).to.haveOwnProperty('color'); + }); it('should set the timestamp in the embed JSON', () => { - const now = new Date() + const now = new Date(); - expect(new EmbedsBuilder().setTimestamp(now)).to.eql([{ timestamp: now.toISOString() }]) - }) + expect(new EmbedsBuilder().setTimestamp(now)).to.eql([{ timestamp: now.toISOString() }]); + }); it('should set the title in the embed JSON', () => { - expect(new EmbedsBuilder().setTitle('My Title')).to.eql([{ title: 'My Title' }]) - }) + expect(new EmbedsBuilder().setTitle('My Title')).to.eql([{ title: 'My Title' }]); + }); it('should set the url in the embed JSON', () => { - expect(new EmbedsBuilder().setUrl('https://google.com')).to.eql([{ url: 'https://google.com' }]) - }) -}) + expect(new EmbedsBuilder().setUrl('https://google.com')).to.eql([{ url: 'https://google.com' }]); + }); +}); diff --git a/packages/utils/tests/casting.spec.ts b/packages/utils/tests/casting.spec.ts index fe137e5c1..d2a45a8b3 100644 --- a/packages/utils/tests/casting.spec.ts +++ b/packages/utils/tests/casting.spec.ts @@ -1,6 +1,6 @@ -import { expect } from 'chai' -import { describe, it } from 'mocha' -import { camelize, snakelize, snakeToCamelCase } from '../src/casing.js' +import { expect } from 'chai'; +import { describe, it } from 'mocha'; +import { camelize, snakelize, snakeToCamelCase } from '../src/casing.js'; describe('casting.ts', () => { describe('camelize function', () => { @@ -15,8 +15,8 @@ describe('casting.ts', () => { testAxByCz: 'dummy_dx_ey_fz', testgxhyiz: 'dummyjxkylz', 32: 'adw_dw', - }) - }) + }); + }); it('will convert array of snake case object to camel case object', () => { expect( @@ -35,15 +35,15 @@ describe('casting.ts', () => { { testGxHyIz: 'dummy_jx_ky_lz', }, - ]) - }) + ]); + }); describe('snakeToCamelCase function', () => { it('will convert string snake case to camel case', () => { - expect(snakeToCamelCase('sd_sd')).to.equal('sdSd') - }) - }) - }) + expect(snakeToCamelCase('sd_sd')).to.equal('sdSd'); + }); + }); + }); describe('snakelize function', () => { it('will convert snake case object to camel case object', () => { @@ -57,8 +57,8 @@ describe('casting.ts', () => { test_ax_by_cz: 'dummy_dx_ey_fz', testgxhyiz: 'dummyjxkylz', 32: 'adw_dw', - }) - }) + }); + }); it('will convert array of snake case object to camel case object', () => { expect( @@ -77,13 +77,13 @@ describe('casting.ts', () => { { test_gx_hy_iz: 'dummy_jx_ky_lz', }, - ]) - }) + ]); + }); describe('snakeToCamelCase function', () => { it('will convert string snake case to camel case', () => { - expect(snakeToCamelCase('sd_sd')).to.equal('sdSd') - }) - }) - }) -}) + expect(snakeToCamelCase('sd_sd')).to.equal('sdSd'); + }); + }); + }); +}); diff --git a/packages/utils/tests/collection.spec.ts b/packages/utils/tests/collection.spec.ts index f2c47c829..14a89fb00 100644 --- a/packages/utils/tests/collection.spec.ts +++ b/packages/utils/tests/collection.spec.ts @@ -1,75 +1,75 @@ -import { expect } from 'chai' -import { afterEach, beforeEach, describe, it } from 'mocha' -import sinon from 'sinon' -import { Collection } from '../src/Collection.js' +import { expect } from 'chai'; +import { afterEach, beforeEach, describe, it } from 'mocha'; +import sinon from 'sinon'; +import { Collection } from '../src/Collection.js'; describe('collection.ts', () => { afterEach(() => { - sinon.restore() - }) + sinon.restore(); + }); describe('Collection class', () => { - let collection: Collection + let collection: Collection; beforeEach(() => { collection = new Collection([ ['best', 'tri'], ['proficient', 'yui'], - ]) - }) + ]); + }); describe('.array() method', () => { it('will return values as array', () => { - expect(collection.array()).to.be.deep.equal(['tri', 'yui']) - }) - }) + expect(collection.array()).to.be.deep.equal(['tri', 'yui']); + }); + }); describe('.random() method', () => { it('will get a random value', () => { - expect(collection.random() ?? '').to.be.oneOf(['tri', 'yui']) - expect(new Collection().random()).to.be.undefined - }) - }) + expect(collection.random() ?? '').to.be.oneOf(['tri', 'yui']); + expect(new Collection().random()).to.be.undefined; + }); + }); describe('.set() method', () => { describe('without maxSize', () => { it('will set a value', () => { - collection.set('best developer', 'triformine') + collection.set('best developer', 'triformine'); - expect(collection.size).to.be.equal(3) - expect(collection.get('best developer')).to.be.equal('triformine') - }) - }) + expect(collection.size).to.be.equal(3); + expect(collection.get('best developer')).to.be.equal('triformine'); + }); + }); describe('with maxSize', () => { - const maxSize = 2 + const maxSize = 2; beforeEach(() => { collection = new Collection([], { maxSize, - }) - }) + }); + }); it('will set a value when not over max size', () => { - collection.set('foo', 'bar') - collection.set('me', 'you') + collection.set('foo', 'bar'); + collection.set('me', 'you'); - expect(collection.size).to.be.equal(2) - }) + expect(collection.size).to.be.equal(2); + }); it('will not set a value when over max size', () => { - collection.set('foo', 'bar') - collection.set('me', 'you') - expect(collection.size).to.be.equal(2) + collection.set('foo', 'bar'); + collection.set('me', 'you'); + expect(collection.size).to.be.equal(2); - collection.set('this', 'not') - expect(collection.size).to.be.equal(2) - }) - }) - }) + collection.set('this', 'not'); + expect(collection.size).to.be.equal(2); + }); + }); + }); describe('.forceSet() method', () => { - const maxSize = 2 + const maxSize = 2; beforeEach(() => { collection = new Collection( @@ -78,85 +78,85 @@ describe('collection.ts', () => { ['me', 'you'], ], { maxSize }, - ) - }) + ); + }); it('will ignore maxSize and set a value ', () => { - collection.forceSet('this', 'not') + collection.forceSet('this', 'not'); - expect(collection.size).to.be.equal(3) - }) - }) + expect(collection.size).to.be.equal(3); + }); + }); describe('.first() method', () => { it('will get the value of the first element', () => { - expect(collection.first()).to.be.equal('tri') - }) - }) + expect(collection.first()).to.be.equal('tri'); + }); + }); describe('.last() method', () => { it('get the value of the last element', () => { - expect(collection.last()).to.be.equal('yui') - }) - }) + expect(collection.last()).to.be.equal('yui'); + }); + }); const testCollection = new Collection([ ['a', 1], ['b', 2], ['c', 3], - ]) + ]); describe('.find() method', () => { it('will find value by value', () => { - expect(collection.find((v) => v === 'tri')).to.be.equal('tri') - expect(collection.find((v) => v === 'skillz')).to.be.undefined - }) + expect(collection.find((v) => v === 'tri')).to.be.equal('tri'); + expect(collection.find((v) => v === 'skillz')).to.be.undefined; + }); it('will find value by key', () => { - expect(collection.find((_v, k) => k === 'proficient')).to.be.equal('yui') - expect(collection.find((_v, k) => k === 'skillz')).to.be.undefined - }) - }) + expect(collection.find((_v, k) => k === 'proficient')).to.be.equal('yui'); + expect(collection.find((_v, k) => k === 'skillz')).to.be.undefined; + }); + }); describe('.filter() method', () => { it('will filter by key', () => { - expect(collection.filter((v) => v === 'yui').array()).to.deep.equal(['yui']) - expect(collection.filter((v) => v === 'skillz').array()).to.deep.equal([]) - }) + expect(collection.filter((v) => v === 'yui').array()).to.deep.equal(['yui']); + expect(collection.filter((v) => v === 'skillz').array()).to.deep.equal([]); + }); it('will filter by key', () => { - expect(collection.filter((_v, k) => k === 'best').array()).to.deep.equal(['tri']) - expect(collection.filter((_v, k) => k === 'skillz').array()).to.deep.equal([]) - }) - }) + expect(collection.filter((_v, k) => k === 'best').array()).to.deep.equal(['tri']); + expect(collection.filter((_v, k) => k === 'skillz').array()).to.deep.equal([]); + }); + }); it('map', () => { - expect(testCollection.map((k, v) => `${v}${k}`)).to.be.deep.equal(['a1', 'b2', 'c3']) - }) + expect(testCollection.map((k, v) => `${v}${k}`)).to.be.deep.equal(['a1', 'b2', 'c3']); + }); it('some', () => { - expect(testCollection.some((v, _) => v === 1)).to.be.equal(true) - expect(testCollection.some((v, _) => v === 4)).to.be.equal(false) - }) + expect(testCollection.some((v, _) => v === 1)).to.be.equal(true); + expect(testCollection.some((v, _) => v === 4)).to.be.equal(false); + }); it('every', () => { - expect(testCollection.every((v, _) => v !== 0)).to.be.equal(true) - expect(testCollection.every((v, _) => v === 1)).to.be.equal(false) - }) + expect(testCollection.every((v, _) => v !== 0)).to.be.equal(true); + expect(testCollection.every((v, _) => v === 1)).to.be.equal(false); + }); it('reduce', () => { - expect(testCollection.reduce((acc, val) => acc + val, 0)).to.be.equal(6) - }) + expect(testCollection.reduce((acc, val) => acc + val, 0)).to.be.equal(6); + }); describe('sweeper', () => { - let clock: sinon.SinonFakeTimers + let clock: sinon.SinonFakeTimers; beforeEach(() => { - clock = sinon.useFakeTimers() - }) + clock = sinon.useFakeTimers(); + }); afterEach(() => { - clock.restore() - }) + clock.restore(); + }); it('start sweeper', async () => { const sweeperCollection = new Collection( @@ -170,49 +170,49 @@ describe('collection.ts', () => { interval: 50, }, }, - ) + ); try { - await clock.tickAsync(49) - expect(sweeperCollection.size).to.be.equal(2) - await clock.tickAsync(1) - expect(sweeperCollection.size).to.be.equal(1) + await clock.tickAsync(49); + expect(sweeperCollection.size).to.be.equal(2); + await clock.tickAsync(1); + expect(sweeperCollection.size).to.be.equal(1); } catch (err) { - sweeperCollection.stopSweeper() + sweeperCollection.stopSweeper(); - throw err + throw err; } - sweeperCollection.stopSweeper() - }) + sweeperCollection.stopSweeper(); + }); describe('.changeSweeperInterval() method', () => { it('will call startSweeper with new interval', () => { - collection.startSweeper({ filter: () => false, interval: 1000 }) - collection.changeSweeperInterval(20000) - expect(collection.sweeper?.interval).to.equal(20000) - }) + collection.startSweeper({ filter: () => false, interval: 1000 }); + collection.changeSweeperInterval(20000); + expect(collection.sweeper?.interval).to.equal(20000); + }); it('will not startsweeper if not started', () => { - collection.changeSweeperInterval(20000) - expect(collection.sweeper).to.undefined - }) - }) + collection.changeSweeperInterval(20000); + expect(collection.sweeper).to.undefined; + }); + }); describe('.changeSweeperFilter() method', () => { it('will call startSweeper with new interval', () => { - const newFilter = () => true - collection.startSweeper({ filter: () => false, interval: 1000 }) - collection.changeSweeperFilter(newFilter) - expect(collection.sweeper?.filter).to.equal(newFilter) - }) + const newFilter = () => true; + collection.startSweeper({ filter: () => false, interval: 1000 }); + collection.changeSweeperFilter(newFilter); + expect(collection.sweeper?.filter).to.equal(newFilter); + }); it('will not startsweeper if not started', () => { - const newFilter = () => true - collection.changeSweeperFilter(newFilter) - expect(collection.sweeper).to.undefined - }) - }) - }) - }) -}) + const newFilter = () => true; + collection.changeSweeperFilter(newFilter); + expect(collection.sweeper).to.undefined; + }); + }); + }); + }); +}); diff --git a/packages/utils/tests/color.spec.ts b/packages/utils/tests/color.spec.ts index dc1d2ac61..8b6e5f964 100644 --- a/packages/utils/tests/color.spec.ts +++ b/packages/utils/tests/color.spec.ts @@ -1,38 +1,38 @@ -import { expect } from 'chai' -import { describe, it } from 'mocha' -import * as colors from '../src/colors.js' +import { expect } from 'chai'; +import { describe, it } from 'mocha'; +import * as colors from '../src/colors.js'; -const arrayOfColors = ['black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white'] +const arrayOfColors = ['black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white']; describe('Colors', () => { it(`Color functions will return colored word`, () => { for (const [index, color] of arrayOfColors.entries()) { - const value = (colors[color as keyof typeof colors] as typeof colors.black)('testWord') - expect(value).equals(`\x1B[${30 + index}mtestWord\x1B[39m`) + const value = (colors[color as keyof typeof colors] as typeof colors.black)('testWord'); + expect(value).equals(`\x1B[${30 + index}mtestWord\x1B[39m`); - const brightName = `bright${color.slice(0, 1).toUpperCase()}${color.slice(1)}` - const brightValue = (colors[brightName as keyof typeof colors] as typeof colors.black)('testWord') - expect(brightValue).to.equal(`\x1B[${90 + index}mtestWord\x1B[39m`) + const brightName = `bright${color.slice(0, 1).toUpperCase()}${color.slice(1)}`; + const brightValue = (colors[brightName as keyof typeof colors] as typeof colors.black)('testWord'); + expect(brightValue).to.equal(`\x1B[${90 + index}mtestWord\x1B[39m`); - const bgName = `bg${color.slice(0, 1).toUpperCase()}${color.slice(1)}` - const bgValue = (colors[bgName as keyof typeof colors] as typeof colors.black)('testWord') - expect(bgValue).to.equal(`\x1B[${40 + index}mtestWord\x1B[49m`, `Color ${color} has failed .`) + const bgName = `bg${color.slice(0, 1).toUpperCase()}${color.slice(1)}`; + const bgValue = (colors[bgName as keyof typeof colors] as typeof colors.black)('testWord'); + expect(bgValue).to.equal(`\x1B[${40 + index}mtestWord\x1B[49m`, `Color ${color} has failed .`); - const bgBrightName = `bgBright${color.slice(0, 1).toUpperCase()}${color.slice(1)}` - const bgBrightValue = (colors[bgBrightName as keyof typeof colors] as typeof colors.black)('testWord') - expect(bgBrightValue).to.equal(`\x1B[${100 + index}mtestWord\x1B[49m`) + const bgBrightName = `bgBright${color.slice(0, 1).toUpperCase()}${color.slice(1)}`; + const bgBrightValue = (colors[bgBrightName as keyof typeof colors] as typeof colors.black)('testWord'); + expect(bgBrightValue).to.equal(`\x1B[${100 + index}mtestWord\x1B[49m`); } - }) + }); it('Will return grey colored word', () => { - expect(colors.gray('testWord')).to.equal(`\x1B[${90}mtestWord\x1B[39m`) - }) + expect(colors.gray('testWord')).to.equal(`\x1B[${90}mtestWord\x1B[39m`); + }); it('Set and get colors enabled value', () => { - expect(colors.getColorEnabled()).to.equal(true) - colors.setColorEnabled(false) - expect(colors.getColorEnabled()).to.equal(false) - colors.setColorEnabled(true) - expect(colors.getColorEnabled()).to.equal(true) - }) -}) + expect(colors.getColorEnabled()).to.equal(true); + colors.setColorEnabled(false); + expect(colors.getColorEnabled()).to.equal(false); + colors.setColorEnabled(true); + expect(colors.getColorEnabled()).to.equal(true); + }); +}); diff --git a/packages/utils/tests/hash.spec.ts b/packages/utils/tests/hash.spec.ts index 0b71e93d8..870cfd4c9 100644 --- a/packages/utils/tests/hash.spec.ts +++ b/packages/utils/tests/hash.spec.ts @@ -1,26 +1,26 @@ -import { expect } from 'chai' -import { describe, it } from 'mocha' -import { iconBigintToHash, iconHashToBigInt } from '../src/hash.js' +import { expect } from 'chai'; +import { describe, it } from 'mocha'; +import { iconBigintToHash, iconHashToBigInt } from '../src/hash.js'; -const iconHash = '4bbb271a13f7195031adcc06a2d867ce' -const iconBigInt = 3843769888406823508519992434416504301518n -const a_iconHash = 'a_4bbb271a13f7195031adcc06a2d867ce' -const a_iconBigInt = 3503487521485885045056617826984736090062n +const iconHash = '4bbb271a13f7195031adcc06a2d867ce'; +const iconBigInt = 3843769888406823508519992434416504301518n; +const a_iconHash = 'a_4bbb271a13f7195031adcc06a2d867ce'; +const a_iconBigInt = 3503487521485885045056617826984736090062n; describe('hash.ts', () => { it('[utils] icon hash to bigint', () => { - expect(iconHashToBigInt(iconHash)).to.be.equal(iconBigInt) - }) + expect(iconHashToBigInt(iconHash)).to.be.equal(iconBigInt); + }); it('[utils] icon bigint to hash', () => { - expect(iconBigintToHash(iconBigInt)).to.be.equal(iconHash) - }) + expect(iconBigintToHash(iconBigInt)).to.be.equal(iconHash); + }); it('[utils] icon hash to bigint a_ (animated)', () => { - expect(iconHashToBigInt(a_iconHash)).to.be.equal(a_iconBigInt) - }) + expect(iconHashToBigInt(a_iconHash)).to.be.equal(a_iconBigInt); + }); it('[utils] icon bigint to hash a_ (animated)', () => { - expect(iconBigintToHash(a_iconBigInt)).to.be.equal(a_iconHash) - }) -}) + expect(iconBigintToHash(a_iconBigInt)).to.be.equal(a_iconHash); + }); +}); diff --git a/packages/utils/tests/images.spec.ts b/packages/utils/tests/images.spec.ts index 156cdde87..b23669282 100644 --- a/packages/utils/tests/images.spec.ts +++ b/packages/utils/tests/images.spec.ts @@ -1,5 +1,5 @@ -import { expect } from 'chai' -import { describe, it } from 'mocha' +import { expect } from 'chai'; +import { describe, it } from 'mocha'; import { avatarUrl, defaultAvatarUrl, @@ -10,196 +10,196 @@ import { guildBannerUrl, guildIconUrl, guildSplashUrl, -} from '../src/images.js' +} from '../src/images.js'; describe('images.ts', () => { describe('formatImageUrl function', () => { it('will return formated url with default size 128 and webp', () => { - expect(formatImageUrl('https://skillz.is.pro/image')).to.be.equal('https://skillz.is.pro/image.webp?size=128') - }) + expect(formatImageUrl('https://skillz.is.pro/image')).to.be.equal('https://skillz.is.pro/image.webp?size=128'); + }); it('will return formated url with given size', () => { - expect(formatImageUrl('https://skillz.is.pro/image', 1024)).to.be.equal('https://skillz.is.pro/image.webp?size=1024') - }) + expect(formatImageUrl('https://skillz.is.pro/image', 1024)).to.be.equal('https://skillz.is.pro/image.webp?size=1024'); + }); it('will return formated url with given size and format', () => { - expect(formatImageUrl('https://skillz.is.pro/image', 1024, 'gif')).to.be.equal('https://skillz.is.pro/image.gif?size=1024') - }) + expect(formatImageUrl('https://skillz.is.pro/image', 1024, 'gif')).to.be.equal('https://skillz.is.pro/image.gif?size=1024'); + }); it('will return formated url with default size and format', () => { - expect(formatImageUrl('https://skillz.is.pro/image', undefined, 'gif')).to.be.equal('https://skillz.is.pro/image.gif?size=128') - }) + expect(formatImageUrl('https://skillz.is.pro/image', undefined, 'gif')).to.be.equal('https://skillz.is.pro/image.gif?size=128'); + }); describe('without format', () => { it('will use gif if a_ is found', () => { expect(formatImageUrl('https://cdn.discordapp.com/avatars/568505543511259840/a_482491d6dcf12e12746ccd3148f0c646')).to.be.equal( 'https://cdn.discordapp.com/avatars/568505543511259840/a_482491d6dcf12e12746ccd3148f0c646.gif?size=128', - ) - }) + ); + }); it('will use webp if no a_ is found', () => { expect(formatImageUrl('https://cdn.discordapp.com/avatars/568505543511259840/482491d6dcf12e12746ccd3148f0c646')).to.be.equal( 'https://cdn.discordapp.com/avatars/568505543511259840/482491d6dcf12e12746ccd3148f0c646.webp?size=128', - ) - }) - }) - }) + ); + }); + }); + }); describe('emojiUrl function', () => { it('can format emoji url with png as default ext', () => { - expect(emojiUrl('1079823706743918622')).to.equal('https://cdn.discordapp.com/emojis/1079823706743918622.png') - }) + expect(emojiUrl('1079823706743918622')).to.equal('https://cdn.discordapp.com/emojis/1079823706743918622.png'); + }); it('can format emoji url with gif as ext', () => { - expect(emojiUrl('1079584570661404724', true)).to.equal('https://cdn.discordapp.com/emojis/1079584570661404724.gif') - }) + expect(emojiUrl('1079584570661404724', true)).to.equal('https://cdn.discordapp.com/emojis/1079584570661404724.gif'); + }); it('can format emoji url with webp as ext', () => { - expect(emojiUrl('1079823706743918622', false, 'webp')).to.equal('https://cdn.discordapp.com/emojis/1079823706743918622.webp') - }) + expect(emojiUrl('1079823706743918622', false, 'webp')).to.equal('https://cdn.discordapp.com/emojis/1079823706743918622.webp'); + }); it('can format emoji url with webp as ext when animated', () => { - expect(emojiUrl('1079823706743918622', true, 'webp')).to.equal('https://cdn.discordapp.com/emojis/1079823706743918622.webp?animated=true') - }) - }) + expect(emojiUrl('1079823706743918622', true, 'webp')).to.equal('https://cdn.discordapp.com/emojis/1079823706743918622.webp?animated=true'); + }); + }); describe('avatarUrl function', () => { it('will return the url for given avatar icon hash', () => { expect(avatarUrl('207324334904049664', 'db26a6fb924c985f66b79364cf5797b7')).to.equal( 'https://cdn.discordapp.com/avatars/207324334904049664/db26a6fb924c985f66b79364cf5797b7.webp?size=128', - ) - }) + ); + }); it('will return the url for given avatar icon bigint', () => { expect(avatarUrl('207324334904049664', 4034407661299384404326332419647968090039n)).to.equal( 'https://cdn.discordapp.com/avatars/207324334904049664/db26a6fb924c985f66b79364cf5797b7.webp?size=128', - ) - }) - }) + ); + }); + }); describe('defaultAvatarUrl function', () => { it('will return the url for default avatar', () => { - expect(defaultAvatarUrl('207324334904049664', '9130')).to.equal('https://cdn.discordapp.com/embed/avatars/0.png') - }) - }) + expect(defaultAvatarUrl('207324334904049664', '9130')).to.equal('https://cdn.discordapp.com/embed/avatars/0.png'); + }); + }); describe('displayAvatarUrl function', () => { it('will return the url for given avatar icon hash', () => { expect(displayAvatarUrl('207324334904049664', '9130', 'db26a6fb924c985f66b79364cf5797b7')).to.equal( 'https://cdn.discordapp.com/avatars/207324334904049664/db26a6fb924c985f66b79364cf5797b7.webp?size=128', - ) - }) + ); + }); it('will return the url for given avatar icon bigint', () => { expect(displayAvatarUrl('207324334904049664', '9130', 4034407661299384404326332419647968090039n)).to.equal( 'https://cdn.discordapp.com/avatars/207324334904049664/db26a6fb924c985f66b79364cf5797b7.webp?size=128', - ) - }) + ); + }); it('will return the url for default avatar', () => { - expect(displayAvatarUrl('207324334904049664', '9130', undefined)).to.equal('https://cdn.discordapp.com/embed/avatars/0.png') - }) - }) + expect(displayAvatarUrl('207324334904049664', '9130', undefined)).to.equal('https://cdn.discordapp.com/embed/avatars/0.png'); + }); + }); describe('guildBannerUrl function', () => { it("will return the url for given guild's banner's icon hash", () => { expect(guildBannerUrl('785384884197392384', { banner: '2fc0f64acd7a326e0c93c123db02eb1d' })).to.equal( 'https://cdn.discordapp.com/banners/785384884197392384/2fc0f64acd7a326e0c93c123db02eb1d.webp?size=128', - ) - }) + ); + }); it("will return the url for given guild's banner's icon big int", () => { expect(guildBannerUrl('785384884197392384', { banner: 3806581668328291509506503737571885116189n })).to.equal( 'https://cdn.discordapp.com/banners/785384884197392384/2fc0f64acd7a326e0c93c123db02eb1d.webp?size=128', - ) - }) + ); + }); it("will return the url for given guild's banner with format", () => { expect(guildBannerUrl('785384884197392384', { banner: '2fc0f64acd7a326e0c93c123db02eb1d', format: 'png' })).to.equal( 'https://cdn.discordapp.com/banners/785384884197392384/2fc0f64acd7a326e0c93c123db02eb1d.png?size=128', - ) - }) + ); + }); it("will return the url for given guild's banner with size", () => { expect(guildBannerUrl('785384884197392384', { banner: '2fc0f64acd7a326e0c93c123db02eb1d', size: 256 })).to.equal( 'https://cdn.discordapp.com/banners/785384884197392384/2fc0f64acd7a326e0c93c123db02eb1d.webp?size=256', - ) - }) + ); + }); it('will return undefined without given banner', () => { - expect(guildBannerUrl('785384884197392384', {})).to.equal(undefined) - }) - }) + expect(guildBannerUrl('785384884197392384', {})).to.equal(undefined); + }); + }); describe('guildIconUrl function', () => { it("will return the url for given guild's icon's icon hash", () => { expect(guildIconUrl('785384884197392384', '7cb67c989d54d824239b2bb4270955b1')).to.equal( 'https://cdn.discordapp.com/icons/785384884197392384/7cb67c989d54d824239b2bb4270955b1.webp?size=128', - ) - }) + ); + }); it("will return the url for given guild's icon's icon big int", () => { expect(guildIconUrl('785384884197392384', 3908877832746069276949504774836813649329n)).to.equal( 'https://cdn.discordapp.com/icons/785384884197392384/7cb67c989d54d824239b2bb4270955b1.webp?size=128', - ) - }) + ); + }); it("will return the url for given guild's icon with format", () => { expect(guildIconUrl('785384884197392384', '7cb67c989d54d824239b2bb4270955b1', { format: 'png' })).to.equal( 'https://cdn.discordapp.com/icons/785384884197392384/7cb67c989d54d824239b2bb4270955b1.png?size=128', - ) - }) + ); + }); it("will return the url for given guild's icon with size", () => { expect(guildIconUrl('785384884197392384', '7cb67c989d54d824239b2bb4270955b1', { size: 256 })).to.equal( 'https://cdn.discordapp.com/icons/785384884197392384/7cb67c989d54d824239b2bb4270955b1.webp?size=256', - ) - }) + ); + }); it('will return undefined without given icon', () => { - expect(guildIconUrl('785384884197392384', undefined)).to.equal(undefined) - }) - }) + expect(guildIconUrl('785384884197392384', undefined)).to.equal(undefined); + }); + }); describe('guildSplashUrl function', () => { it("will return the url for given guild's splash's icon big hash", () => { expect(guildSplashUrl('785384884197392384', '207961ff6c41f119874e10efc602858c')).to.equal( 'https://cdn.discordapp.com/splashes/785384884197392384/207961ff6c41f119874e10efc602858c.webp?size=128', - ) - }) + ); + }); it("will return the url for given guild's splash's icon big int", () => { expect(guildSplashUrl('785384884197392384', 3786271587545740215322752847582515594636n)).to.equal( 'https://cdn.discordapp.com/splashes/785384884197392384/207961ff6c41f119874e10efc602858c.webp?size=128', - ) - }) + ); + }); it("will return the url for given guild's splash with format", () => { expect(guildSplashUrl('785384884197392384', '207961ff6c41f119874e10efc602858c', { format: 'png' })).to.equal( 'https://cdn.discordapp.com/splashes/785384884197392384/207961ff6c41f119874e10efc602858c.png?size=128', - ) - }) + ); + }); it("will return the url for given guild's splash with size", () => { expect(guildSplashUrl('785384884197392384', '207961ff6c41f119874e10efc602858c', { size: 2048 })).to.equal( 'https://cdn.discordapp.com/splashes/785384884197392384/207961ff6c41f119874e10efc602858c.webp?size=2048', - ) - }) + ); + }); it('will return undefined without given icon', () => { - expect(guildSplashUrl('785384884197392384', undefined)).to.equal(undefined) - }) - }) + expect(guildSplashUrl('785384884197392384', undefined)).to.equal(undefined); + }); + }); describe('getWidgetImageUrl function', () => { it("will return the url for given guild's widget", () => { - expect(getWidgetImageUrl('785384884197392384')).to.equal('https://discordapp.com/api/guilds/785384884197392384/widget.png') - }) + expect(getWidgetImageUrl('785384884197392384')).to.equal('https://discordapp.com/api/guilds/785384884197392384/widget.png'); + }); it("will return the url for given guild's widget with the style", () => { expect(getWidgetImageUrl('785384884197392384', { style: 'banner2' })).to.equal( 'https://discordapp.com/api/guilds/785384884197392384/widget.png?style=banner2', - ) - }) - }) -}) + ); + }); + }); +}); diff --git a/packages/utils/tests/index.spec.ts b/packages/utils/tests/index.spec.ts index 4cc609818..cf4daa90a 100644 --- a/packages/utils/tests/index.spec.ts +++ b/packages/utils/tests/index.spec.ts @@ -1,7 +1,7 @@ -import { describe, it } from 'mocha' +import { describe, it } from 'mocha'; describe('index.ts', () => { it('will import without error', async () => { - await import('../src/index.js') - }) -}) + await import('../src/index.js'); + }); +}); diff --git a/packages/utils/tests/logger.spec.ts b/packages/utils/tests/logger.spec.ts index a4923c3ff..87f1ed6a7 100644 --- a/packages/utils/tests/logger.spec.ts +++ b/packages/utils/tests/logger.spec.ts @@ -1,32 +1,32 @@ -import { expect } from 'chai' -import { describe, it } from 'mocha' -import { createLogger, LogLevels } from '../src/logger.js' +import { expect } from 'chai'; +import { describe, it } from 'mocha'; +import { createLogger, LogLevels } from '../src/logger.js'; describe('Logger', () => { it('create logger with default options', () => { - const loggy = createLogger() - loggy.setLevel(LogLevels.Debug) - loggy.debug('debugging') - loggy.error('error') - loggy.fatal('fatal') - loggy.info('info') - loggy.warn('warn') + const loggy = createLogger(); + loggy.setLevel(LogLevels.Debug); + loggy.debug('debugging'); + loggy.error('error'); + loggy.fatal('fatal'); + loggy.info('info'); + loggy.warn('warn'); - loggy.debug('debugging') - loggy.error('error') - loggy.fatal('fatal') - loggy.info('info') - loggy.warn('warn') - }) + loggy.debug('debugging'); + loggy.error('error'); + loggy.fatal('fatal'); + loggy.info('info'); + loggy.warn('warn'); + }); it('create logger with a name', () => { - const loggy = createLogger({ name: 'loggy' }) - expect(loggy).to.exist - }) + const loggy = createLogger({ name: 'loggy' }); + expect(loggy).to.exist; + }); it('Handle fake level', () => { - const loggy = createLogger({ name: 'fake level' }) - const level = 123 as LogLevels - loggy.log(level, 'idk') - }) -}) + const loggy = createLogger({ name: 'fake level' }); + const level = 123 as LogLevels; + loggy.log(level, 'idk'); + }); +}); diff --git a/packages/utils/tests/permissions.spec.ts b/packages/utils/tests/permissions.spec.ts index 91b09f3dc..2331ad11a 100644 --- a/packages/utils/tests/permissions.spec.ts +++ b/packages/utils/tests/permissions.spec.ts @@ -1,16 +1,16 @@ -import { expect } from 'chai' -import { describe, it } from 'mocha' -import { calculateBits, calculatePermissions } from '../src/permissions.js' +import { expect } from 'chai'; +import { describe, it } from 'mocha'; +import { calculateBits, calculatePermissions } from '../src/permissions.js'; describe('permissions.ts', () => { describe('calculatePermissions function', () => { it('will return the array of permissions of bitwise string', () => { - expect(calculatePermissions(34393292864n)).to.have.members(['ADD_REACTIONS', 'CREATE_PUBLIC_THREADS', 'USE_VAD']) - }) - }) + expect(calculatePermissions(34393292864n)).to.have.members(['ADD_REACTIONS', 'CREATE_PUBLIC_THREADS', 'USE_VAD']); + }); + }); describe('calculateBits function', () => { it('will return the bitwise string of array of permissions', () => { - expect(calculateBits(['ADD_REACTIONS', 'CREATE_PUBLIC_THREADS', 'USE_VAD'])).to.equal('34393292864') - }) - }) -}) + expect(calculateBits(['ADD_REACTIONS', 'CREATE_PUBLIC_THREADS', 'USE_VAD'])).to.equal('34393292864'); + }); + }); +}); diff --git a/packages/utils/tests/reactions.spec.ts b/packages/utils/tests/reactions.spec.ts index 0c3c90cba..1d6a4e866 100644 --- a/packages/utils/tests/reactions.spec.ts +++ b/packages/utils/tests/reactions.spec.ts @@ -1,20 +1,20 @@ -import { expect } from 'chai' -import { describe, it } from 'mocha' -import { processReactionString } from '../src/reactions.js' +import { expect } from 'chai'; +import { describe, it } from 'mocha'; +import { processReactionString } from '../src/reactions.js'; describe('Reactions', () => { it('Convert a unicode emoji to discord form', () => { - const reaction = processReactionString('😄') - expect(reaction).to.be.equal('😄') - }) + const reaction = processReactionString('😄'); + expect(reaction).to.be.equal('😄'); + }); it('Convert a custom emoji to discord form', () => { - const reaction = processReactionString('<:discordeno:785403373817823272>') - expect(reaction).to.be.equal('discordeno:785403373817823272') - }) + const reaction = processReactionString('<:discordeno:785403373817823272>'); + expect(reaction).to.be.equal('discordeno:785403373817823272'); + }); it('Convert an animated custom emoji to discord form', () => { - const reaction = processReactionString('') - expect(reaction).to.be.equal('discordeno:785403373817823272') - }) -}) + const reaction = processReactionString(''); + expect(reaction).to.be.equal('discordeno:785403373817823272'); + }); +}); diff --git a/packages/utils/tests/token.spec.ts b/packages/utils/tests/token.spec.ts index d2ca1e4e8..fb9d6cddf 100644 --- a/packages/utils/tests/token.spec.ts +++ b/packages/utils/tests/token.spec.ts @@ -1,26 +1,26 @@ -import { Buffer } from 'node:buffer' -import { expect } from 'chai' -import { describe, it } from 'mocha' -import { getBotIdFromToken, removeTokenPrefix } from '../src/token.js' +import { Buffer } from 'node:buffer'; +import { expect } from 'chai'; +import { describe, it } from 'mocha'; +import { getBotIdFromToken, removeTokenPrefix } from '../src/token.js'; describe('token.ts', () => { describe('token function', () => { it('Will remove token prefix when Bot is prefixed.', () => { - expect(removeTokenPrefix('Bot discordeno is best lib')).to.be.equal('discordeno is best lib') - }) + expect(removeTokenPrefix('Bot discordeno is best lib')).to.be.equal('discordeno is best lib'); + }); it('Will remove token prefix when Bot is NOT prefixed.', () => { - expect(removeTokenPrefix('discordeno is best lib')).to.be.equal('discordeno is best lib') - }) + expect(removeTokenPrefix('discordeno is best lib')).to.be.equal('discordeno is best lib'); + }); it('Will throw when token is undefined.', () => { - expect(() => removeTokenPrefix(undefined)).to.throw() - }) - }) + expect(() => removeTokenPrefix(undefined)).to.throw(); + }); + }); describe('getBotIdFromToken function', () => { it('Will get Bot Id from token', () => { - expect(getBotIdFromToken(`${Buffer.from('1033452747380494366').toString('base64')}.zawsxedcrftvgybhu`)).to.equal(1033452747380494366n) - }) - }) -}) + expect(getBotIdFromToken(`${Buffer.from('1033452747380494366').toString('base64')}.zawsxedcrftvgybhu`)).to.equal(1033452747380494366n); + }); + }); +}); diff --git a/packages/utils/tests/typeguards.spec.ts b/packages/utils/tests/typeguards.spec.ts index eefb4d124..9a24493ca 100644 --- a/packages/utils/tests/typeguards.spec.ts +++ b/packages/utils/tests/typeguards.spec.ts @@ -1,6 +1,6 @@ -import { expect } from 'chai' -import { describe, it } from 'mocha' -import { isGetMessagesAfter, isGetMessagesAround, isGetMessagesBefore, isGetMessagesLimit } from '../src/typeguards.js' +import { expect } from 'chai'; +import { describe, it } from 'mocha'; +import { isGetMessagesAfter, isGetMessagesAround, isGetMessagesBefore, isGetMessagesLimit } from '../src/typeguards.js'; describe('typeguard.ts', () => { describe('isGetMessagesAfter function', () => { @@ -9,13 +9,13 @@ describe('typeguard.ts', () => { isGetMessagesAfter({ after: '684146387468463', }), - ).equal(true) - }) + ).equal(true); + }); it("will return false if don't has after", () => { - expect(isGetMessagesAfter({})).equal(false) - }) - }) + expect(isGetMessagesAfter({})).equal(false); + }); + }); describe('isGetMessagesBefore function', () => { it('will return true if has after', () => { @@ -23,13 +23,13 @@ describe('typeguard.ts', () => { isGetMessagesBefore({ before: '684146387468463', }), - ).equal(true) - }) + ).equal(true); + }); it("will return false if don't has after", () => { - expect(isGetMessagesBefore({})).equal(false) - }) - }) + expect(isGetMessagesBefore({})).equal(false); + }); + }); describe('isGetMessagesAround function', () => { it('will return true if has after', () => { @@ -37,13 +37,13 @@ describe('typeguard.ts', () => { isGetMessagesAround({ around: '684146387468463', }), - ).equal(true) - }) + ).equal(true); + }); it("will return false if don't has after", () => { - expect(isGetMessagesAround({})).equal(false) - }) - }) + expect(isGetMessagesAround({})).equal(false); + }); + }); describe('isGetMessagesAfter function', () => { it('will return true if has after', () => { @@ -51,11 +51,11 @@ describe('typeguard.ts', () => { isGetMessagesLimit({ limit: 54, }), - ).equal(true) - }) + ).equal(true); + }); it("will return false if don't has after", () => { - expect(isGetMessagesLimit({})).equal(false) - }) - }) -}) + expect(isGetMessagesLimit({})).equal(false); + }); + }); +}); diff --git a/packages/utils/tests/urlToBase64.spec.ts b/packages/utils/tests/urlToBase64.spec.ts index d48c0760b..b1a9a3a04 100644 --- a/packages/utils/tests/urlToBase64.spec.ts +++ b/packages/utils/tests/urlToBase64.spec.ts @@ -1,30 +1,30 @@ -import { expect } from 'chai' -import { afterEach, beforeEach, describe, it } from 'mocha' -import sinon from 'sinon' -import { urlToBase64 } from '../src/urlToBase64.js' +import { expect } from 'chai'; +import { afterEach, beforeEach, describe, it } from 'mocha'; +import sinon from 'sinon'; +import { urlToBase64 } from '../src/urlToBase64.js'; describe('urlToBase64.ts', () => { - let fetchStub: sinon.SinonStub + let fetchStub: sinon.SinonStub; beforeEach(() => { - fetchStub = sinon.stub(globalThis, 'fetch') - }) + fetchStub = sinon.stub(globalThis, 'fetch'); + }); afterEach(() => { - sinon.restore() - }) + sinon.restore(); + }); describe('urlToBase64 function', () => { it('Will convert a png image to base64', async () => { - const mockArrayBuffer = new ArrayBuffer(8) + const mockArrayBuffer = new ArrayBuffer(8); fetchStub.resolves({ arrayBuffer: () => Promise.resolve(mockArrayBuffer), - }) + }); - const url = await urlToBase64('https://example.com/image.png') + const url = await urlToBase64('https://example.com/image.png'); - expect(url).equal('data:image/png;base64,AAAAAAAAAAA=') - }) - }) -}) + expect(url).equal('data:image/png;base64,AAAAAAAAAAA='); + }); + }); +}); diff --git a/packages/utils/tests/utils.spec.ts b/packages/utils/tests/utils.spec.ts index fe388d2f9..dd7751243 100644 --- a/packages/utils/tests/utils.spec.ts +++ b/packages/utils/tests/utils.spec.ts @@ -1,52 +1,52 @@ -import { expect } from 'chai' -import { afterEach, beforeEach, describe, it } from 'mocha' -import sinon from 'sinon' -import { delay, hasProperty, jsonSafeReplacer } from '../src/utils.js' +import { expect } from 'chai'; +import { afterEach, beforeEach, describe, it } from 'mocha'; +import sinon from 'sinon'; +import { delay, hasProperty, jsonSafeReplacer } from '../src/utils.js'; describe('utils.ts', () => { - let clock: sinon.SinonFakeTimers + let clock: sinon.SinonFakeTimers; beforeEach(() => { - clock = sinon.useFakeTimers() - }) + clock = sinon.useFakeTimers(); + }); afterEach(() => { - sinon.restore() - clock.restore() - }) + sinon.restore(); + clock.restore(); + }); describe('jsonSafe function', () => { it('will convert records to `JSON.stringify`-serializable', () => { // Example from issue#4196: https://github.com/discordeno/discordeno/issues/4196. - const value = { limit: 0, userIds: [0n, 0n, 0n] } - const expected = { limit: 0, userIds: ['0', '0', '0'] } - expect(JSON.stringify(value, jsonSafeReplacer)).equal(JSON.stringify(expected)) - }) - }) + const value = { limit: 0, userIds: [0n, 0n, 0n] }; + const expected = { limit: 0, userIds: ['0', '0', '0'] }; + expect(JSON.stringify(value, jsonSafeReplacer)).equal(JSON.stringify(expected)); + }); + }); describe('delay function', () => { it('will delay/sleep for given time', async () => { - let delayEnded = false + let delayEnded = false; delay(31).then(() => { - delayEnded = true - }) - expect(delayEnded).to.be.false - await clock.tickAsync(30) - expect(delayEnded).to.be.false - await clock.tickAsync(31) - expect(delayEnded).to.be.true - }) - }) + delayEnded = true; + }); + expect(delayEnded).to.be.false; + await clock.tickAsync(30); + expect(delayEnded).to.be.false; + await clock.tickAsync(31); + expect(delayEnded).to.be.true; + }); + }); describe('hasProperty funciton', async () => { - const obj = { prop: 'lts372005' } + const obj = { prop: 'lts372005' }; it('will return true if it does have property', () => { - expect(hasProperty(obj, 'prop')).equal(true) - }) + expect(hasProperty(obj, 'prop')).equal(true); + }); it('will return false if it does not have property', () => { - expect(hasProperty(obj, 'lts372005')).equal(false) - }) - }) -}) + expect(hasProperty(obj, 'lts372005')).equal(false); + }); + }); +}); diff --git a/scripts/bumpVersionByCommit.js b/scripts/bumpVersionByCommit.js index 9ce75006d..45c02e239 100644 --- a/scripts/bumpVersionByCommit.js +++ b/scripts/bumpVersionByCommit.js @@ -1,36 +1,36 @@ -import { execSync } from 'node:child_process' -import { readFile, writeFile } from 'node:fs/promises' +import { execSync } from 'node:child_process'; +import { readFile, writeFile } from 'node:fs/promises'; -const packageName = process.argv[2] +const packageName = process.argv[2]; if (!packageName) { - throw new Error('No package name specified') + throw new Error('No package name specified'); } -const commitHash = execSync('git rev-parse HEAD').toString().slice(0, 7) +const commitHash = execSync('git rev-parse HEAD').toString().slice(0, 7); -const file = JSON.parse(await readFile(`packages/${packageName}/package.json`, 'utf-8')) +const file = JSON.parse(await readFile(`packages/${packageName}/package.json`, 'utf-8')); -const version = file.version.split('-')[0] +const version = file.version.split('-')[0]; -file.version = `${bumpPatch(version)}-next.${commitHash}` +file.version = `${bumpPatch(version)}-next.${commitHash}`; if (file.dependencies) { Object.keys(file.dependencies).forEach((dependency) => { - if (dependency.startsWith('@discordeno/')) file.dependencies[dependency] = file.version - }) + if (dependency.startsWith('@discordeno/')) file.dependencies[dependency] = file.version; + }); } -await writeFile(`packages/${packageName}/package.json`, JSON.stringify(file, null, 2)) +await writeFile(`packages/${packageName}/package.json`, JSON.stringify(file, null, 2)); -console.log(`Bumped ${packageName} to ${file.version}`) +console.log(`Bumped ${packageName} to ${file.version}`); function bumpPatch(version) { - const parts = version.split('.').map(Number) + const parts = version.split('.').map(Number); if (parts.length !== 3 || parts.some(isNaN)) { - throw new Error('Invalid semver format. Expected format "MAJOR.MINOR.PATCH"') + throw new Error('Invalid semver format. Expected format "MAJOR.MINOR.PATCH"'); } - parts[2] += 1 - return parts.join('.') + parts[2] += 1; + return parts.join('.'); } diff --git a/scripts/checkCpuModel.js b/scripts/checkCpuModel.js index 8557387b6..c135d41ae 100644 --- a/scripts/checkCpuModel.js +++ b/scripts/checkCpuModel.js @@ -1,12 +1,12 @@ -import fs from 'node:fs' -import os from 'node:os' +import fs from 'node:fs'; +import os from 'node:os'; -const hostCpu = os.cpus()[0].model.trim() +const hostCpu = os.cpus()[0].model.trim(); const targetCpu = await fetch('https://raw.githubusercontent.com/discordeno/discordeno/benchies/cpu') .then(async (res) => await res.text()) - .then((text) => text.slice(0, -1)) -console.dir(`host cpu: ${hostCpu} target cpu: ${targetCpu}`) + .then((text) => text.slice(0, -1)); +console.dir(`host cpu: ${hostCpu} target cpu: ${targetCpu}`); -let outputFile = fs.readFileSync(process.env.GITHUB_OUTPUT, 'utf8') -outputFile += `\nmatch=${hostCpu === targetCpu}` -fs.writeFileSync(process.env.GITHUB_OUTPUT, outputFile, 'utf8') +let outputFile = fs.readFileSync(process.env.GITHUB_OUTPUT, 'utf8'); +outputFile += `\nmatch=${hostCpu === targetCpu}`; +fs.writeFileSync(process.env.GITHUB_OUTPUT, outputFile, 'utf8'); diff --git a/scripts/coveragePathFixing.js b/scripts/coveragePathFixing.js index b0d3b923f..d6ec62a41 100644 --- a/scripts/coveragePathFixing.js +++ b/scripts/coveragePathFixing.js @@ -1,3 +1,3 @@ -import { readFileSync, writeFileSync } from 'node:fs' +import { readFileSync, writeFileSync } from 'node:fs'; -writeFileSync('./coverage/lcov.info', readFileSync('./coverage/lcov.info', 'utf-8').replace(/SF:src/g, `SF:packages/${process.argv[2]}/src`)) +writeFileSync('./coverage/lcov.info', readFileSync('./coverage/lcov.info', 'utf-8').replace(/SF:src/g, `SF:packages/${process.argv[2]}/src`)); diff --git a/scripts/generateMessage.js b/scripts/generateMessage.js index d506751e6..2eb0b2557 100644 --- a/scripts/generateMessage.js +++ b/scripts/generateMessage.js @@ -1,56 +1,56 @@ -import fs from 'node:fs/promises' +import fs from 'node:fs/promises'; const benchmarkData = await fetch(`https://raw.githubusercontent.com/discordeno/discordeno/benchies/benchmarksResult/data.js`) .then(async (res) => await res.text()) - .then((text) => JSON.parse(text.slice(24))) + .then((text) => JSON.parse(text.slice(24))); // const commitSha = await fs.readFile('./sha', 'utf-8') -const results = JSON.parse(await fs.readFile('./data.json', 'utf-8')) -const benchmarks = results.entries.Benchmark -benchmarks.reverse() -const compareWithHead = {} -const latestBaseBenchmarks = benchmarkData.entries.Benchmark.slice(-1)[0] +const results = JSON.parse(await fs.readFile('./data.json', 'utf-8')); +const benchmarks = results.entries.Benchmark; +benchmarks.reverse(); +const compareWithHead = {}; +const latestBaseBenchmarks = benchmarkData.entries.Benchmark.slice(-1)[0]; for (const benchmark of latestBaseBenchmarks.benches) { compareWithHead[benchmark.name] = { [latestBaseBenchmarks.commit.id]: benchmark, - } + }; } for (let i = benchmarks.length - 1; i >= 0; i--) { for (const bench of benchmarks[i].benches) { if (compareWithHead[bench.name]) { - compareWithHead[bench.name][benchmarks[i].commit.id] = bench + compareWithHead[bench.name][benchmarks[i].commit.id] = bench; } else { compareWithHead[bench.name] = { [benchmarks[i].commit.id]: bench, - } + }; } } } -let message = '\n' -message += `## Benchmark\n\n` -message += '
Detail results of benchmarks\n\n' -let header1 = `| Benchmark suite | Base (${latestBaseBenchmarks.commit.id}) |` -let header2 = `|-|-|` -const commitIds = benchmarks.map((benchmark) => benchmark.commit.id) -const uniqueCommitIds = commitIds.filter((benchmarkCommitId, index) => commitIds.indexOf(benchmarkCommitId) === index) +let message = '\n'; +message += `## Benchmark\n\n`; +message += '
Detail results of benchmarks\n\n'; +let header1 = `| Benchmark suite | Base (${latestBaseBenchmarks.commit.id}) |`; +let header2 = `|-|-|`; +const commitIds = benchmarks.map((benchmark) => benchmark.commit.id); +const uniqueCommitIds = commitIds.filter((benchmarkCommitId, index) => commitIds.indexOf(benchmarkCommitId) === index); for (const [index, commitId] of uniqueCommitIds.entries()) { - header1 += index === 0 ? ` Latest Head (${commitId}) |` : ` ${commitId} |` - header2 += '-|' + header1 += index === 0 ? ` Latest Head (${commitId}) |` : ` ${commitId} |`; + header2 += '-|'; } -message += `${header1}\n` -message += `${header2}\n` +message += `${header1}\n`; +message += `${header2}\n`; for (const benchName of Object.keys(compareWithHead)) { - let benchData = `| ${benchName} |` + let benchData = `| ${benchName} |`; benchData += compareWithHead[benchName][latestBaseBenchmarks.commit.id] ? ` ${`\`${compareWithHead[benchName][latestBaseBenchmarks.commit.id].value}\` ${ compareWithHead[benchName][latestBaseBenchmarks.commit.id].unit } \`${compareWithHead[benchName][latestBaseBenchmarks.commit.id].range}\``} |` - : '|' + : '|'; for (const commitId of uniqueCommitIds) { benchData += compareWithHead[benchName][commitId] ? ` \`${compareWithHead[benchName][commitId].value}\` ${compareWithHead[benchName][commitId].unit} \`${compareWithHead[benchName][commitId].range}\`|` - : '|' + : '|'; } - message += `${benchData}\n` + message += `${benchData}\n`; } -message += '
\n\n' -console.log(message.replaceAll('`', '\\`')) +message += '
\n\n'; +console.log(message.replaceAll('`', '\\`')); diff --git a/scripts/openApiSchema.js b/scripts/openApiSchema.js index 9757b2a7a..0a6ee9827 100644 --- a/scripts/openApiSchema.js +++ b/scripts/openApiSchema.js @@ -1,58 +1,58 @@ /* eslint-disable @typescript-eslint/explicit-function-return-type */ /* eslint-disable @typescript-eslint/no-unsafe-argument */ -import fs from 'fs' +import fs from 'fs'; // TODO: replace with fetch of live spec -const DISCORD_SPEC = {} +const DISCORD_SPEC = {}; function schemaRefToName(ref) { - if (!ref) return '' - return `Discord${ref?.substring(ref.lastIndexOf('/') + 1)}` + if (!ref) return ''; + return `Discord${ref?.substring(ref.lastIndexOf('/') + 1)}`; } function snakeToPascalCase(str) { - if (!str.includes('_')) return str + if (!str.includes('_')) return str; - let result = '' + let result = ''; for (let i = 0, len = str.length; i < len; ++i) { if (str[i] === '_') { - result += str[++i].toUpperCase() + result += str[++i].toUpperCase(); - continue + continue; } - result += str[i] + result += str[i]; } - return result + return result; } function generateFromSpec() { - const finalTypings = [] + const finalTypings = []; for (const [key, schema] of Object.entries(DISCORD_SPEC.components.schemas)) { - const interfacey = [`export interface Discord${key} {`] + const interfacey = [`export interface Discord${key} {`]; if (schema.properties) { for (const [name, property] of Object.entries(schema.properties)) { - const type = Array.isArray(property.type) ? property.type : property.type ? [property.type] : undefined - let ref = property.$ref && schemaRefToName(property.$ref) - let allOf = property.allOf?.find((a) => a.$ref) + const type = Array.isArray(property.type) ? property.type : property.type ? [property.type] : undefined; + let ref = property.$ref && schemaRefToName(property.$ref); + let allOf = property.allOf?.find((a) => a.$ref); if (allOf) { - allOf = schemaRefToName(allOf.$ref) + allOf = schemaRefToName(allOf.$ref); } - const isArray = property.type === 'array' + const isArray = property.type === 'array'; if (isArray) { - if (property.items.$ref) ref = schemaRefToName(property.items.$ref) + if (property.items.$ref) ref = schemaRefToName(property.items.$ref); else if (Array.isArray(property.oneOf)) { - ref = property.oneOf.map((o) => schemaRefToName(o.$ref)).join(' | ') + ref = property.oneOf.map((o) => schemaRefToName(o.$ref)).join(' | '); } } if (property.description) { - interfacey.push(` /** ${property.description} */`) + interfacey.push(` /** ${property.description} */`); } let cleanType = @@ -83,17 +83,17 @@ function generateFromSpec() { : undefined) ?? schemaRefToName(o.$ref), ) .join(' | ') ?? - 'unknown' + 'unknown'; - if (cleanType.startsWith('null | ')) cleanType = cleanType.substring(cleanType.indexOf('|') + 2) + ' | null' - interfacey.push(` ${name}${schema.required?.includes(name) ? ':' : '?:'} ${cleanType}`) + if (cleanType.startsWith('null | ')) cleanType = cleanType.substring(cleanType.indexOf('|') + 2) + ' | null'; + interfacey.push(` ${name}${schema.required?.includes(name) ? ':' : '?:'} ${cleanType}`); } } else { // No properties so is enum if (['integer', 'string'].includes(schema.type) && Array.isArray(schema.oneOf)) { - const enumm = [`export enum Discord${key} {`] + const enumm = [`export enum Discord${key} {`]; for (const possible of schema.oneOf) { - if (possible.description) enumm.push(` /** ${possible.description} */`) + if (possible.description) enumm.push(` /** ${possible.description} */`); // TODO: camel case the title enumm.push( ` ${possible.title.includes('-') ? '"' : ''}${snakeToPascalCase( @@ -101,26 +101,26 @@ function generateFromSpec() { )}${possible.title.includes('-') ? '"' : ''} = ${schema.type === 'string' ? '"' : ''}${possible.const}${ schema.type === 'string' ? '"' : '' },`, - ) + ); } - enumm.push('}') + enumm.push('}'); - finalTypings.push(enumm.join('\n')) - continue + finalTypings.push(enumm.join('\n')); + continue; } - console.log('NO PROPERTIES', key, schema) - continue + console.log('NO PROPERTIES', key, schema); + continue; } - interfacey.push('}') + interfacey.push('}'); - finalTypings.push(interfacey.join('\n')) + finalTypings.push(interfacey.join('\n')); } fs.writeFileSync('./packages/types/src/discord.ts', finalTypings.join('\n\n'), function (err, _result) { - if (err) throw err - }) + if (err) throw err; + }); } -generateFromSpec() +generateFromSpec(); diff --git a/website/docusaurus.config.ts b/website/docusaurus.config.ts index b1535720f..a4478fcdd 100644 --- a/website/docusaurus.config.ts +++ b/website/docusaurus.config.ts @@ -1,8 +1,8 @@ -import type { Options as ClientRedirectOptions } from '@docusaurus/plugin-client-redirects' -import type { Options as PluginContentDocs } from '@docusaurus/plugin-content-docs' -import type { Options as PresetClassicOptions, ThemeConfig } from '@docusaurus/preset-classic' -import type { Config } from '@docusaurus/types' -import { themes } from 'prism-react-renderer' +import type { Options as ClientRedirectOptions } from '@docusaurus/plugin-client-redirects'; +import type { Options as PluginContentDocs } from '@docusaurus/plugin-content-docs'; +import type { Options as PresetClassicOptions, ThemeConfig } from '@docusaurus/preset-classic'; +import type { Config } from '@docusaurus/types'; +import { themes } from 'prism-react-renderer'; const config: Config = { title: 'Discordeno', @@ -235,6 +235,6 @@ const config: Config = { } satisfies ClientRedirectOptions, ], ], -} +}; -export default config +export default config; diff --git a/website/sidebars.ts b/website/sidebars.ts index 16ac8a1bb..d04904a9c 100644 --- a/website/sidebars.ts +++ b/website/sidebars.ts @@ -9,7 +9,7 @@ Create as many sidebars as you want. */ -import type { SidebarsConfig } from '@docusaurus/plugin-content-docs' +import type { SidebarsConfig } from '@docusaurus/plugin-content-docs'; const sidebars: SidebarsConfig = { // By default, Docusaurus generates a sidebar from the docs folder structure @@ -27,6 +27,6 @@ const sidebars: SidebarsConfig = { }, ], */ -} +}; -export default sidebars +export default sidebars; diff --git a/website/src/components/architecture/BaseFlowChart.tsx b/website/src/components/architecture/BaseFlowChart.tsx index 6e7252316..668f13fb0 100644 --- a/website/src/components/architecture/BaseFlowChart.tsx +++ b/website/src/components/architecture/BaseFlowChart.tsx @@ -1,26 +1,26 @@ -import { useColorMode } from '@docusaurus/theme-common' -import { Background, Controls, type Edge, Handle, type Node, Position, ReactFlow, useEdgesState, useNodesState } from '@xyflow/react' -import '@xyflow/react/dist/style.css' +import { useColorMode } from '@docusaurus/theme-common'; +import { Background, Controls, type Edge, Handle, type Node, Position, ReactFlow, useEdgesState, useNodesState } from '@xyflow/react'; +import '@xyflow/react/dist/style.css'; -export const multiplier = 225 -export const height = 40 +export const multiplier = 225; +export const height = 40; export const defaultNodeOptions = { targetPosition: Position.Left, sourcePosition: Position.Right, draggable: false, style: { width: `${multiplier * 0.75}px`, height: `${height}px` }, -} +}; export const defaultGroupOptions = { draggable: false, -} +}; export default function BaseFlowChart({ initialNodes = [], initialEdges = [] }: { initialNodes: Node[]; initialEdges: Edge[] }) { - const [nodes] = useNodesState(initialNodes) - const [edges] = useEdgesState(initialEdges) + const [nodes] = useNodesState(initialNodes); + const [edges] = useEdgesState(initialEdges); - const color = useColorMode() + const color = useColorMode(); return ( <> @@ -73,5 +73,5 @@ export default function BaseFlowChart({ initialNodes = [], initialEdges = [] }: - ) + ); } diff --git a/website/src/components/architecture/FlowChart.tsx b/website/src/components/architecture/FlowChart.tsx index 57fa5e45b..a1ae7f17c 100644 --- a/website/src/components/architecture/FlowChart.tsx +++ b/website/src/components/architecture/FlowChart.tsx @@ -1,6 +1,6 @@ -import type { Edge, Node } from '@xyflow/react' -import '@xyflow/react/dist/style.css' -import BaseFlowChart, { defaultNodeOptions, multiplier } from './BaseFlowChart' +import type { Edge, Node } from '@xyflow/react'; +import '@xyflow/react/dist/style.css'; +import BaseFlowChart, { defaultNodeOptions, multiplier } from './BaseFlowChart'; const initialNodes: Node[] = [ { @@ -119,7 +119,7 @@ const initialNodes: Node[] = [ data: { label: 'Discord Api' }, ...defaultNodeOptions, }, -] +]; const initialEdges: Edge[] = [ { id: 'd-g', source: 'discordGateway', target: 'gateway' }, @@ -155,8 +155,8 @@ const initialEdges: Edge[] = [ style: { stroke: 'blue', strokeDasharray: 20 }, animated: false, }, -] +]; export default function FlowChart() { - return + return ; } diff --git a/website/src/components/architecture/FlowChart2.tsx b/website/src/components/architecture/FlowChart2.tsx index 43838e93b..b230d1de1 100644 --- a/website/src/components/architecture/FlowChart2.tsx +++ b/website/src/components/architecture/FlowChart2.tsx @@ -1,6 +1,6 @@ -import { type Edge, type Node, Position } from '@xyflow/react' -import '@xyflow/react/dist/style.css' -import BaseFlowChart, { defaultGroupOptions, defaultNodeOptions, multiplier } from './BaseFlowChart' +import { type Edge, type Node, Position } from '@xyflow/react'; +import '@xyflow/react/dist/style.css'; +import BaseFlowChart, { defaultGroupOptions, defaultNodeOptions, multiplier } from './BaseFlowChart'; const initialNodes: Node[] = [ { @@ -164,7 +164,7 @@ const initialNodes: Node[] = [ data: { label: 'Bot' }, ...defaultNodeOptions, }, -] +]; const initialEdges: Edge[] = [ { id: 'd-g', source: 'discordGateway', target: 'gateway' }, @@ -296,8 +296,8 @@ const initialEdges: Edge[] = [ target: 'shard-n', zIndex: 100, }, -] +]; export default function FlowChart2() { - return + return ; } diff --git a/website/src/components/architecture/FlowChart3.tsx b/website/src/components/architecture/FlowChart3.tsx index 1e425228f..ee53aaf10 100644 --- a/website/src/components/architecture/FlowChart3.tsx +++ b/website/src/components/architecture/FlowChart3.tsx @@ -1,15 +1,15 @@ -import { useColorMode } from '@docusaurus/theme-common' -import { Background, Controls, type Edge, Handle, type Node, Position, ReactFlow, useEdgesState, useNodesState } from '@xyflow/react' -import type React from 'react' -import { useEffect, useState } from 'react' -import '@xyflow/react/dist/style.css' -import { defaultNodeOptions, height, multiplier } from './BaseFlowChart' +import { useColorMode } from '@docusaurus/theme-common'; +import { Background, Controls, type Edge, Handle, type Node, Position, ReactFlow, useEdgesState, useNodesState } from '@xyflow/react'; +import type React from 'react'; +import { useEffect, useState } from 'react'; +import '@xyflow/react/dist/style.css'; +import { defaultNodeOptions, height, multiplier } from './BaseFlowChart'; const handlers: Record< string, { - transformers: string[] - event: string + transformers: string[]; + event: string; } > = { handleChannelCreate: { @@ -28,11 +28,11 @@ const handlers: Record< transformers: ['transformers.channel'], event: 'events.channelUpdate', }, -} +}; export default function FlowChart() { - const transformers = [] - const events = [] + const transformers = []; + const events = []; const initialNodes: Node[] = [ { id: 'baseNode-gateway', @@ -96,7 +96,7 @@ export default function FlowChart() { data: { label: 'Handle discord payload' }, ...defaultNodeOptions, }, - ] + ]; const initialEdges: Edge[] = [ { @@ -122,9 +122,9 @@ export default function FlowChart() { target: 'baseLineNode-4', style: { stroke: 'blue', strokeDasharray: 20 }, }, - ] + ]; - const handlerKeys = Object.keys(handlers) + const handlerKeys = Object.keys(handlers); for (const [index, handler] of handlerKeys.entries()) { initialNodes.push({ @@ -135,35 +135,35 @@ export default function FlowChart() { }, data: { label: handler }, ...defaultNodeOptions, - }) + }); initialEdges.push({ id: `handleDiscordPayload-${handler}`, source: 'baseNode-handleDiscordPayload', target: handler, - }) + }); if (!events.find((e) => e === handlers[handler].event) && handlers[handler].event) { - events.push(handlers[handler].event) + events.push(handlers[handler].event); initialEdges.push({ id: `${handlers[handler].event}-yourCode`, source: handlers[handler].event, target: 'baseNode-yourCode', - }) + }); } for (const transformer of handlers[handler].transformers) { - if (!transformers.find((t) => t === transformer) && transformer) transformers.push(transformer) + if (!transformers.find((t) => t === transformer) && transformer) transformers.push(transformer); if (!initialEdges.find((edge) => edge.id === `${handler}-${transformer}`) && transformer) { initialEdges.push({ id: `${handler}-${transformer}`, source: handler, target: transformer, - }) + }); } if (!initialEdges.find((edge) => edge.id === `${transformer}-${handlers[handler].event}`) && handlers[handler].event) { initialEdges.push({ id: `${transformer}-${handlers[handler].event}`, source: transformer, target: handlers[handler].event, - }) + }); } } } @@ -177,7 +177,7 @@ export default function FlowChart() { }, data: { label: transformer.slice(13) }, ...defaultNodeOptions, - }) + }); } for (const [index, event] of events.entries()) { @@ -189,7 +189,7 @@ export default function FlowChart() { }, data: { label: event.slice(7) }, ...defaultNodeOptions, - }) + }); } initialNodes.unshift( @@ -268,137 +268,137 @@ export default function FlowChart() { data: { label: 'Event' }, draggable: false, }, - ) + ); - const [nodes] = useNodesState(initialNodes) - const [edges, setEdges] = useEdgesState(initialEdges) - const [userClick, setUserClick] = useState(false) + const [nodes] = useNodesState(initialNodes); + const [edges, setEdges] = useEdgesState(initialEdges); + const [userClick, setUserClick] = useState(false); const nodeMouseHandler = (_: React.MouseEvent, node: Node, userTrigger = true) => { - if (userTrigger) setUserClick(true) + if (userTrigger) setUserClick(true); if (node.id.split('-')[0] === 'baseNode') { edges.forEach((e) => { - if (e.id.startsWith('baseLine')) return - e.animated = true - e.style = { stroke: 'blue' } - }) - setEdges([...edges]) - return + if (e.id.startsWith('baseLine')) return; + e.animated = true; + e.style = { stroke: 'blue' }; + }); + setEdges([...edges]); + return; } if (handlerKeys.find((h) => handlers[h].event === node.id)) { - const handlerName = handlerKeys.find((h) => handlers[h].event === node.id) - const handler = handlers[handlerName] + const handlerName = handlerKeys.find((h) => handlers[h].event === node.id); + const handler = handlers[handlerName]; edges.forEach((e) => { - if (e.id.startsWith('baseLine')) return + if (e.id.startsWith('baseLine')) return; if (e.id.split('-')[0] === 'baseEdge') { - e.animated = true - e.style = { stroke: 'blue' } - return + e.animated = true; + e.style = { stroke: 'blue' }; + return; } if (e.id.split('-')[0] === 'handleDiscordPayload' && e.id.split('-')[1] === handlerName) { - e.animated = true - e.style = { stroke: 'blue' } - return + e.animated = true; + e.style = { stroke: 'blue' }; + return; } if (e.id.split('-')[0] === handlerName && handler.transformers.includes(e.id.split('-')[1])) { - e.animated = true - e.style = { stroke: 'blue' } - return + e.animated = true; + e.style = { stroke: 'blue' }; + return; } if (handler.transformers.includes(e.id.split('-')[0]) && e.id.split('-')[1] === handler.event) { - e.animated = true - e.style = { stroke: 'blue' } - return + e.animated = true; + e.style = { stroke: 'blue' }; + return; } if (e.id.split('-')[0] === handler.event && e.id.split('-')[1] === 'yourCode') { - e.animated = true - e.style = { stroke: 'blue' } - return + e.animated = true; + e.style = { stroke: 'blue' }; + return; } - e.animated = false - e.style = { opacity: 0.3 } - }) - setEdges([...edges]) - return + e.animated = false; + e.style = { opacity: 0.3 }; + }); + setEdges([...edges]); + return; } if (handlerKeys.find((h) => handlers[h].transformers.includes(node.id))) { edges.forEach((e) => { - if (e.id.startsWith('baseLine')) return + if (e.id.startsWith('baseLine')) return; if (e.id.split('-')[0] === 'baseEdge') { - e.animated = true - e.style = { stroke: 'blue' } - return + e.animated = true; + e.style = { stroke: 'blue' }; + return; } if ( e.id.split('-')[0] === 'handleDiscordPayload' && handlerKeys.filter((h) => handlers[h].transformers.includes(node.id)).includes(e.id.split('-')[1]) ) { - e.animated = true - e.style = { stroke: 'blue' } - return + e.animated = true; + e.style = { stroke: 'blue' }; + return; } if (handlerKeys.filter((h) => handlers[h].transformers.includes(node.id)).includes(e.id.split('-')[0]) && e.id.split('-')[1] === node.id) { - e.animated = true - e.style = { stroke: 'blue' } - return + e.animated = true; + e.style = { stroke: 'blue' }; + return; } if (e.id.split('-')[0] === node.id) { - e.animated = true - e.style = { stroke: 'blue' } - return + e.animated = true; + e.style = { stroke: 'blue' }; + return; } - e.animated = false - e.style = { opacity: 0.3 } - }) - setEdges([...edges]) - return + e.animated = false; + e.style = { opacity: 0.3 }; + }); + setEdges([...edges]); + return; } if (handlers[node.id]) { - const handler = handlers[node.id] + const handler = handlers[node.id]; edges.forEach((e) => { - if (e.id.startsWith('baseLine')) return + if (e.id.startsWith('baseLine')) return; if (e.id.split('-')[0] === 'baseEdge') { - e.animated = true - e.style = { stroke: 'blue' } - return + e.animated = true; + e.style = { stroke: 'blue' }; + return; } if (e.id.split('-')[0] === 'handleDiscordPayload' && e.id.split('-')[1] === node.id) { - e.animated = true - e.style = { stroke: 'blue' } - return + e.animated = true; + e.style = { stroke: 'blue' }; + return; } if (e.id.split('-')[0] === node.id && handler.transformers.includes(e.id.split('-')[1])) { - e.animated = true - e.style = { stroke: 'blue' } - return + e.animated = true; + e.style = { stroke: 'blue' }; + return; } if (handler.transformers.includes(e.id.split('-')[0]) && e.id.split('-')[1] === handler.event) { - e.animated = true - e.style = { stroke: 'blue' } - return + e.animated = true; + e.style = { stroke: 'blue' }; + return; } if (e.id.split('-')[0] === handler.event) { - e.animated = true - e.style = { stroke: 'blue' } - return + e.animated = true; + e.style = { stroke: 'blue' }; + return; } - e.animated = false - e.style = { opacity: 0.3 } - }) - setEdges([...edges]) - return + e.animated = false; + e.style = { opacity: 0.3 }; + }); + setEdges([...edges]); + return; } edges.forEach((e) => { - if (e.id.startsWith('baseLine')) return - e.animated = false - e.style = {} - }) - setEdges([...edges]) - } + if (e.id.startsWith('baseLine')) return; + e.animated = false; + e.style = {}; + }); + setEdges([...edges]); + }; useEffect(() => { const interval = setInterval(() => { - const randomIndex = Math.round((handlerKeys.length - 1) * Math.random()) + const randomIndex = Math.round((handlerKeys.length - 1) * Math.random()); if (!userClick) { nodeMouseHandler( undefined, @@ -408,26 +408,26 @@ export default function FlowChart() { position: undefined, }, false, - ) + ); } - }, 1000) + }, 1000); return () => { - clearInterval(interval) - } - }, [userClick]) + clearInterval(interval); + }; + }, [userClick]); useEffect(() => { if (userClick) { const timeout = setTimeout(() => { - setUserClick(false) - }, 10000) + setUserClick(false); + }, 10000); return () => { - clearTimeout(timeout) - } + clearTimeout(timeout); + }; } - }, [userClick]) + }, [userClick]); - const color = useColorMode() + const color = useColorMode(); return ( <> @@ -444,14 +444,14 @@ export default function FlowChart() { onNodeDoubleClick={nodeMouseHandler} onNodeClick={nodeMouseHandler} onClick={(e) => { - const target = e.target as HTMLDivElement + const target = e.target as HTMLDivElement; if (target.className === 'react-flow__pane') { nodeMouseHandler(e, { id: ' - ', data: { label: ' - ' }, position: undefined, - }) + }); } }} nodeTypes={{ @@ -493,5 +493,5 @@ export default function FlowChart() { - ) + ); } diff --git a/website/src/components/architecture/FlowChart4.tsx b/website/src/components/architecture/FlowChart4.tsx index 0e2dcc479..4de04a650 100644 --- a/website/src/components/architecture/FlowChart4.tsx +++ b/website/src/components/architecture/FlowChart4.tsx @@ -1,6 +1,6 @@ -import type { Edge, Node } from '@xyflow/react' -import '@xyflow/react/dist/style.css' -import BaseFlowChart, { defaultNodeOptions, multiplier } from './BaseFlowChart' +import type { Edge, Node } from '@xyflow/react'; +import '@xyflow/react/dist/style.css'; +import BaseFlowChart, { defaultNodeOptions, multiplier } from './BaseFlowChart'; const initialNodes: Node[] = [ { @@ -72,7 +72,7 @@ const initialNodes: Node[] = [ position: { x: 2.75 * multiplier, y: -200 }, data: { label: 'Discord' }, }, -] +]; const initialEdges: Edge[] = [ { id: 'bp-rp', source: 'bot', target: 'rest' }, @@ -100,8 +100,8 @@ const initialEdges: Edge[] = [ style: { stroke: 'blue', strokeDasharray: 20 }, animated: false, }, -] +]; export default function FlowChart4() { - return + return ; } diff --git a/website/src/components/bigbotguide/GatewayFlowChart.tsx b/website/src/components/bigbotguide/GatewayFlowChart.tsx index 2d172b62f..1c1ce3d7b 100644 --- a/website/src/components/bigbotguide/GatewayFlowChart.tsx +++ b/website/src/components/bigbotguide/GatewayFlowChart.tsx @@ -1,12 +1,12 @@ -import { Background, Controls, type Edge, type Node, Position, ReactFlow } from '@xyflow/react' -import '@xyflow/react/dist/style.css' +import { Background, Controls, type Edge, type Node, Position, ReactFlow } from '@xyflow/react'; +import '@xyflow/react/dist/style.css'; export const defaultNodeOptions = { targetPosition: Position.Top, sourcePosition: Position.Bottom, draggable: false, style: { width: '70px', height: '50px', padding: '10px 0' }, -} +}; const genServer = (x: number, id: number) => { const server: Node[] = [ @@ -15,7 +15,7 @@ const genServer = (x: number, id: number) => { data: { label: `Server ${id + 1}` }, position: { x: x - 42.5, y: 100 }, }, - ] + ]; for (let i = 0; i < 4; i++) { if (i === 2) { @@ -36,8 +36,8 @@ const genServer = (x: number, id: number) => { label: '.....', }, }, - ) - continue + ); + continue; } server.push( ...[ @@ -65,11 +65,11 @@ const genServer = (x: number, id: number) => { }, }, ], - ) + ); } - return server -} + return server; +}; const nodes = [ { @@ -89,7 +89,7 @@ const nodes = [ label: '...............', }, }, -] +]; const edges: Edge[] = [ { id: 'gwm-s1', source: 'gwm', target: 's1', type: 'step' }, @@ -113,10 +113,10 @@ const edges: Edge[] = [ { id: 'w451-w451s', source: 'w451', target: 'w451s', type: 'step' }, { id: 'w452-w452s', source: 'w452', target: 'w452s', type: 'step' }, { id: 'w500-w500s', source: 'w500', target: 'w500s', type: 'step' }, -] +]; function Flow() { - const colorMode = document.documentElement.dataset['theme'] || 'light' + const colorMode = document.documentElement.dataset['theme'] || 'light'; return (
@@ -142,7 +142,7 @@ function Flow() {
- ) + ); } -export default Flow +export default Flow; diff --git a/website/src/components/footer/index.tsx b/website/src/components/footer/index.tsx index 36f1eb376..6f6f1de7e 100644 --- a/website/src/components/footer/index.tsx +++ b/website/src/components/footer/index.tsx @@ -13,5 +13,5 @@ export default function Footer() { d="M0,96L34.3,85.3C68.6,75,137,53,206,64C274.3,75,343,117,411,138.7C480,160,549,160,617,170.7C685.7,181,754,203,823,186.7C891.4,171,960,117,1029,112C1097.1,107,1166,149,1234,144C1302.9,139,1371,85,1406,58.7L1440,32L1440,320L1405.7,320C1371.4,320,1303,320,1234,320C1165.7,320,1097,320,1029,320C960,320,891,320,823,320C754.3,320,686,320,617,320C548.6,320,480,320,411,320C342.9,320,274,320,206,320C137.1,320,69,320,34,320L0,320Z" > - ) + ); } diff --git a/website/src/components/header/index.tsx b/website/src/components/header/index.tsx index 3540c9ced..f636d5eb6 100644 --- a/website/src/components/header/index.tsx +++ b/website/src/components/header/index.tsx @@ -1,5 +1,5 @@ -import Link from '@docusaurus/Link' -import style from './index.module.css' +import Link from '@docusaurus/Link'; +import style from './index.module.css'; export default function DiscordenoHeader() { return ( @@ -16,5 +16,5 @@ export default function DiscordenoHeader() { - ) + ); } diff --git a/website/src/components/home/faq/index.tsx b/website/src/components/home/faq/index.tsx index 55c5f8efc..12165bfb4 100644 --- a/website/src/components/home/faq/index.tsx +++ b/website/src/components/home/faq/index.tsx @@ -1,12 +1,12 @@ -import { useState } from 'react' -import style from './index.module.css' +import { useState } from 'react'; +import style from './index.module.css'; const Faq = ({ question, answer, defaultExpanded }: { question: string; answer: string; defaultExpanded?: boolean }) => { - const [visible, setVisible] = useState(defaultExpanded ?? false) + const [visible, setVisible] = useState(defaultExpanded ?? false); const toggleVisibility = () => { - setVisible(!visible) - } + setVisible(!visible); + }; return (
@@ -28,8 +28,8 @@ const Faq = ({ question, answer, defaultExpanded }: { question: string; answer:
- ) -} + ); +}; const questions = [ { @@ -53,7 +53,7 @@ const questions = [ answer: "Yes! While Discordeno itself does not use classes, you can still use classes in your own code by using one of the many libraries or frameworks that provide class-based abstractions on top of Discordeno. Some examples of such libraries include the Discordeno.js which provides a very similar framework and API to Discord.js, or the Sinf library that provides a similar API to Eris library. These libraries provide classes and other abstractions that can help simplify the development of your bot, while still leveraging the power and flexibility of Discordeno's underlying object-based API. Make sure to check the documentation of these libraries for more information on how to use them in your bot.", }, -] +]; export default function DiscordenoFAQ() { return ( @@ -67,5 +67,5 @@ export default function DiscordenoFAQ() { - ) + ); } diff --git a/website/src/components/home/features/feature.tsx b/website/src/components/home/features/feature.tsx index b1616900e..7752dd82c 100644 --- a/website/src/components/home/features/feature.tsx +++ b/website/src/components/home/features/feature.tsx @@ -1,4 +1,4 @@ -import type { FeatureList } from '@site/src/types' +import type { FeatureList } from '@site/src/types'; export default function Feature({ data }: FeatureList) { return ( @@ -10,5 +10,5 @@ export default function Feature({ data }: FeatureList) { {data.feature.description} - ) + ); } diff --git a/website/src/components/home/features/index.tsx b/website/src/components/home/features/index.tsx index 91f369f11..355c5dbe2 100644 --- a/website/src/components/home/features/index.tsx +++ b/website/src/components/home/features/index.tsx @@ -1,6 +1,6 @@ -import type { FeatureItem } from '@site/src/types' -import Feature from './feature' -import styles from './index.module.css' +import type { FeatureItem } from '@site/src/types'; +import Feature from './feature'; +import styles from './index.module.css'; const FeatureList: FeatureItem[] = [ { @@ -107,7 +107,7 @@ const FeatureList: FeatureItem[] = [ ), }, -] +]; export default function DiscordenoFeatures() { return ( @@ -126,5 +126,5 @@ export default function DiscordenoFeatures() { - ) + ); } diff --git a/website/src/components/home/reviews/index.tsx b/website/src/components/home/reviews/index.tsx index 494ecd929..d70b9d62d 100644 --- a/website/src/components/home/reviews/index.tsx +++ b/website/src/components/home/reviews/index.tsx @@ -1,5 +1,5 @@ -import { DiscordLibraries, type IReview } from '@site/src/types' -import style from './index.module.css' +import { DiscordLibraries, type IReview } from '@site/src/types'; +import style from './index.module.css'; const reviewList: IReview[] = [ { @@ -82,7 +82,7 @@ const reviewList: IReview[] = [ guild_count: 211000, }, }, -] +]; export default function DiscordenoReviews() { return ( @@ -94,7 +94,7 @@ export default function DiscordenoReviews() {
{reviewList .sort((a, b) => { - return b.bot.guild_count - a.bot.guild_count + return b.bot.guild_count - a.bot.guild_count; }) .map((review) => (
@@ -202,5 +202,5 @@ export default function DiscordenoReviews() {
- ) + ); } diff --git a/website/src/pages/index.tsx b/website/src/pages/index.tsx index 081ed94e6..72b9c6570 100644 --- a/website/src/pages/index.tsx +++ b/website/src/pages/index.tsx @@ -1,9 +1,9 @@ -import Layout from '@theme/Layout' -import Footer from '../components/footer' -import DiscordenoHeader from '../components/header' -import DiscordenoFAQ from '../components/home/faq' -import DiscordenoFeatures from '../components/home/features' -import DiscordenoReviews from '../components/home/reviews' +import Layout from '@theme/Layout'; +import Footer from '../components/footer'; +import DiscordenoHeader from '../components/header'; +import DiscordenoFAQ from '../components/home/faq'; +import DiscordenoFeatures from '../components/home/features'; +import DiscordenoReviews from '../components/home/reviews'; export default function Home(): React.JSX.Element { return ( @@ -16,5 +16,5 @@ export default function Home(): React.JSX.Element {