diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 9c03e674b..914d025bc 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,9 +1,9 @@ --- name: Bug report about: Create a report to help us improve -title: "" +title: '' labels: bug -assignees: "" +assignees: '' --- **Describe the bug** A clear and concise description of what the bug is. @@ -11,10 +11,10 @@ assignees: "" **To Reproduce** Write a small mod.ts example to replicate the behavior. ```ts -import { createBot, startBot } from "https://deno.land/x/discordeno/mod.ts"; +import { createBot, startBot } from 'https://deno.land/x/discordeno/mod.ts' -const token = "DO NOT PUT TOKEN HERE!!!"; -const botId = BigInt(atob(TOKEN.split(".")[0])); +const token = 'DO NOT PUT TOKEN HERE!!!' +const botId = BigInt(atob(TOKEN.split('.')[0])) const bot = createBot({ token, @@ -23,9 +23,9 @@ const bot = createBot({ // ADD EVENTS NEEDED TO SHOW THE BUG HERE }, intents: 0, // ADD INTENTS NEEDED HERE FOR YOUR TEST IF NECESSARY -}); +}) -await startBot(bot); +await startBot(bot) ``` **Expected behavior** A clear and concise description of what you expected to happen. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index 13412bb5c..abcb29180 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -1,9 +1,9 @@ --- name: Feature request about: Suggest an idea for this project -title: "" +title: '' labels: feat -assignees: "" +assignees: '' --- **Is your feature request related to a problem? Please describe.** A clear and concise description of what the problem diff --git a/.gitpod.yml b/.gitpod.yml new file mode 100644 index 000000000..72c309053 --- /dev/null +++ b/.gitpod.yml @@ -0,0 +1,11 @@ +# This configuration file was automatically generated by Gitpod. +# Please adjust to your needs (see https://www.gitpod.io/docs/introduction/learn-gitpod/gitpod-yaml) +# and commit this file to your remote git repository to share the goodness with others. + +# Learn more from ready-to-use templates: https://www.gitpod.io/docs/introduction/getting-started/quickstart + +tasks: + - init: yarn install && yarn run build && yarn run lint && yarn run build:doc + command: yarn run dev + + diff --git a/bench/generateMessage.ts b/bench/generateMessage.ts index b6238ea6e..7dc7a55f7 100644 --- a/bench/generateMessage.ts +++ b/bench/generateMessage.ts @@ -1,64 +1,66 @@ -await import(`https://raw.githubusercontent.com/discordeno/discordeno/benchies/benchmarksResult/data.js`); -const commitSha = await Deno.readTextFile("./sha"); -const results = JSON.parse(await Deno.readTextFile("./data.json")); +await import(`https://raw.githubusercontent.com/discordeno/discordeno/benchies/benchmarksResult/data.js`) +const commitSha = await Deno.readTextFile('./sha') +const results = JSON.parse(await Deno.readTextFile('./data.json')) interface BenchmarksData { commit: { - author: { email: string; name: string; username: string }; - committer: { email: string; name: string; username: string }; - distinct: boolean; - id: string; - message: string; - timestamp: string; - tree_id: string; - url: string; - }; - date: number; - tool: string; - benches: Array<{ name: string; value: number; unit: string; range: string }>; + author: { email: string; name: string; username: string } + committer: { email: string; name: string; username: string } + distinct: boolean + id: string + message: string + timestamp: string + tree_id: string + url: string + } + date: number + tool: string + benches: Array<{ name: string; value: number; unit: string; range: string }> } interface CompareTable { [index: string]: { - current: { name: string; value: number; unit: string; range: string } | { - name?: string; - value?: number; - unit?: string; - range?: string; - }; - previous: { name: string; value: number; unit: string; range: string } | { - name?: string; - value?: number; - unit?: string; - range?: string; - }; - }; + current: + | { name: string; value: number; unit: string; range: string } + | { + name?: string + value?: number + unit?: string + range?: string + } + previous: + | { name: string; value: number; unit: string; range: string } + | { + name?: string + value?: number + unit?: string + range?: string + } + } } -const benchmarks = results.entries.Benchmark.slice(-2) as BenchmarksData[]; -const latestHeadBenchmarks = benchmarks.length === 2 ? benchmarks[1] : benchmarks[0]; -const lastHeadBenchmarks = benchmarks.length === 2 ? benchmarks[0] : undefined; +const benchmarks = results.entries.Benchmark.slice(-2) as BenchmarksData[] +const latestHeadBenchmarks = benchmarks.length === 2 ? benchmarks[1] : benchmarks[0] +const lastHeadBenchmarks = benchmarks.length === 2 ? benchmarks[0] : undefined // @ts-expect-error -const latestBaseBenchmarks = JSON.parse(JSON.stringify(window.BENCHMARK_DATA.entries.Benchmark)).slice( - -1, -)[0] as BenchmarksData; +const latestBaseBenchmarks = JSON.parse(JSON.stringify(window.BENCHMARK_DATA.entries.Benchmark)).slice(-1)[0] as BenchmarksData -const compareWithHead: CompareTable = {}; -const compareWithBase: CompareTable = {}; +const compareWithHead: CompareTable = {} +const compareWithBase: CompareTable = {} if (lastHeadBenchmarks) { for (const benchmark of lastHeadBenchmarks.benches) { compareWithHead[benchmark.name] = { previous: benchmark, current: {}, - }; + } } } for (const benchmark of latestBaseBenchmarks.benches) { compareWithBase[benchmark.name] = { previous: benchmark, current: {}, - }; + } } for (const benchmark of latestHeadBenchmarks.benches) { compareWithBase[benchmark.name] = { @@ -66,51 +68,48 @@ for (const benchmark of latestHeadBenchmarks.benches) { previous: {}, ...compareWithBase[benchmark.name], current: benchmark, - }; + } compareWithHead[benchmark.name] = { // @ts-expect-error previous: {}, ...compareWithHead[benchmark.name], current: benchmark, - }; -} - -let message = ""; - -const compareTableInfo = [{ name: "last head", commit: lastHeadBenchmarks ? lastHeadBenchmarks.commit.id : "" }, { - name: "base", - commit: latestBaseBenchmarks.commit.id, -}]; -for (const benchmarkType of ["Performance", "Memory"]) { - message += `# ${benchmarkType} Benchmark\n\n`; - for (const [index, compare] of [compareWithHead, compareWithBase].entries()) { - message += `## Compared with ${compareTableInfo[index].name}\n`; - message += "
Detail results of benchmarks\n\n"; - message += `| Benchmark suite | Current: ${latestHeadBenchmarks.commit.id} | Previous: ${ - compareTableInfo[index].commit - } | Ratio |\n | -| -| -| -|\n`; - for ( - const field of Object.keys(compare).filter((key) => - benchmarkType === "Performance" ? !key.startsWith("[Cache Plugin]") : key.startsWith("[Cache Plugin]") - ) - ) { - message += `| \`${field}\` | ${compare[field].current.value ? `\`${compare[field].current.value}\`` : ""} ${ - compare[field].current.unit ?? "" - } ${compare[field].current.range ? `(\`${compare[field].current.range ?? ""}\`)` : ""} | ${ - compare[field].previous.value ? `\`${compare[field].previous.value}\`` : "" - } ${compare[field].previous.unit ?? ""} ${ - compare[field].previous.range ? `(\`${compare[field].previous.range ?? ""}\`)` : "" - } | ${ - compare[field].previous.value && compare[field].current.value - ? `\`${ - // @ts-expect-error - Math.round((parseFloat(compare[field].previous.value) / parseFloat(compare[field].current.value)) * 100) / - 100}\`` - : "" - } |\n`; - } - message += "
\n\n"; } } -console.log(message.replaceAll("`", "\\`")); +let message = '' + +const compareTableInfo = [ + { name: 'last head', commit: lastHeadBenchmarks ? lastHeadBenchmarks.commit.id : '' }, + { + name: 'base', + commit: latestBaseBenchmarks.commit.id, + }, +] +for (const benchmarkType of ['Performance', 'Memory']) { + message += `# ${benchmarkType} Benchmark\n\n` + for (const [index, compare] of [compareWithHead, compareWithBase].entries()) { + message += `## Compared with ${compareTableInfo[index].name}\n` + message += '
Detail results of benchmarks\n\n' + message += `| Benchmark suite | Current: ${latestHeadBenchmarks.commit.id} | Previous: ${compareTableInfo[index].commit} | Ratio |\n | -| -| -| -|\n` + for (const field of Object.keys(compare).filter((key) => + benchmarkType === 'Performance' ? !key.startsWith('[Cache Plugin]') : key.startsWith('[Cache Plugin]'), + )) { + message += `| \`${field}\` | ${compare[field].current.value ? `\`${compare[field].current.value}\`` : ''} ${ + compare[field].current.unit ?? '' + } ${compare[field].current.range ? `(\`${compare[field].current.range ?? ''}\`)` : ''} | ${ + compare[field].previous.value ? `\`${compare[field].previous.value}\`` : '' + } ${compare[field].previous.unit ?? ''} ${compare[field].previous.range ? `(\`${compare[field].previous.range ?? ''}\`)` : ''} | ${ + compare[field].previous.value && compare[field].current.value + ? `\`${ + // @ts-expect-error + Math.round((parseFloat(compare[field].previous.value) / parseFloat(compare[field].current.value)) * 100) / 100 + }\`` + : '' + } |\n` + } + message += '
\n\n' + } +} + +console.log(message.replaceAll('`', '\\`')) diff --git a/bench/memory.ts b/bench/memory.ts index 8e65252f3..07eac8556 100644 --- a/bench/memory.ts +++ b/bench/memory.ts @@ -1,28 +1,30 @@ -import { memoryBenchmarks } from "https://raw.githubusercontent.com/discordeno/benchmarks/main/index.ts"; -import { createBot } from '../mod.ts.js'; -import { enableCachePlugin } from '../plugins/mod.ts.js'; +import { memoryBenchmarks } from 'https://raw.githubusercontent.com/discordeno/benchmarks/main/index.ts' +import { createBot } from '../mod.ts.js' +import { enableCachePlugin } from '../plugins/mod.ts.js' const results = await memoryBenchmarks(() => - enableCachePlugin(createBot({ - token: " ", - botId: 0n, - })) -); + enableCachePlugin( + createBot({ + token: ' ', + botId: 0n, + }), + ), +) const output: Array<{ - name: string; - value: number; - range: string; - unit: string; -}> = JSON.parse(await Deno.readTextFile("output.txt")); + name: string + value: number + range: string + unit: string +}> = JSON.parse(await Deno.readTextFile('output.txt')) for (const resultKey of Object.keys(results.Cached) as Array) { output.push({ name: `[Cache Plugin] ${resultKey.toString()}`, value: results.Cached[resultKey].value, range: `${results.Cached[resultKey].min} … ${results.Cached[resultKey].max}`, - unit: "MB", - }); + unit: 'MB', + }) } -Deno.writeTextFile("output.txt", JSON.stringify(output, undefined, 2)); +Deno.writeTextFile('output.txt', JSON.stringify(output, undefined, 2)) diff --git a/bench/tranformOutput.ts b/bench/tranformOutput.ts index d60d26618..1bb7f03cb 100644 --- a/bench/tranformOutput.ts +++ b/bench/tranformOutput.ts @@ -1,31 +1,31 @@ // Just a constant sysbench sorce to compare against -const baselineSysbenchScore = 2000; -let sysbenchScore = 2000; +const baselineSysbenchScore = 2000 +let sysbenchScore = 2000 try { - const { stdout } = await Deno.spawn("sysbench", { args: ["cpu", "run"] }); - const textout = new TextDecoder().decode(stdout); - sysbenchScore = parseFloat(textout.match(/\s+events per second:\s+(.+)/)![1]); + const { stdout } = await Deno.spawn('sysbench', { args: ['cpu', 'run'] }) + const textout = new TextDecoder().decode(stdout) + sysbenchScore = parseFloat(textout.match(/\s+events per second:\s+(.+)/)![1]) } catch { // } -const output = await Deno.readTextFile("output.txt"); -const lines = output.split(/\r?\n/g); +const output = await Deno.readTextFile('output.txt') +const lines = output.split(/\r?\n/g) -const ret = []; +const ret = [] const unitMultiplier = { - "s": 1000 * 1000 * 1000 * (sysbenchScore / baselineSysbenchScore), - "ms": 1000 * 1000 * (sysbenchScore / baselineSysbenchScore), - "µs": 1000 * (sysbenchScore / baselineSysbenchScore), - "ns": 1 * (sysbenchScore / baselineSysbenchScore), - "ps": 0.1 * (sysbenchScore / baselineSysbenchScore), -}; + s: 1000 * 1000 * 1000 * (sysbenchScore / baselineSysbenchScore), + ms: 1000 * 1000 * (sysbenchScore / baselineSysbenchScore), + µs: 1000 * (sysbenchScore / baselineSysbenchScore), + ns: 1 * (sysbenchScore / baselineSysbenchScore), + ps: 0.1 * (sysbenchScore / baselineSysbenchScore), +} for (const line of lines) { - const m = line.match(/^(.+)\s+([0-9.]+) (.s)\/iter\s+\((.+) (.s) … (.+) (.s)\)(.+)$/); - if (m === null) continue; + const m = line.match(/^(.+)\s+([0-9.]+) (.s)\/iter\s+\((.+) (.s) … (.+) (.s)\)(.+)$/) + if (m === null) continue ret.push({ name: m[1].trim(), @@ -33,8 +33,8 @@ for (const line of lines) { range: `${Math.round(parseFloat(m[4]) * unitMultiplier[m[5] as keyof typeof unitMultiplier] * 100) / 100} … ${ Math.round(parseFloat(m[6]) * unitMultiplier[m[7] as keyof typeof unitMultiplier] * 100) / 100 }`, - unit: "ns/iter", - }); + unit: 'ns/iter', + }) } -await Deno.writeTextFile("output.txt", JSON.stringify(ret, undefined, 2)); +await Deno.writeTextFile('output.txt', JSON.stringify(ret, undefined, 2)) diff --git a/examples/beginner/bot.ts b/examples/beginner/bot.ts index 6974b1395..444693eda 100644 --- a/examples/beginner/bot.ts +++ b/examples/beginner/bot.ts @@ -1,7 +1,5 @@ -import { configs } from './configs.ts.js'; -import type { - BotWithCache, - BotWithHelpersPlugin} from './deps.ts.js'; +import { configs } from './configs.ts.js' +import type { BotWithCache, BotWithHelpersPlugin } from './deps.ts.js' import { Collection, createBot, @@ -10,8 +8,8 @@ import { enableHelpersPlugin, enablePermissionsPlugin, GatewayIntents, -} from './deps.ts.js'; -import type { Command } from './src/types/commands.ts.js'; +} from './deps.ts.js' +import type { Command } from './src/types/commands.ts.js' // MAKE THE BASIC BOT OBJECT const bot = createBot({ @@ -19,19 +17,19 @@ const bot = createBot({ botId: configs.botId, intents: GatewayIntents.Guilds, events: {}, -}); +}) // ENABLE ALL THE PLUGINS THAT WILL HELP MAKE IT EASIER TO CODE YOUR BOT -enableHelpersPlugin(bot); -enableCachePlugin(bot); -enableCacheSweepers(bot as BotWithCache); -enablePermissionsPlugin(bot as BotWithCache); +enableHelpersPlugin(bot) +enableCachePlugin(bot) +enableCacheSweepers(bot as BotWithCache) +enablePermissionsPlugin(bot as BotWithCache) export interface BotClient extends BotWithCache { - commands: Collection; + commands: Collection } // THIS IS THE BOT YOU WANT TO USE EVERYWHERE IN YOUR CODE! IT HAS EVERYTHING BUILT INTO IT! -export const Bot = bot as BotClient; +export const Bot = bot as BotClient // PREPARE COMMANDS HOLDER -Bot.commands = new Collection(); +Bot.commands = new Collection() diff --git a/examples/beginner/configs.ts b/examples/beginner/configs.ts index f42459573..536e902a0 100644 --- a/examples/beginner/configs.ts +++ b/examples/beginner/configs.ts @@ -1,19 +1,19 @@ -import { dotEnvConfig } from './deps.ts.js'; +import { dotEnvConfig } from './deps.ts.js' // Get the .env file that the user should have created, and get the token -const env = dotEnvConfig({ export: true, path: "./.env" }); -const token = env.BOT_TOKEN || ""; +const env = dotEnvConfig({ export: true, path: './.env' }) +const token = env.BOT_TOKEN || '' export interface Config { - token: string; - botId: bigint; + token: string + botId: bigint } export const configs = { /** Get token from ENV variable */ token, /** Get the BotId from the token */ - botId: BigInt(atob(token.split(".")[0])), + botId: BigInt(atob(token.split('.')[0])), /** The server id where you develop your bot and want dev commands created. */ devGuildId: BigInt(env.DEV_GUILD_ID!), -}; +} diff --git a/examples/beginner/deps.ts b/examples/beginner/deps.ts index 9da9ac457..9cf710fa8 100644 --- a/examples/beginner/deps.ts +++ b/examples/beginner/deps.ts @@ -1,9 +1,9 @@ -export * from "https://deno.land/x/discordeno@17.0.0/mod.ts"; -export * from "https://deno.land/x/discordeno@17.0.0/plugins/mod.ts"; +export * from 'https://deno.land/x/discordeno@17.0.0/mod.ts' +export * from 'https://deno.land/x/discordeno@17.0.0/plugins/mod.ts' // Terminal Colors! -export * from "https://deno.land/std@0.117.0/fmt/colors.ts"; +export * from 'https://deno.land/std@0.117.0/fmt/colors.ts' // Get data from .env files -export { config as dotEnvConfig } from "https://deno.land/x/dotenv@v3.1.0/mod.ts"; +export { config as dotEnvConfig } from 'https://deno.land/x/dotenv@v3.1.0/mod.ts' // Database, thx Tri! -export { decode as KwikDecode, encode as KwikEncode, Kwik } from "https://deno.land/x/kwik@v1.3.1/mod.ts"; +export { decode as KwikDecode, encode as KwikEncode, Kwik } from 'https://deno.land/x/kwik@v1.3.1/mod.ts' diff --git a/examples/beginner/mod.ts b/examples/beginner/mod.ts index 53642f048..97b1dbdfd 100644 --- a/examples/beginner/mod.ts +++ b/examples/beginner/mod.ts @@ -1,25 +1,25 @@ -import { startBot } from './deps.ts.js'; -import log from './src/utils/logger.ts.js'; -import { fileLoader, importDirectory } from './src/utils/loader.ts.js'; -import { updateApplicationCommands } from './src/utils/updateCommands.ts.js'; +import { startBot } from './deps.ts.js' +import log from './src/utils/logger.ts.js' +import { fileLoader, importDirectory } from './src/utils/loader.ts.js' +import { updateApplicationCommands } from './src/utils/updateCommands.ts.js' // setup db -import './src/database/mod.ts.js'; -import { Bot } from './bot.ts.js'; +import './src/database/mod.ts.js' +import { Bot } from './bot.ts.js' -log.info("Starting bot..."); +log.info('Starting bot...') // Forces deno to read all the files which will fill the commands/inhibitors cache etc. await Promise.all( [ - "./src/commands", - "./src/events", + './src/commands', + './src/events', // "./src/tasks", ].map((path) => importDirectory(Deno.realPathSync(path))), -); -await fileLoader(); +) +await fileLoader() // UPDATES YOUR COMMANDS TO LATEST COMMANDS -await updateApplicationCommands(); +await updateApplicationCommands() // STARTS THE CONNECTION TO DISCORD -await startBot(Bot); +await startBot(Bot) diff --git a/examples/beginner/src/commands/mod.ts b/examples/beginner/src/commands/mod.ts index ce9f3e284..27bbef957 100644 --- a/examples/beginner/src/commands/mod.ts +++ b/examples/beginner/src/commands/mod.ts @@ -1,6 +1,6 @@ -import { Bot } from '../../bot.ts.js'; -import type { Command } from '../types/commands.ts.js'; +import { Bot } from '../../bot.ts.js' +import type { Command } from '../types/commands.ts.js' export function createCommand(command: Command) { - Bot.commands.set(command.name, command); + Bot.commands.set(command.name, command) } diff --git a/examples/beginner/src/commands/ping.ts b/examples/beginner/src/commands/ping.ts index 4108c590d..1922edcf4 100644 --- a/examples/beginner/src/commands/ping.ts +++ b/examples/beginner/src/commands/ping.ts @@ -1,22 +1,18 @@ -import { ApplicationCommandTypes, InteractionResponseTypes } from '../../deps.ts.js'; -import { snowflakeToTimestamp } from '../utils/helpers.ts.js'; -import { createCommand } from './mod.ts.js'; +import { ApplicationCommandTypes, InteractionResponseTypes } from '../../deps.ts.js' +import { snowflakeToTimestamp } from '../utils/helpers.ts.js' +import { createCommand } from './mod.ts.js' createCommand({ - name: "ping", - description: "Ping the Bot!", + name: 'ping', + description: 'Ping the Bot!', type: ApplicationCommandTypes.ChatInput, execute: async (Bot, interaction) => { - const ping = Date.now() - snowflakeToTimestamp(interaction.id); - await Bot.helpers.sendInteractionResponse( - interaction.id, - interaction.token, - { - type: InteractionResponseTypes.ChannelMessageWithSource, - data: { - content: `🏓 Pong! ${ping}ms`, - }, + const ping = Date.now() - snowflakeToTimestamp(interaction.id) + await Bot.helpers.sendInteractionResponse(interaction.id, interaction.token, { + type: InteractionResponseTypes.ChannelMessageWithSource, + data: { + content: `🏓 Pong! ${ping}ms`, }, - ); + }) }, -}); +}) diff --git a/examples/beginner/src/database/mod.ts b/examples/beginner/src/database/mod.ts index d66e72931..434328763 100644 --- a/examples/beginner/src/database/mod.ts +++ b/examples/beginner/src/database/mod.ts @@ -1,32 +1,32 @@ -import { Kwik, KwikDecode, KwikEncode } from '../../deps.ts.js'; -import { logger } from '../utils/logger.ts.js'; +import { Kwik, KwikDecode, KwikEncode } from '../../deps.ts.js' +import { logger } from '../utils/logger.ts.js' -const log = logger({ name: "DB Manager" }); +const log = logger({ name: 'DB Manager' }) -log.info("Initializing Database"); +log.info('Initializing Database') -const kwik = new Kwik(); +const kwik = new Kwik() // Add BigInt Support kwik.msgpackExtensionCodec.register({ type: 0, encode: (object: unknown): Uint8Array | null => { - if (typeof object === "bigint") { + if (typeof object === 'bigint') { if (object <= Number.MAX_SAFE_INTEGER && object >= Number.MIN_SAFE_INTEGER) { - return KwikEncode(parseInt(object.toString(), 10), {}); + return KwikEncode(parseInt(object.toString(), 10), {}) } else { - return KwikEncode(object.toString(), {}); + return KwikEncode(object.toString(), {}) } } else { - return null; + return null } }, decode: (data: Uint8Array) => { - return BigInt(KwikDecode(data, {}) as string); + return BigInt(KwikDecode(data, {}) as string) }, -}); +}) // Initialize the Database -await kwik.init(); +await kwik.init() -log.info("Database Initialized!"); +log.info('Database Initialized!') diff --git a/examples/beginner/src/events/interactionCreate.ts b/examples/beginner/src/events/interactionCreate.ts index 46b925caa..178680dff 100644 --- a/examples/beginner/src/events/interactionCreate.ts +++ b/examples/beginner/src/events/interactionCreate.ts @@ -1,16 +1,14 @@ -import { Bot } from '../../bot.ts.js'; -import { InteractionTypes } from '../../deps.ts.js'; -import log from '../utils/logger.ts.js'; +import { Bot } from '../../bot.ts.js' +import { InteractionTypes } from '../../deps.ts.js' +import log from '../utils/logger.ts.js' Bot.events.interactionCreate = (_, interaction) => { - if (!interaction.data) return; + if (!interaction.data) return switch (interaction.type) { case InteractionTypes.ApplicationCommand: - log.info( - `[Application Command] ${interaction.data.name} command executed.`, - ); - Bot.commands.get(interaction.data.name!)?.execute(Bot, interaction); - break; + log.info(`[Application Command] ${interaction.data.name} command executed.`) + Bot.commands.get(interaction.data.name!)?.execute(Bot, interaction) + break } -}; +} diff --git a/examples/beginner/src/events/ready.ts b/examples/beginner/src/events/ready.ts index eaf12d058..1d57aeccc 100644 --- a/examples/beginner/src/events/ready.ts +++ b/examples/beginner/src/events/ready.ts @@ -1,16 +1,16 @@ -import { Bot } from '../../bot.ts.js'; -import log from '../utils/logger.ts.js'; +import { Bot } from '../../bot.ts.js' +import log from '../utils/logger.ts.js' Bot.events.ready = (_, payload) => { - log.info(`[READY] Shard ID ${payload.shardId} of ${Bot.gateway.lastShardId + 1} shards is ready!`); + log.info(`[READY] Shard ID ${payload.shardId} of ${Bot.gateway.lastShardId + 1} shards is ready!`) if (payload.shardId === Bot.gateway.lastShardId) { - botFullyReady(); + botFullyReady() } -}; +} // This function lets you run custom code when all your bot's shards are online. function botFullyReady() { // DO STUFF YOU WANT HERE ONCE BOT IS FULLY ONLINE. - log.info("[READY] Bot is fully online."); + log.info('[READY] Bot is fully online.') } diff --git a/examples/beginner/src/types/commands.ts b/examples/beginner/src/types/commands.ts index 2d0a7e7dc..aeddaf60a 100644 --- a/examples/beginner/src/types/commands.ts +++ b/examples/beginner/src/types/commands.ts @@ -1,17 +1,17 @@ -import type { BotClient } from '../../bot.ts.js'; -import type { ApplicationCommandOption, ApplicationCommandTypes, Interaction } from '../../deps.ts.js'; +import type { BotClient } from '../../bot.ts.js' +import type { ApplicationCommandOption, ApplicationCommandTypes, Interaction } from '../../deps.ts.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: (bot: BotClient, interaction: Interaction) => unknown; + execute: (bot: BotClient, interaction: Interaction) => unknown } diff --git a/examples/beginner/src/types/mod.ts b/examples/beginner/src/types/mod.ts index f3d0e7629..88fce63cc 100644 --- a/examples/beginner/src/types/mod.ts +++ b/examples/beginner/src/types/mod.ts @@ -1,3 +1,3 @@ // This file will export all of the types in this directory. -export * from './commands.ts.js'; +export * from './commands.ts.js' diff --git a/examples/beginner/src/utils/helpers.ts b/examples/beginner/src/utils/helpers.ts index 2ac9255bb..d5f880cdc 100644 --- a/examples/beginner/src/utils/helpers.ts +++ b/examples/beginner/src/utils/helpers.ts @@ -1,3 +1,3 @@ export function snowflakeToTimestamp(id: bigint) { - return Number(id / 4194304n + 1420070400000n); + return Number(id / 4194304n + 1420070400000n) } diff --git a/examples/beginner/src/utils/loader.ts b/examples/beginner/src/utils/loader.ts index a5b9af0d9..807cec5a6 100644 --- a/examples/beginner/src/utils/loader.ts +++ b/examples/beginner/src/utils/loader.ts @@ -1,47 +1,40 @@ -import log from './logger.ts.js'; +import log from './logger.ts.js' // Very important to make sure files are reloaded properly -let uniqueFilePathCounter = 0; -let paths: string[] = []; +let uniqueFilePathCounter = 0 +let paths: string[] = [] /** This function allows reading all files in a folder. Useful for loading/reloading commands, monitors etc */ export async function importDirectory(path: string) { - path = path.replaceAll("\\", "/"); - const files = Deno.readDirSync(Deno.realPathSync(path)); - const folder = path.substring(path.indexOf("/src/") + 5); + path = path.replaceAll('\\', '/') + const files = Deno.readDirSync(Deno.realPathSync(path)) + const folder = path.substring(path.indexOf('/src/') + 5) - if (!folder.includes("/")) log.info(`Loading ${folder}...`); + if (!folder.includes('/')) log.info(`Loading ${folder}...`) for (const file of files) { - if (!file.name) continue; + if (!file.name) continue - const currentPath = `${path}/${file.name}`; + const currentPath = `${path}/${file.name}` if (file.isFile) { - if (!currentPath.endsWith(".ts")) continue; + if (!currentPath.endsWith('.ts')) continue paths.push( - `import "${Deno.mainModule.substring(0, Deno.mainModule.lastIndexOf("/"))}/${ - currentPath.substring( - currentPath.indexOf("src/"), - ) - }#${uniqueFilePathCounter}";`, - ); - continue; + `import "${Deno.mainModule.substring(0, Deno.mainModule.lastIndexOf('/'))}/${currentPath.substring( + currentPath.indexOf('src/'), + )}#${uniqueFilePathCounter}";`, + ) + continue } - await importDirectory(currentPath); + await importDirectory(currentPath) } - uniqueFilePathCounter++; + uniqueFilePathCounter++ } /** Imports all everything in fileloader.ts */ export async function fileLoader() { - await Deno.writeTextFile( - "fileloader.ts", - paths.join("\n").replaceAll("\\", "/"), - ); - await import( - `${Deno.mainModule.substring(0, Deno.mainModule.lastIndexOf("/"))}/fileloader.ts#${uniqueFilePathCounter}` - ); - paths = []; + await Deno.writeTextFile('fileloader.ts', paths.join('\n').replaceAll('\\', '/')) + await import(`${Deno.mainModule.substring(0, Deno.mainModule.lastIndexOf('/'))}/fileloader.ts#${uniqueFilePathCounter}`) + paths = [] } diff --git a/examples/beginner/src/utils/logger.ts b/examples/beginner/src/utils/logger.ts index d5a039064..c69924a23 100644 --- a/examples/beginner/src/utils/logger.ts +++ b/examples/beginner/src/utils/logger.ts @@ -1,5 +1,5 @@ // deno-lint-ignore-file no-explicit-any -import { bold, cyan, gray, italic, red, yellow } from '../../deps.ts.js'; +import { bold, cyan, gray, italic, red, yellow } from '../../deps.ts.js' export enum LogLevels { Debug, @@ -10,81 +10,81 @@ export enum LogLevels { } const prefixes = new Map([ - [LogLevels.Debug, "DEBUG"], - [LogLevels.Info, "INFO"], - [LogLevels.Warn, "WARN"], - [LogLevels.Error, "ERROR"], - [LogLevels.Fatal, "FATAL"], -]); + [LogLevels.Debug, 'DEBUG'], + [LogLevels.Info, 'INFO'], + [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 logger({ logLevel = LogLevels.Info, name, }: { - logLevel?: LogLevels; - name?: string; + 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 = [ `[${date.toLocaleDateString()} ${date.toLocaleTimeString()}]`, - color(prefixes.get(level) || "DEBUG"), - name ? `${name} >` : ">", + 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 { @@ -95,8 +95,8 @@ export function logger({ warn, error, fatal, - }; + } } -export const log = logger({ name: "Main" }); -export default log; +export const log = logger({ name: 'Main' }) +export default log diff --git a/examples/beginner/src/utils/updateCommands.ts b/examples/beginner/src/utils/updateCommands.ts index 9e4afd77b..f2751e7a8 100644 --- a/examples/beginner/src/utils/updateCommands.ts +++ b/examples/beginner/src/utils/updateCommands.ts @@ -1,5 +1,5 @@ -import { Bot } from '../../bot.ts.js'; -import { configs } from '../../configs.ts.js'; +import { Bot } from '../../bot.ts.js' +import { configs } from '../../configs.ts.js' export async function updateApplicationCommands() { await Bot.helpers.upsertGlobalApplicationCommands( @@ -7,7 +7,7 @@ export async function updateApplicationCommands() { // ONLY GLOBAL COMMANDS .filter((command) => !command.devOnly) .array(), - ); + ) await Bot.helpers.upsertGuildApplicationCommands( configs.devGuildId, @@ -15,5 +15,5 @@ export async function updateApplicationCommands() { // ONLY GLOBAL COMMANDS .filter((command) => !!command.devOnly) .array(), - ); + ) } diff --git a/examples/bigbot/src/analytics.ts b/examples/bigbot/src/analytics.ts index 78dd217cf..85638d167 100644 --- a/examples/bigbot/src/analytics.ts +++ b/examples/bigbot/src/analytics.ts @@ -1,5 +1,5 @@ -import { InfluxDB, Point } from "@influxdata/influxdb-client"; -import type { RestManager } from "discordeno/rest"; +import { InfluxDB, Point } from '@influxdata/influxdb-client'; +import type { RestManager } from 'discordeno/rest'; const INFLUX_ORG = process.env.INFLUX_ORG as string; const INFLUX_BUCKET = process.env.INFLUX_BUCKET as string; @@ -10,46 +10,46 @@ export const influxDB = INFLUX_URL && INFLUX_TOKEN ? new InfluxDB({ url: INFLUX_ export const Influx = influxDB?.getWriteApi(INFLUX_ORG, INFLUX_BUCKET); export const setupAnalyticsHooks = (rest: RestManager) => { - // If influxdb data is provided, enable analytics in this proxy. - if (Influx) { - rest.fetching = function (options) { - Influx?.writePoint( - new Point("restEvents") - // MARK THE TIME WHEN EVENT ARRIVED - .timestamp(new Date()) - // SET THE GUILD ID - .stringField("type", "REQUEST_FETCHING") - .tag("method", options.method) - .tag("url", options.url) - .tag("bucket", options.bucketId ?? "NA"), - ); - }; + // If influxdb data is provided, enable analytics in this proxy. + if (Influx) { + rest.fetching = function (options) { + Influx?.writePoint( + new Point('restEvents') + // MARK THE TIME WHEN EVENT ARRIVED + .timestamp(new Date()) + // SET THE GUILD ID + .stringField('type', 'REQUEST_FETCHING') + .tag('method', options.method) + .tag('url', options.url) + .tag('bucket', options.bucketId ?? 'NA'), + ); + }; - rest.fetched = function (options, response) { - Influx?.writePoint( - new Point("restEvents") - // MARK THE TIME WHEN EVENT ARRIVED - .timestamp(new Date()) - // SET THE GUILD ID - .stringField("type", "REQUEST_FETCHED") - .tag("method", options.method) - .tag("url", options.url) - .tag("bucket", options.bucketId ?? "NA") - .intField("status", response.status) - .tag("statusText", response.statusText), - ); - }; + rest.fetched = function (options, response) { + Influx?.writePoint( + new Point('restEvents') + // MARK THE TIME WHEN EVENT ARRIVED + .timestamp(new Date()) + // SET THE GUILD ID + .stringField('type', 'REQUEST_FETCHED') + .tag('method', options.method) + .tag('url', options.url) + .tag('bucket', options.bucketId ?? 'NA') + .intField('status', response.status) + .tag('statusText', response.statusText), + ); + }; - setInterval(() => { - console.log(`[Influx - REST] Saving events...`); - Influx?.flush() - .then(() => { - console.log(`[Influx - REST] Saved events!`); - }) - .catch((error) => { - console.log(`[Influx - REST] Error saving events!`, error); - }); - // Every 30seconds - }, 30000); - } + setInterval(() => { + console.log(`[Influx - REST] Saving events...`); + Influx?.flush() + .then(() => { + console.log(`[Influx - REST] Saved events!`); + }) + .catch((error) => { + console.log(`[Influx - REST] Error saving events!`, error); + }); + // Every 30seconds + }, 30000); + } }; diff --git a/examples/bigbot/src/bot/bot.ts b/examples/bigbot/src/bot/bot.ts index 572a0619b..fbaca1ac9 100644 --- a/examples/bigbot/src/bot/bot.ts +++ b/examples/bigbot/src/bot/bot.ts @@ -1,50 +1,50 @@ -import type { Bot} from "discordeno"; -import { Collection, createBot, createRestManager } from "discordeno"; -import enableHelpersPlugin from "discordeno/helpers-plugin"; -import { createLogger } from "discordeno/logger"; -import { setupAnalyticsHooks } from "../analytics.js"; -import { INTENTS, REST_URL } from "../configs.js"; -import { setupEventHandlers } from "./events/mod.js"; -import type { MessageCollector } from "./utils/collectors.js"; -import { customizeInternals } from "./utils/internals/mod.js"; +import type { Bot } from 'discordeno'; +import { Collection, createBot, createRestManager } from 'discordeno'; +import enableHelpersPlugin from 'discordeno/helpers-plugin'; +import { createLogger } from 'discordeno/logger'; +import { setupAnalyticsHooks } from '../analytics.js'; +import { INTENTS, REST_URL } from '../configs.js'; +import { setupEventHandlers } from './events/mod.js'; +import type { MessageCollector } from './utils/collectors.js'; +import { customizeInternals } from './utils/internals/mod.js'; const DISCORD_TOKEN = process.env.DISCORD_TOKEN as string; const REST_AUTHORIZATION = process.env.REST_AUTHORIZATION as string; export const bot = enableHelpersPlugin( - customizeBot( - createBot({ - token: DISCORD_TOKEN, - intents: INTENTS, - }), - ), + customizeBot( + createBot({ + token: DISCORD_TOKEN, + intents: INTENTS, + }), + ), ); /** Add custom props to your `bot` here */ // SETUP-DD-TEMP: If you want to add any custom props to `bot` you can do so here. Please make sure to also add them in the type below. As an example, i have added a `logger` property. You can add any useful methods or props you wish to have easily available. function customizeBot(bot: B): BotWithCustomProps { - const customized = bot as unknown as BotWithCustomProps; - customized.logger = createLogger({ name: "[Bot]" }); - customized.collectors = { - messages: new Collection(), - }; - customized.commandVersions = new Collection(); + const customized = bot as unknown as BotWithCustomProps; + customized.logger = createLogger({ name: '[Bot]' }); + customized.collectors = { + messages: new Collection(), + }; + customized.commandVersions = new Collection(); - return customized; + return customized; } // SETUP-DD-TEMP: If you want to add any custom props to `bot` you can do so here. Please make sure to also add them in the function above. Run a find all and change this to your Bot's name. For example, if your bot's name is Gamer change BotWithCustomProps to Gamer. This way whenever you need to provide the type for the Bot with your custom props it is your bots name. // Note: ALWAYS edit the function above first before adding the type here. export type BotWithCustomProps = B & { - /** A easy to use logger to make clean log messages. */ - logger: ReturnType; - /** Collectors that can be used to get input from users. */ - collectors: { - /** Holds the pending messages collectors that users can respond to. */ - messages: Collection; - }; - /** The command versions for each guild id. */ - commandVersions: Collection; + /** A easy to use logger to make clean log messages. */ + logger: ReturnType; + /** Collectors that can be used to get input from users. */ + collectors: { + /** Holds the pending messages collectors that users can respond to. */ + messages: Collection; + }; + /** The command versions for each guild id. */ + commandVersions: Collection; }; // Example of how to customize internal discordeno stuff easily. @@ -54,9 +54,9 @@ customizeInternals(bot); setupEventHandlers(); bot.rest = createRestManager({ - token: DISCORD_TOKEN, - secretKey: REST_AUTHORIZATION, - customUrl: REST_URL, + token: DISCORD_TOKEN, + secretKey: REST_AUTHORIZATION, + customUrl: REST_URL, }); // Add send fetching analytics hook to rest diff --git a/examples/bigbot/src/bot/commands/language.ts b/examples/bigbot/src/bot/commands/language.ts index df2ba0206..3f25e4d9f 100644 --- a/examples/bigbot/src/bot/commands/language.ts +++ b/examples/bigbot/src/bot/commands/language.ts @@ -1,33 +1,33 @@ -import { ApplicationCommandOptionTypes } from "discordeno"; -import { prisma } from "../../prisma.js"; -import languages from "../languages/languages.js"; -import { serverLanguages, translate } from "../languages/translate.js"; -import { createCommand } from "../utils/slash/createCommand.js"; +import { ApplicationCommandOptionTypes } from 'discordeno'; +import { prisma } from '../../prisma.js'; +import languages from '../languages/languages.js'; +import { serverLanguages, translate } from '../languages/translate.js'; +import { createCommand } from '../utils/slash/createCommand.js'; export default createCommand({ - name: "LANGUAGE_NAME", - description: "LANGUAGE_DESCRIPTION", - options: [ - { - name: "LANGUAGE_KEY_NAME", - description: "LANGUAGE_KEY_DESCRIPTION", - type: ApplicationCommandOptionTypes.String, - choices: Object.keys(languages).map((key) => ({ name: key, value: key })), - required: true, - }, - ], - execute: async function (_, interaction, args) { - if (!interaction.guildId) return; + name: 'LANGUAGE_NAME', + description: 'LANGUAGE_DESCRIPTION', + options: [ + { + name: 'LANGUAGE_KEY_NAME', + description: 'LANGUAGE_KEY_DESCRIPTION', + type: ApplicationCommandOptionTypes.String, + choices: Object.keys(languages).map((key) => ({ name: key, value: key })), + required: true, + }, + ], + execute: async function (_, interaction, args) { + if (!interaction.guildId) return; - // Set the new language in cache - serverLanguages.set(interaction.guildId, args.name); - // Let the user know its been updated. - await interaction.reply(translate(interaction.guildId!, "LANGUAGE_UPDATED", args.name)); - // Update the db - return await prisma.guilds.upsert({ - where: { id: interaction.guildId }, - create: { language: args.name, id: interaction.guildId }, - update: { language: args.name }, - }); - }, + // Set the new language in cache + serverLanguages.set(interaction.guildId, args.name); + // Let the user know its been updated. + await interaction.reply(translate(interaction.guildId!, 'LANGUAGE_UPDATED', args.name)); + // Update the db + return await prisma.guilds.upsert({ + where: { id: interaction.guildId }, + create: { language: args.name, id: interaction.guildId }, + update: { language: args.name }, + }); + }, }); diff --git a/examples/bigbot/src/bot/commands/mod.ts b/examples/bigbot/src/bot/commands/mod.ts index 557bbfd61..b25e3edf5 100644 --- a/examples/bigbot/src/bot/commands/mod.ts +++ b/examples/bigbot/src/bot/commands/mod.ts @@ -1,9 +1,9 @@ -import language from "./language.js"; -import ping from "./ping.js"; +import language from './language.js'; +import ping from './ping.js'; export const COMMANDS = { - language, - ping, + language, + ping, }; export default COMMANDS; diff --git a/examples/bigbot/src/bot/commands/ping.ts b/examples/bigbot/src/bot/commands/ping.ts index b1856aeec..b733f9b3f 100644 --- a/examples/bigbot/src/bot/commands/ping.ts +++ b/examples/bigbot/src/bot/commands/ping.ts @@ -1,17 +1,17 @@ -import { translate } from "../languages/translate.js"; -import { createCommand } from "../utils/slash/createCommand.js"; +import { translate } from '../languages/translate.js'; +import { createCommand } from '../utils/slash/createCommand.js'; export default createCommand({ - name: "PING_NAME", - description: "PING_DESCRIPTION", - execute: async function (_, interaction) { - return await interaction.reply( - translate(interaction.guildId!, "PING_RESPONSE_WITH_TIME", Date.now() - snowflakeToTimestamp(interaction.id)), - ); - }, + name: 'PING_NAME', + description: 'PING_DESCRIPTION', + execute: async function (_, interaction) { + return await interaction.reply( + translate(interaction.guildId!, 'PING_RESPONSE_WITH_TIME', Date.now() - snowflakeToTimestamp(interaction.id)), + ); + }, }); // TODO: This should be deleted once this is available in the helpers plugin. export function snowflakeToTimestamp(id: bigint) { - return Number(id / 4194304n + 1420070400000n); + return Number(id / 4194304n + 1420070400000n); } diff --git a/examples/bigbot/src/bot/events/interactions/button.ts b/examples/bigbot/src/bot/events/interactions/button.ts index 89acc8322..a863ceb0c 100644 --- a/examples/bigbot/src/bot/events/interactions/button.ts +++ b/examples/bigbot/src/bot/events/interactions/button.ts @@ -1,14 +1,14 @@ -import type { Interaction } from "discordeno"; -import type { BotWithCustomProps } from "../../bot.js"; +import type { Interaction } from 'discordeno'; +import type { BotWithCustomProps } from '../../bot.js'; export async function executeButtonClick(bot: BotWithCustomProps, interaction: Interaction) { - if (!interaction.data) return; + if (!interaction.data) return; - bot.logger.info( - `[Button] The ${interaction.data.customId} button was clicked in Guild: ${interaction.guildId} by ${interaction.user.id}.`, - ); + bot.logger.info( + `[Button] The ${interaction.data.customId} button was clicked in Guild: ${interaction.guildId} by ${interaction.user.id}.`, + ); - await Promise.allSettled([ - // SETUP-DD-TEMP: Insert any functions you wish to run when a user clicks a button. - ]).catch(console.log); + await Promise.allSettled([ + // SETUP-DD-TEMP: Insert any functions you wish to run when a user clicks a button. + ]).catch(console.log); } diff --git a/examples/bigbot/src/bot/events/interactions/command.ts b/examples/bigbot/src/bot/events/interactions/command.ts index a8ebb2d7d..137041f4d 100644 --- a/examples/bigbot/src/bot/events/interactions/command.ts +++ b/examples/bigbot/src/bot/events/interactions/command.ts @@ -1,121 +1,116 @@ -import { bgBlack, bgGreen, bgMagenta, bgYellow, black, green, red, white } from "colorette"; +import { bgBlack, bgGreen, bgMagenta, bgYellow, black, green, red, white } from 'colorette'; import type { - ApplicationCommandOption, - Bot, - Channel, - ChannelTypes, - Interaction, - InteractionDataOption, - Member, - Role, - User} from "discordeno"; -import { - ApplicationCommandOptionTypes, - InteractionResponseTypes -} from "discordeno"; -import type { BotWithCustomProps } from "../../bot.js"; -import { bot } from "../../bot.js"; -import COMMANDS from "../../commands/mod.js"; -import type { translationKeys } from "../../languages/translate.js"; -import { getLanguage, loadLanguage, serverLanguages, translate } from "../../languages/translate.js"; -import type { InteractionWithCustomProps } from "../../typings/discordeno.js"; -import type { Command, ConvertArgumentDefinitionsToArgs } from "../../utils/slash/createCommand.js"; + ApplicationCommandOption, + Bot, + Channel, + ChannelTypes, + Interaction, + InteractionDataOption, + Member, + Role, + User, +} from 'discordeno'; +import { ApplicationCommandOptionTypes, InteractionResponseTypes } from 'discordeno'; +import type { BotWithCustomProps } from '../../bot.js'; +import { bot } from '../../bot.js'; +import COMMANDS from '../../commands/mod.js'; +import type { translationKeys } from '../../languages/translate.js'; +import { getLanguage, loadLanguage, serverLanguages, translate } from '../../languages/translate.js'; +import type { InteractionWithCustomProps } from '../../typings/discordeno.js'; +import type { Command, ConvertArgumentDefinitionsToArgs } from '../../utils/slash/createCommand.js'; function logCommand( - info: Interaction, - type: "Failure" | "Success" | "Trigger" | "Slowmode" | "Missing" | "Inhibit", - commandName: string, + info: Interaction, + type: 'Failure' | 'Success' | 'Trigger' | 'Slowmode' | 'Missing' | 'Inhibit', + commandName: string, ) { - const command = `[COMMAND: ${bgYellow(black(commandName || "Unknown"))} - ${ - bgBlack( - ["Failure", "Slowmode", "Missing"].includes(type) ? red(type) : type === "Success" ? green(type) : white(type), - ) - }]`; + const command = `[COMMAND: ${bgYellow(black(commandName || 'Unknown'))} - ${bgBlack( + ['Failure', 'Slowmode', 'Missing'].includes(type) ? red(type) : type === 'Success' ? green(type) : white(type), + )}]`; - const user = bgGreen( - black(`${info.user.username}#${info.user.discriminator.toString().padStart(4, "0")}(${info.id})`), - ); - const guild = bgMagenta(black(`${info.guildId ? `Guild ID: (${info.guildId})` : "DM"}`)); + const user = bgGreen( + black(`${info.user.username}#${info.user.discriminator.toString().padStart(4, '0')}(${info.id})`), + ); + const guild = bgMagenta(black(`${info.guildId ? `Guild ID: (${info.guildId})` : 'DM'}`)); - bot.logger.info(`${command} by ${user} in ${guild} with MessageID: ${info.id}`); + bot.logger.info(`${command} by ${user} in ${guild} with MessageID: ${info.id}`); } export async function executeSlashCommand(bot: BotWithCustomProps, interaction: InteractionWithCustomProps) { - const data = interaction.data; - const name = data?.name as keyof typeof COMMANDS; + const data = interaction.data; + const name = data?.name as keyof typeof COMMANDS; - const command: Command | undefined = COMMANDS[name]; + const command: Command | undefined = COMMANDS[name]; - // Command could not be found - if (!command?.execute) { - return await interaction - .reply(translate(interaction.guildId!, "EXECUTE_COMMAND_NOT_FOUND")) - .catch(bot.logger.error); - } + // Command could not be found + if (!command?.execute) { + return await interaction + .reply(translate(interaction.guildId!, 'EXECUTE_COMMAND_NOT_FOUND')) + .catch(bot.logger.error); + } - // HAVE TO CONVERT OUTSIDE OF TRY SO IT CAN BE USED IN CATCH TOO - try { - logCommand(interaction, "Trigger", name); + // HAVE TO CONVERT OUTSIDE OF TRY SO IT CAN BE USED IN CATCH TOO + try { + logCommand(interaction, 'Trigger', name); - // Check subcommand permissions and options - if (!(await commandAllowed(interaction, command))) return; + // Check subcommand permissions and options + if (!(await commandAllowed(interaction, command))) return; - // Load the language for this guild - if (interaction.guildId && !serverLanguages.has(interaction.guildId)) { - // Todo: make command.execute reply change to editReply after running this - // await interaction.reply({ - // type: InteractionResponseTypes.DeferredChannelMessageWithSource, - // }); - await loadLanguage(interaction.guildId); - } // Load the language for this guild - else if (command.acknowledge) { - // Acknowledge the command - await interaction.reply({ - type: InteractionResponseTypes.DeferredChannelMessageWithSource, - }); - } + // Load the language for this guild + if (interaction.guildId && !serverLanguages.has(interaction.guildId)) { + // Todo: make command.execute reply change to editReply after running this + // await interaction.reply({ + // type: InteractionResponseTypes.DeferredChannelMessageWithSource, + // }); + await loadLanguage(interaction.guildId); + } // Load the language for this guild + else if (command.acknowledge) { + // Acknowledge the command + await interaction.reply({ + type: InteractionResponseTypes.DeferredChannelMessageWithSource, + }); + } - // FIRST GET THE TRANSLATIONS FOR ALL OPTIONS - const translatedOptionNames = interaction.guildId && command.options - ? translateOptionNames(bot, interaction.guildId, command.options) - : {}; + // FIRST GET THE TRANSLATIONS FOR ALL OPTIONS + const translatedOptionNames = + interaction.guildId && command.options ? translateOptionNames(bot, interaction.guildId, command.options) : {}; - // PARSE THE OPTIONS TO A NICE OBJECT AND TRANSLATE THE KEYS TO ENGLISH - const parsedArguments = optionParser(interaction, translatedOptionNames); + // PARSE THE OPTIONS TO A NICE OBJECT AND TRANSLATE THE KEYS TO ENGLISH + const parsedArguments = optionParser(interaction, translatedOptionNames); - await command.execute(bot, interaction, parsedArguments as ConvertArgumentDefinitionsToArgs); - logCommand(interaction, "Success", name); - } catch (error) { - console.error(error); - logCommand(interaction, "Failure", name); + await command.execute(bot, interaction, parsedArguments as ConvertArgumentDefinitionsToArgs); + logCommand(interaction, 'Success', name); + } catch (error) { + console.error(error); + logCommand(interaction, 'Failure', name); - try { - console.log("try"); - // try to reply the interaction, becuase we don't know if it replied or deffered - return await interaction.reply(translate(interaction.id, "EXECUTE_COMMAND_ERROR")); - } catch { - console.log("catch"); - // edit the reply or deffered reply of interaction - return await interaction.editReply(translate(interaction.id, "EXECUTE_COMMAND_ERROR")).catch(bot.logger.error); - } - } + try { + console.log('try'); + // try to reply the interaction, becuase we don't know if it replied or deffered + return await interaction.reply(translate(interaction.id, 'EXECUTE_COMMAND_ERROR')); + } catch { + console.log('catch'); + // edit the reply or deffered reply of interaction + return await interaction.editReply(translate(interaction.id, 'EXECUTE_COMMAND_ERROR')).catch(bot.logger.error); + } + } } /** Runs the inhibitors to see if a command is allowed to run. */ export async function commandAllowed(interaction: InteractionWithCustomProps, command: Command) { - // CHECK WHETHER THE USER/GUILD IS VIP - if (command.vipOnly) { - // SETUP-DD-TEMP: Check if this server/user is a vip. - const isVIP = true; + // CHECK WHETHER THE USER/GUILD IS VIP + if (command.vipOnly) { + // SETUP-DD-TEMP: Check if this server/user is a vip. + const isVIP = true; - if (!isVIP) { - await interaction.reply(translate(interaction.id, "NEED_VIP")).catch(bot.logger.error); + if (!isVIP) { + await interaction.reply(translate(interaction.id, 'NEED_VIP')).catch(bot.logger.error); - return false; - } - } + return false; + } + } - return true; + return true; } // Mapped by `language-commandName` @@ -123,189 +118,187 @@ const translatedOptionNamesCache = new Map>(); /** Translates all options of the command to an object: translatedOptionName: optionName */ export function translateOptionNames( - bot: Bot, - guildId: bigint, - options: ApplicationCommandOption[], - commandName?: string, + bot: Bot, + guildId: bigint, + options: ApplicationCommandOption[], + commandName?: string, ): Record { - const language = getLanguage(guildId); - // RETURN THE ALREADY TRANSLATED OPTIONS WHICH ARE IN CACHE - if (commandName && translatedOptionNamesCache.has(`${language}-${commandName}`)) { - return translatedOptionNamesCache.get(`${language}-${commandName}`)!; - } + const language = getLanguage(guildId); + // RETURN THE ALREADY TRANSLATED OPTIONS WHICH ARE IN CACHE + if (commandName && translatedOptionNamesCache.has(`${language}-${commandName}`)) { + return translatedOptionNamesCache.get(`${language}-${commandName}`)!; + } - // TRANSLATE ALL OPTIONS - let translated: Record = {}; - for (const option of options) { - translated[translate(guildId, option.name as translationKeys).toLowerCase()] = translate( - "english", - option.name as translationKeys, - ); - if (option.options) { - translated = { - ...translated, - ...translateOptionNames(bot, guildId, option.options), - }; - } - } + // TRANSLATE ALL OPTIONS + let translated: Record = {}; + for (const option of options) { + translated[translate(guildId, option.name as translationKeys).toLowerCase()] = translate( + 'english', + option.name as translationKeys, + ); + if (option.options) { + translated = { + ...translated, + ...translateOptionNames(bot, guildId, option.options), + }; + } + } - // SAVE THE TRANSLATED OPTIONS IN CACHE FOR FASTER ACCESS - if (commandName) { - translatedOptionNamesCache.set(`${language}-${commandName}`, translated); - } + // SAVE THE TRANSLATED OPTIONS IN CACHE FOR FASTER ACCESS + if (commandName) { + translatedOptionNamesCache.set(`${language}-${commandName}`, translated); + } - return translated; + return translated; } function convertOptionValue( - interaction: Interaction, - option: InteractionDataOption, - translateOptions?: Record, + interaction: Interaction, + option: InteractionDataOption, + translateOptions?: Record, ): [ - string, - ( - | { user: User; member: Member } - | Role - | { - id: bigint; - name: string; - type: ChannelTypes; - permissions: bigint; - } - | boolean - | string - | number - ), + string, + ( + | { user: User; member: Member } + | Role + | { + id: bigint; + name: string; + type: ChannelTypes; + permissions: bigint; + } + | boolean + | string + | number + ), ] { - // THE OPTION IS A CHANNEL - if (option.type === ApplicationCommandOptionTypes.Channel) { - const channel = interaction.data?.resolved?.channels?.get(BigInt(option.value as string)); + // THE OPTION IS A CHANNEL + if (option.type === ApplicationCommandOptionTypes.Channel) { + const channel = interaction.data?.resolved?.channels?.get(BigInt(option.value as string)); - // SAVE THE ARGUMENT WITH THE CORRECT NAME - return [translateOptions?.[option.name] ?? option.name, channel]; - } + // SAVE THE ARGUMENT WITH THE CORRECT NAME + return [translateOptions?.[option.name] ?? option.name, channel]; + } - // THE OPTION IS A ROLE - if (option.type === ApplicationCommandOptionTypes.Role) { - const role = interaction.data?.resolved?.roles?.get(BigInt(option.value as string)); + // THE OPTION IS A ROLE + if (option.type === ApplicationCommandOptionTypes.Role) { + const role = interaction.data?.resolved?.roles?.get(BigInt(option.value as string)); - // SAVE THE ARGUMENT WITH THE CORRECT NAME - return [translateOptions?.[option.name] ?? option.name, role]; - } + // SAVE THE ARGUMENT WITH THE CORRECT NAME + return [translateOptions?.[option.name] ?? option.name, role]; + } - // THE OPTION IS A USER - if (option.type === ApplicationCommandOptionTypes.User) { - const user = interaction.data?.resolved?.users?.get(BigInt(option.value as string)); - const member = interaction.data?.resolved?.members?.get(BigInt(option.value as string)); + // THE OPTION IS A USER + if (option.type === ApplicationCommandOptionTypes.User) { + const user = interaction.data?.resolved?.users?.get(BigInt(option.value as string)); + const member = interaction.data?.resolved?.members?.get(BigInt(option.value as string)); - // SAVE THE ARGUMENT WITH THE CORRECT NAME - return [ - translateOptions?.[option.name] ?? option.name, - { - member, - user, - }, - ]; - } + // SAVE THE ARGUMENT WITH THE CORRECT NAME + return [ + translateOptions?.[option.name] ?? option.name, + { + member, + user, + }, + ]; + } - // THE OPTION IS A MENTIONABLE - if (option.type === ApplicationCommandOptionTypes.Mentionable) { - const role = interaction.data?.resolved?.roles?.get(BigInt(option.value as string)); - const user = interaction.data?.resolved?.users?.get(BigInt(option.value as string)); - const member = interaction.data?.resolved?.members?.get(BigInt(option.value as string)); + // THE OPTION IS A MENTIONABLE + if (option.type === ApplicationCommandOptionTypes.Mentionable) { + const role = interaction.data?.resolved?.roles?.get(BigInt(option.value as string)); + const user = interaction.data?.resolved?.users?.get(BigInt(option.value as string)); + const member = interaction.data?.resolved?.members?.get(BigInt(option.value as string)); - const final = user && member ? { user, member } : role; + const final = user && member ? { user, member } : role; - // SAVE THE ARGUMENT WITH THE CORRECT NAME - return [translateOptions?.[option.name] ?? option.name, final]; - } + // SAVE THE ARGUMENT WITH THE CORRECT NAME + return [translateOptions?.[option.name] ?? option.name, final]; + } - // THE REST OF OPTIONS DON'T NEED ANY CONVERTION - // SAVE THE ARGUMENT WITH THE CORRECT NAME - // @ts-expect-error - return [translateOptions?.[option.name] ?? option.name, option.value]; + // THE REST OF OPTIONS DON'T NEED ANY CONVERTION + // SAVE THE ARGUMENT WITH THE CORRECT NAME + // @ts-expect-error + return [translateOptions?.[option.name] ?? option.name, option.value]; } /** Parse the options to a nice object. * NOTE: this does not work with subcommands */ export function optionParser( - interaction: Interaction, - translateOptions?: Record, + interaction: Interaction, + translateOptions?: Record, ): - | InteractionCommandArgs - | { [key: string]: InteractionCommandArgs } - | { [key: string]: { [key: string]: InteractionCommandArgs } } { - // OPTIONS CAN BE UNDEFINED SO WE JUST RETURN AN EMPTY OBJECT - if (!interaction.data?.options) return {}; + | InteractionCommandArgs + | { [key: string]: InteractionCommandArgs } + | { [key: string]: { [key: string]: InteractionCommandArgs } } { + // OPTIONS CAN BE UNDEFINED SO WE JUST RETURN AN EMPTY OBJECT + if (!interaction.data?.options) return {}; - // A SUBCOMMAND WAS USED - if (interaction.data.options[0]?.type === ApplicationCommandOptionTypes.SubCommand) { - const convertedOptions: Record< - string, - | { user: User; member: Member } - | Role - | { - id: bigint; - name: string; - type: ChannelTypes; - permissions: bigint; - } - | boolean - | string - | number - > = {}; - // CONVERT ALL THE OPTIONS - for (const option of interaction.data.options[0].options ?? []) { - const [name, value] = convertOptionValue(interaction, option, translateOptions); - convertedOptions[name] = value; - } + // A SUBCOMMAND WAS USED + if (interaction.data.options[0]?.type === ApplicationCommandOptionTypes.SubCommand) { + const convertedOptions: Record< + string, + | { user: User; member: Member } + | Role + | { + id: bigint; + name: string; + type: ChannelTypes; + permissions: bigint; + } + | boolean + | string + | number + > = {}; + // CONVERT ALL THE OPTIONS + for (const option of interaction.data.options[0].options ?? []) { + const [name, value] = convertOptionValue(interaction, option, translateOptions); + convertedOptions[name] = value; + } - // @ts-expect-error - return { - [translateOptions?.[interaction.data.options[0].name] ?? interaction.data.options[0].name]: convertedOptions, - }; - } + // @ts-expect-error + return { + [translateOptions?.[interaction.data.options[0].name] ?? interaction.data.options[0].name]: convertedOptions, + }; + } - // A SUBCOMMAND GROUP WAS USED - if (interaction.data.options[0]?.type === ApplicationCommandOptionTypes.SubCommandGroup) { - const convertedOptions: Record = {}; - // CONVERT ALL THE OPTIONS - for (const option of interaction.data.options[0]?.options![0]?.options ?? []) { - const [name, value] = convertOptionValue(interaction, option, translateOptions); - // @ts-expect-error - convertedOptions[name] = value; - } + // A SUBCOMMAND GROUP WAS USED + if (interaction.data.options[0]?.type === ApplicationCommandOptionTypes.SubCommandGroup) { + const convertedOptions: Record = {}; + // CONVERT ALL THE OPTIONS + for (const option of interaction.data.options[0]?.options![0]?.options ?? []) { + const [name, value] = convertOptionValue(interaction, option, translateOptions); + // @ts-expect-error + convertedOptions[name] = value; + } - // @ts-expect-error - return { - [translateOptions?.[interaction.data.options[0].name] ?? interaction.data.options[0].name]: { - [ - translateOptions?.[interaction.data.options[0]!.options![0]!.name] ?? - interaction.data.options[0]!.options![0]!.name - ]: convertedOptions, - }, - }; - } + // @ts-expect-error + return { + [translateOptions?.[interaction.data.options[0].name] ?? interaction.data.options[0].name]: { + [translateOptions?.[interaction.data.options[0]!.options![0]!.name] ?? + interaction.data.options[0]!.options![0]!.name]: convertedOptions, + }, + }; + } - // A NORMAL COMMAND WAS USED - const convertedOptions: Record< - string, - Member | Role | Record> | boolean | string | number - > = {}; - for (const option of interaction.data.options ?? []) { - const [name, value] = convertOptionValue(interaction, option, translateOptions); - // @ts-expect-error - convertedOptions[name] = value; - } + // A NORMAL COMMAND WAS USED + const convertedOptions: Record< + string, + Member | Role | Record> | boolean | string | number + > = {}; + for (const option of interaction.data.options ?? []) { + const [name, value] = convertOptionValue(interaction, option, translateOptions); + // @ts-expect-error + convertedOptions[name] = value; + } - return convertedOptions; + return convertedOptions; } /** The interaction arguments. * Important the members `deaf` and `mute` properties will always be false. */ export type InteractionCommandArgs = Record< - string, - Member | Role | Record> | boolean | string | number + string, + Member | Role | Record> | boolean | string | number >; diff --git a/examples/bigbot/src/bot/events/interactions/mod.ts b/examples/bigbot/src/bot/events/interactions/mod.ts index e07a7a069..63de86904 100644 --- a/examples/bigbot/src/bot/events/interactions/mod.ts +++ b/examples/bigbot/src/bot/events/interactions/mod.ts @@ -1,23 +1,23 @@ -import { InteractionTypes, MessageComponentTypes } from "discordeno"; -import { bot } from "../../bot.js"; -import type { InteractionWithCustomProps } from "../../typings/discordeno.js"; -import { executeButtonClick } from "./button.js"; -import { executeSlashCommand } from "./command.js"; -import { executeModalSubmit } from "./modal.js"; +import { InteractionTypes, MessageComponentTypes } from 'discordeno'; +import { bot } from '../../bot.js'; +import type { InteractionWithCustomProps } from '../../typings/discordeno.js'; +import { executeButtonClick } from './button.js'; +import { executeSlashCommand } from './command.js'; +import { executeModalSubmit } from './modal.js'; export function setInteractionCreateEvent() { - bot.events.interactionCreate = async function (_, interaction) { - if (interaction.type === InteractionTypes.ApplicationCommand) { - await executeSlashCommand(bot, interaction as InteractionWithCustomProps); - } else if (interaction.type === InteractionTypes.MessageComponent) { - if (!interaction.data) return; + bot.events.interactionCreate = async function (_, interaction) { + if (interaction.type === InteractionTypes.ApplicationCommand) { + await executeSlashCommand(bot, interaction as InteractionWithCustomProps); + } else if (interaction.type === InteractionTypes.MessageComponent) { + if (!interaction.data) return; - // THE INTERACTION CAME FROM A BUTTON - if (interaction.data.componentType === MessageComponentTypes.Button) { - await executeButtonClick(bot, interaction); - } - } else if (interaction.type === InteractionTypes.ModalSubmit) { - await executeModalSubmit(bot, interaction); - } - }; + // THE INTERACTION CAME FROM A BUTTON + if (interaction.data.componentType === MessageComponentTypes.Button) { + await executeButtonClick(bot, interaction); + } + } else if (interaction.type === InteractionTypes.ModalSubmit) { + await executeModalSubmit(bot, interaction); + } + }; } diff --git a/examples/bigbot/src/bot/events/interactions/modal.ts b/examples/bigbot/src/bot/events/interactions/modal.ts index e01be5a0c..faf395edc 100644 --- a/examples/bigbot/src/bot/events/interactions/modal.ts +++ b/examples/bigbot/src/bot/events/interactions/modal.ts @@ -1,16 +1,16 @@ -import type { Interaction } from "discordeno"; -import type { BotWithCustomProps } from "../../bot.js"; +import type { Interaction } from 'discordeno'; +import type { BotWithCustomProps } from '../../bot.js'; export async function executeModalSubmit(bot: BotWithCustomProps, interaction: Interaction) { - if (!interaction.data) return; + if (!interaction.data) return; - bot.logger.info( - `[Modal] The ${ - interaction.data?.customId || "UNKNWON" - } modal was submitted in Guild: ${interaction.guildId} by ${interaction.user.id}.`, - ); + bot.logger.info( + `[Modal] The ${interaction.data?.customId || 'UNKNWON'} modal was submitted in Guild: ${interaction.guildId} by ${ + interaction.user.id + }.`, + ); - await Promise.allSettled([ - // SETUP-DD-TEMP: Insert any functions you wish to run when a user clicks a button. - ]).catch(console.log); + await Promise.allSettled([ + // SETUP-DD-TEMP: Insert any functions you wish to run when a user clicks a button. + ]).catch(console.log); } diff --git a/examples/bigbot/src/bot/events/messages/create.ts b/examples/bigbot/src/bot/events/messages/create.ts index 7f5466cda..e612077a4 100644 --- a/examples/bigbot/src/bot/events/messages/create.ts +++ b/examples/bigbot/src/bot/events/messages/create.ts @@ -1,12 +1,12 @@ -import { bot } from "../../bot.js"; -import { processMessageCollectors } from "../../utils/collectors.js"; +import { bot } from '../../bot.js'; +import { processMessageCollectors } from '../../utils/collectors.js'; export function setMessageCreateEvent() { - bot.events.messageCreate = async function (_, message) { - processMessageCollectors(message); + bot.events.messageCreate = async function (_, message) { + processMessageCollectors(message); - await Promise.allSettled([ - // SETUP-DD-TEMP: Add any functions you want to run on every message here. For example, automoderation filters. - ]).catch(console.log); - }; + await Promise.allSettled([ + // SETUP-DD-TEMP: Add any functions you want to run on every message here. For example, automoderation filters. + ]).catch(console.log); + }; } diff --git a/examples/bigbot/src/bot/events/mod.ts b/examples/bigbot/src/bot/events/mod.ts index 625f3736e..d9494d269 100644 --- a/examples/bigbot/src/bot/events/mod.ts +++ b/examples/bigbot/src/bot/events/mod.ts @@ -1,9 +1,9 @@ -import { setInteractionCreateEvent } from "./interactions/mod.js"; -import { setMessageCreateEvent } from "./messages/create.js"; -import { setRawEvent } from "./raw.js"; +import { setInteractionCreateEvent } from './interactions/mod.js'; +import { setMessageCreateEvent } from './messages/create.js'; +import { setRawEvent } from './raw.js'; export function setupEventHandlers() { - setInteractionCreateEvent(); - setRawEvent(); - setMessageCreateEvent(); + setInteractionCreateEvent(); + setRawEvent(); + setMessageCreateEvent(); } diff --git a/examples/bigbot/src/bot/events/raw.ts b/examples/bigbot/src/bot/events/raw.ts index e4a6e2772..c5211497f 100644 --- a/examples/bigbot/src/bot/events/raw.ts +++ b/examples/bigbot/src/bot/events/raw.ts @@ -1,38 +1,38 @@ -import type { DiscordUnavailableGuild } from "discordeno"; -import { prisma } from "../../prisma.js"; -import { bot } from "../bot.js"; -import { updateGuildCommands, usesLatestCommandVersion } from "../utils/slash/updateCommands.js"; +import type { DiscordUnavailableGuild } from 'discordeno'; +import { prisma } from '../../prisma.js'; +import { bot } from '../bot.js'; +import { updateGuildCommands, usesLatestCommandVersion } from '../utils/slash/updateCommands.js'; /** To prevent updating every guild when a shard goes ready we have to ignore them using this */ // export const initialyLoadingGuildIds = new Set() export function setRawEvent() { - bot.events.raw = async function (_, data) { - if (data.t === "GUILD_DELETE") { - const id = (data.d as DiscordUnavailableGuild).id; + bot.events.raw = async function (_, data) { + if (data.t === 'GUILD_DELETE') { + const id = (data.d as DiscordUnavailableGuild).id; - return await prisma.commands.delete({ where: { id: bot.transformers.snowflake(id) } }); - } + return await prisma.commands.delete({ where: { id: bot.transformers.snowflake(id) } }); + } - const id = bot.transformers.snowflake( - (data.t && ["GUILD_UPDATE", "GUILD_CREATE"].includes(data.t) - // deno-lint-ignore no-explicit-any - ? (data.d )?.id - // deno-lint-ignore no-explicit-any - : (data.d )?.guild_id) ?? "", - ); + const id = bot.transformers.snowflake( + (data.t && ['GUILD_UPDATE', 'GUILD_CREATE'].includes(data.t) + ? // deno-lint-ignore no-explicit-any + data.d?.id + : // deno-lint-ignore no-explicit-any + data.d?.guild_id) ?? '', + ); - // The GUILD_CREATE event came from a shard loaded event so ignore it - if (["READY", "GUILD_LOADED_DD", null].includes(data.t)) return; + // The GUILD_CREATE event came from a shard loaded event so ignore it + if (['READY', 'GUILD_LOADED_DD', null].includes(data.t)) return; - // console.log({ id, v: await usesLatestCommandVersion(id) }) + // console.log({ id, v: await usesLatestCommandVersion(id) }) - if (!id || (await usesLatestCommandVersion(id))) return; - // dev guild - if (id === 547046977578336286n) return; + if (!id || (await usesLatestCommandVersion(id))) return; + // dev guild + if (id === 547046977578336286n) return; - // NEW GUILD AVAILABLE - bot.logger.info(`[Slash Setup] Installing Slash commands on Guild ${id} event type: ${data.t}`); - await updateGuildCommands(bot, id).catch(bot.logger.error); - }; + // NEW GUILD AVAILABLE + bot.logger.info(`[Slash Setup] Installing Slash commands on Guild ${id} event type: ${data.t}`); + await updateGuildCommands(bot, id).catch(bot.logger.error); + }; } diff --git a/examples/bigbot/src/bot/index.ts b/examples/bigbot/src/bot/index.ts index 55afe2720..32040f629 100644 --- a/examples/bigbot/src/bot/index.ts +++ b/examples/bigbot/src/bot/index.ts @@ -1,14 +1,14 @@ -import dotenv from "dotenv"; +import dotenv from 'dotenv'; -import type { DiscordGatewayPayload } from "discordeno"; +import type { DiscordGatewayPayload } from 'discordeno'; // ReferenceError: publishMessage is not defined // import Embeds from "discordeno/embeds"; -import amqplib from "amqplib"; -import express from "express"; -import { BOT_ID, EVENT_HANDLER_URL } from "../configs.js"; -import { bot } from "./bot.js"; -import { updateDevCommands } from "./utils/slash/updateCommands.js"; -import { webhookURLToIDAndToken } from "./utils/webhook.js"; +import amqplib from 'amqplib'; +import express from 'express'; +import { BOT_ID, EVENT_HANDLER_URL } from '../configs.js'; +import { bot } from './bot.js'; +import { updateDevCommands } from './utils/slash/updateCommands.js'; +import { webhookURLToIDAndToken } from './utils/webhook.js'; dotenv.config(); const BUGS_ERRORS_REPORT_WEBHOOK = process.env.BUGS_ERRORS_REPORT_WEBHOOK; @@ -16,23 +16,23 @@ const EVENT_HANDLER_AUTHORIZATION = process.env.EVENT_HANDLER_AUTHORIZATION as s const EVENT_HANDLER_PORT = process.env.EVENT_HANDLER_PORT as string; process - .on("unhandledRejection", (error) => { - if (!BUGS_ERRORS_REPORT_WEBHOOK) return; - const { id, token } = webhookURLToIDAndToken(BUGS_ERRORS_REPORT_WEBHOOK); - if (!id || !token) return; + .on('unhandledRejection', (error) => { + if (!BUGS_ERRORS_REPORT_WEBHOOK) return; + const { id, token } = webhookURLToIDAndToken(BUGS_ERRORS_REPORT_WEBHOOK); + if (!id || !token) return; - // DO NOT SEND ERRORS FROM NON PRODUCTION - if (BOT_ID !== 270010330782892032n) { - return console.error(error); - } + // DO NOT SEND ERRORS FROM NON PRODUCTION + if (BOT_ID !== 270010330782892032n) { + return console.error(error); + } - // An unhandled error occurred on the bot in production - console.error(error ?? `An unhandled rejection error occurred but error was null or undefined`); + // An unhandled error occurred on the bot in production + console.error(error ?? `An unhandled rejection error occurred but error was null or undefined`); - if (!error) return; + if (!error) return; - // ReferenceError: publishMessage is not defined - /* + // ReferenceError: publishMessage is not defined + /* const embeds = new Embeds() .setDescription(["```js", error, "```"].join(`\n`)) .setTimestamp() @@ -41,23 +41,23 @@ process // SEND ERROR TO THE LOG CHANNEL ON THE DEV SERVER return bot.helpers.sendWebhookMessage(bot.transformers.snowflake(id), token, { embeds }).catch(console.error); */ - }) - .on("uncaughtException", async (error) => { - if (!BUGS_ERRORS_REPORT_WEBHOOK) return; - const { id, token } = webhookURLToIDAndToken(BUGS_ERRORS_REPORT_WEBHOOK); - if (!id || !token) return; + }) + .on('uncaughtException', async (error) => { + if (!BUGS_ERRORS_REPORT_WEBHOOK) return; + const { id, token } = webhookURLToIDAndToken(BUGS_ERRORS_REPORT_WEBHOOK); + if (!id || !token) return; - // DO NOT SEND ERRORS FROM NON PRODUCTION - if (BOT_ID !== 270010330782892032n) { - return console.error(error); - } + // DO NOT SEND ERRORS FROM NON PRODUCTION + if (BOT_ID !== 270010330782892032n) { + return console.error(error); + } - // An unhandled error occurred on the bot in production - console.error(error ?? `An unhandled exception occurred but error was null or undefined`); + // An unhandled error occurred on the bot in production + console.error(error ?? `An unhandled exception occurred but error was null or undefined`); - if (!error) process.exit(1); + if (!error) process.exit(1); - /* + /* const embeds = new Embeds() .setDescription(["```js", error.stack, "```"].join(`\n`)) .setTimestamp() @@ -66,124 +66,120 @@ process await bot.helpers.sendWebhookMessage(bot.transformers.snowflake(id), token, { embeds }).catch(console.error); */ - process.exit(1); - }); + process.exit(1); + }); -if (process.env.DEVELOPMENT === "true") { - bot.logger.info(`[DEV MODE] Updating slash commands for dev server.`); - updateDevCommands(bot); +if (process.env.DEVELOPMENT === 'true') { + bot.logger.info(`[DEV MODE] Updating slash commands for dev server.`); + updateDevCommands(bot); } // Handle events from the gateway const handleEvent = async (message: DiscordGatewayPayload, shardId: number) => { - // EMITS RAW EVENT - bot.events.raw(bot, message, shardId); + // EMITS RAW EVENT + bot.events.raw(bot, message, shardId); - if (message.t && message.t !== "RESUMED") { - // When a guild or something isnt in cache this will fetch it before doing anything else - if (!["READY", "GUILD_LOADED_DD"].includes(message.t)) { - await bot.events.dispatchRequirements(bot, message, shardId); - } + if (message.t && message.t !== 'RESUMED') { + // When a guild or something isnt in cache this will fetch it before doing anything else + if (!['READY', 'GUILD_LOADED_DD'].includes(message.t)) { + await bot.events.dispatchRequirements(bot, message, shardId); + } - bot.handlers[message.t]?.(bot, message, shardId); - } + bot.handlers[message.t]?.(bot, message, shardId); + } }; const app = express(); app.use( - express.urlencoded({ - extended: true, - }), + express.urlencoded({ + extended: true, + }), ); app.use(express.json()); -app.all("/", async (req, res) => { - try { - if (!EVENT_HANDLER_AUTHORIZATION || EVENT_HANDLER_AUTHORIZATION !== req.headers.authorization) { - return res.status(401).json({ error: "Invalid authorization key." }); - } +app.all('/', async (req, res) => { + try { + if (!EVENT_HANDLER_AUTHORIZATION || EVENT_HANDLER_AUTHORIZATION !== req.headers.authorization) { + return res.status(401).json({ error: 'Invalid authorization key.' }); + } - const json = req.body as { - message: DiscordGatewayPayload; - shardId: number; - }; + const json = req.body as { + message: DiscordGatewayPayload; + shardId: number; + }; - await handleEvent(json.message, json.shardId); + await handleEvent(json.message, json.shardId); - res.status(200).json({ success: true }); - } catch (error: any) { - bot.logger.error(error); - res.status(error.code).json(error); - } + res.status(200).json({ success: true }); + } catch (error: any) { + bot.logger.error(error); + res.status(error.code).json(error); + } }); app.listen(EVENT_HANDLER_PORT, () => { - console.log(`Bot is listening at ${EVENT_HANDLER_URL};`); + console.log(`Bot is listening at ${EVENT_HANDLER_URL};`); }); const connectRabbitmq = async () => { - let connection: amqplib.Connection | undefined; + let connection: amqplib.Connection | undefined; - try { - connection = await amqplib.connect( - `amqp://${process.env.MESSAGEQUEUE_USERNAME}:${process.env.MESSAGEQUEUE_PASSWORD}@${process.env.MESSAGEQUEUE_URL}`, - ); - } catch (error) { - console.error(error); - setTimeout(connectRabbitmq, 1000); - } + try { + connection = await amqplib.connect( + `amqp://${process.env.MESSAGEQUEUE_USERNAME}:${process.env.MESSAGEQUEUE_PASSWORD}@${process.env.MESSAGEQUEUE_URL}`, + ); + } catch (error) { + console.error(error); + setTimeout(connectRabbitmq, 1000); + } - if (!connection) return; - connection.on("error", (err) => { - console.error(err); - setTimeout(connectRabbitmq, 1000); - }); + if (!connection) return; + connection.on('error', (err) => { + console.error(err); + setTimeout(connectRabbitmq, 1000); + }); - connection.on("close", () => { - setTimeout(connectRabbitmq, 1000); - }); + connection.on('close', () => { + setTimeout(connectRabbitmq, 1000); + }); - try { - const channel = await connection.createChannel(); + try { + const channel = await connection.createChannel(); - await channel.assertExchange( - "gatewayMessage", - "x-message-deduplication", - { - durable: true, - arguments: { - "x-cache-size": 1000, - "x-cache-ttl": 500, - }, - }, - ); + await channel.assertExchange('gatewayMessage', 'x-message-deduplication', { + durable: true, + arguments: { + 'x-cache-size': 1000, + 'x-cache-ttl': 500, + }, + }); - await channel.assertQueue("gatewayMessageQueue"); - await channel.bindQueue("gatewayMessageQueue", "gatewayMessage", ""); - await channel.consume( - "gatewayMessageQueue", - async (msg) => { - if (!msg) return; - const json = JSON.parse(msg.content.toString()) as { - message: DiscordGatewayPayload; - shardId: number; - }; + await channel.assertQueue('gatewayMessageQueue'); + await channel.bindQueue('gatewayMessageQueue', 'gatewayMessage', ''); + await channel.consume( + 'gatewayMessageQueue', + async (msg) => { + if (!msg) return; + const json = JSON.parse(msg.content.toString()) as { + message: DiscordGatewayPayload; + shardId: number; + }; - await handleEvent(json.message, json.shardId); + await handleEvent(json.message, json.shardId); - await channel.ack(msg); - }, - { - noAck: false, - }, - ); - } catch (error) { - console.error(error); - } + await channel.ack(msg); + }, + { + noAck: false, + }, + ); + } catch (error) { + console.error(error); + } }; -if (process.env.MESSAGEQUEUE_ENABLE === "true") { - connectRabbitmq(); +if (process.env.MESSAGEQUEUE_ENABLE === 'true') { + connectRabbitmq(); } diff --git a/examples/bigbot/src/bot/languages/english.ts b/examples/bigbot/src/bot/languages/english.ts index 71afc7cea..08b37aa4d 100644 --- a/examples/bigbot/src/bot/languages/english.ts +++ b/examples/bigbot/src/bot/languages/english.ts @@ -1,23 +1,23 @@ const english = { - // Permissions - NEED_VIP: "❌ Only VIP users or servers can use this feature.", + // Permissions + NEED_VIP: '❌ Only VIP users or servers can use this feature.', - // Execute Command - EXECUTE_COMMAND_NOT_FOUND: "❌ Something went wrong. I was not able to find this command.", - EXECUTE_COMMAND_ERROR: "❌ Something went wrong. The command execution has thrown an error.", + // Execute Command + EXECUTE_COMMAND_NOT_FOUND: '❌ Something went wrong. I was not able to find this command.', + EXECUTE_COMMAND_ERROR: '❌ Something went wrong. The command execution has thrown an error.', - // Language Command - LANGUAGE_NAME: "language", - LANGUAGE_DESCRIPTION: "⚙️ Change the bots language.", - LANGUAGE_KEY_NAME: "name", - LANGUAGE_KEY_DESCRIPTION: "What language would you like to set?", - LANGUAGE_UPDATED: (language: string) => `The language has been updated to ${language}`, + // Language Command + LANGUAGE_NAME: 'language', + LANGUAGE_DESCRIPTION: '⚙️ Change the bots language.', + LANGUAGE_KEY_NAME: 'name', + LANGUAGE_KEY_DESCRIPTION: 'What language would you like to set?', + LANGUAGE_UPDATED: (language: string) => `The language has been updated to ${language}`, - // Ping Command - PING_NAME: "ping", - PING_DESCRIPTION: "🏓 Check whether the bot is online and responsive.", - PING_RESPONSE: "🏓 Pong! I am online and responsive! :clock10:", - PING_RESPONSE_WITH_TIME: (time: number) => `🏓 Pong! ${time / 1000} seconds! I am online and responsive! :clock10:`, + // Ping Command + PING_NAME: 'ping', + PING_DESCRIPTION: '🏓 Check whether the bot is online and responsive.', + PING_RESPONSE: '🏓 Pong! I am online and responsive! :clock10:', + PING_RESPONSE_WITH_TIME: (time: number) => `🏓 Pong! ${time / 1000} seconds! I am online and responsive! :clock10:`, } as const; export default english; diff --git a/examples/bigbot/src/bot/languages/languages.ts b/examples/bigbot/src/bot/languages/languages.ts index ede55921c..ca1142f49 100644 --- a/examples/bigbot/src/bot/languages/languages.ts +++ b/examples/bigbot/src/bot/languages/languages.ts @@ -1,4 +1,4 @@ -import english from "./english.js"; +import english from './english.js'; // import french from './french' // import german from './german' // import portuguese from './portuguese' @@ -6,15 +6,15 @@ import english from "./english.js"; // import spanish from './spanish' const languages: Record & Record = { - english, - // french, - // german, - // portuguese, - // russian, - // spanish, + english, + // french, + // german, + // portuguese, + // russian, + // spanish, }; export default languages; export type Language = Record string)>; -export type LanguageNames = "english"; +export type LanguageNames = 'english'; diff --git a/examples/bigbot/src/bot/languages/translate.ts b/examples/bigbot/src/bot/languages/translate.ts index 8fe4954ba..75371353e 100644 --- a/examples/bigbot/src/bot/languages/translate.ts +++ b/examples/bigbot/src/bot/languages/translate.ts @@ -1,8 +1,8 @@ -import Embeds from "discordeno/embeds"; -import { bot } from "../bot.js"; -import { webhookURLToIDAndToken } from "../utils/webhook.js"; -import type english from "./english.js"; -import languages from "./languages.js"; +import Embeds from 'discordeno/embeds'; +import { bot } from '../bot.js'; +import { webhookURLToIDAndToken } from '../utils/webhook.js'; +import type english from './english.js'; +import languages from './languages.js'; const MISSING_TRANSLATION_WEBHOOK = process.env.MISSING_TRANSLATION_WEBHOOK; @@ -10,75 +10,75 @@ const MISSING_TRANSLATION_WEBHOOK = process.env.MISSING_TRANSLATION_WEBHOOK; export const serverLanguages = new Map(); export function translate( - guildIdOrLanguage: bigint | keyof typeof languages, - key: K, - ...params: getArgs + guildIdOrLanguage: bigint | keyof typeof languages, + key: K, + ...params: getArgs ): string { - const language = getLanguage(guildIdOrLanguage); - let value: string | ((...any: any[]) => string) | string[] | undefined = languages[language]?.[key]; + const language = getLanguage(guildIdOrLanguage); + let value: string | ((...any: any[]) => string) | string[] | undefined = languages[language]?.[key]; - // Was not able to be translated - if (!value) { - // Check if this key is available in english - if (language !== "english") { - value = languages.english[key]; - } + // Was not able to be translated + if (!value) { + // Check if this key is available in english + if (language !== 'english') { + value = languages.english[key]; + } - // Still not found in english so default to using the KEY_ITSELF - if (!value) value = key; + // Still not found in english so default to using the KEY_ITSELF + if (!value) value = key; - // Send a log webhook so the devs know sth is missing - missingTranslation(language, key); - } + // Send a log webhook so the devs know sth is missing + missingTranslation(language, key); + } - if (Array.isArray(value)) return value.join("\n"); + if (Array.isArray(value)) return value.join('\n'); - if (typeof value === "function") return value(...(params || [])); + if (typeof value === 'function') return value(...(params || [])); - return value ; + return value; } /** Get the language this guild has set, will always return "english" if it is not in cache */ export function getLanguage(guildIdOrLanguage: bigint | keyof typeof languages) { - return typeof guildIdOrLanguage === "string" - ? guildIdOrLanguage - : serverLanguages.get(guildIdOrLanguage) ?? "english"; + return typeof guildIdOrLanguage === 'string' + ? guildIdOrLanguage + : serverLanguages.get(guildIdOrLanguage) ?? 'english'; } export async function loadLanguage(guildId: bigint) { - // TODO: add this settings - // const settings = await database.findOne('guilds', guildId) - const settings = { language: "undefined" }; + // TODO: add this settings + // const settings = await database.findOne('guilds', guildId) + const settings = { language: 'undefined' }; - if (settings?.language && languages[settings.language]) { - serverLanguages.set(guildId, settings.language); - } else serverLanguages.set(guildId, "english"); + if (settings?.language && languages[settings.language]) { + serverLanguages.set(guildId, settings.language); + } else serverLanguages.set(guildId, 'english'); } /** Send a webhook for a missing translation key */ export async function missingTranslation(language: keyof typeof languages, key: string) { - if (!MISSING_TRANSLATION_WEBHOOK) return; - const { id, token } = webhookURLToIDAndToken(MISSING_TRANSLATION_WEBHOOK); - if (!id || !token) return; + if (!MISSING_TRANSLATION_WEBHOOK) return; + const { id, token } = webhookURLToIDAndToken(MISSING_TRANSLATION_WEBHOOK); + if (!id || !token) return; - const embeds = new Embeds() - .setTitle("Missing Translation") - .setColor("RANDOM") - .addField("Language", language, true) - .addField("Key", key, true); + const embeds = new Embeds() + .setTitle('Missing Translation') + .setColor('RANDOM') + .addField('Language', language, true) + .addField('Key', key, true); - await bot.helpers - .sendWebhookMessage(bot.transformers.snowflake(id), token, { - // SETUP-DD-TEMP: If you wish to make it @ mention you, please edit the next line. - // content: `<@${owner id here}>`, - embeds, - wait: false, - }) - .catch(bot.logger.error); + await bot.helpers + .sendWebhookMessage(bot.transformers.snowflake(id), token, { + // SETUP-DD-TEMP: If you wish to make it @ mention you, please edit the next line. + // content: `<@${owner id here}>`, + embeds, + wait: false, + }) + .catch(bot.logger.error); } // type translationKeys = keyof typeof english | string export type translationKeys = keyof typeof english; type getArgs = typeof english[K] extends (...any: any[]) => unknown - ? Parameters - : []; + ? Parameters + : []; diff --git a/examples/bigbot/src/bot/typings/discordeno.ts b/examples/bigbot/src/bot/typings/discordeno.ts index 58a22d82d..fecaf6ec0 100644 --- a/examples/bigbot/src/bot/typings/discordeno.ts +++ b/examples/bigbot/src/bot/typings/discordeno.ts @@ -1,12 +1,12 @@ // This file allows you to tell typescript about any additions you have made to the internal discordeno objects. -import type { Interaction, InteractionCallbackData, InteractionResponse, Message } from "discordeno"; +import type { Interaction, InteractionCallbackData, InteractionResponse, Message } from 'discordeno'; export interface InteractionWithCustomProps extends Interaction { - // Normally, to send a response you would have to do something like bot.helpers.sendInteractionResponse(interaction.id, interaction.token, { type: InteractionResponseTypes.ChannelMessageWithSource, data: { content: "text here" } }) - // But with this reply method we added, it is as simple as interaction.reply("text here"). - // Feel free to delete these comments once you have understood the concept. - /** Send a reply to an interaction. */ - reply: (response: InteractionResponse | string) => Promise; - /** Edit a deferred reply of an interaction. */ - editReply: (response: InteractionCallbackData | string) => Promise; + // Normally, to send a response you would have to do something like bot.helpers.sendInteractionResponse(interaction.id, interaction.token, { type: InteractionResponseTypes.ChannelMessageWithSource, data: { content: "text here" } }) + // But with this reply method we added, it is as simple as interaction.reply("text here"). + // Feel free to delete these comments once you have understood the concept. + /** Send a reply to an interaction. */ + reply: (response: InteractionResponse | string) => Promise; + /** Edit a deferred reply of an interaction. */ + editReply: (response: InteractionCallbackData | string) => Promise; } diff --git a/examples/bigbot/src/bot/utils/collectors.ts b/examples/bigbot/src/bot/utils/collectors.ts index 45a11c5a3..e9e97c2b8 100644 --- a/examples/bigbot/src/bot/utils/collectors.ts +++ b/examples/bigbot/src/bot/utils/collectors.ts @@ -1,151 +1,151 @@ -import type { Interaction, Member, Message } from "discordeno"; -import { bot } from "../bot.js"; +import type { Interaction, Member, Message } from 'discordeno'; +import { bot } from '../bot.js'; export async function needMessage( - memberId: bigint, - channelId: bigint, - options: MessageCollectorOptions & { amount?: 1 }, + memberId: bigint, + channelId: bigint, + options: MessageCollectorOptions & { amount?: 1 }, ): Promise; export async function needMessage( - memberId: bigint, - channelId: bigint, - options: MessageCollectorOptions & { amount?: number }, + memberId: bigint, + channelId: bigint, + options: MessageCollectorOptions & { amount?: number }, ): Promise; export async function needMessage(memberId: bigint, channelId: bigint): Promise; export async function needMessage(memberId: bigint, channelId: bigint, options?: MessageCollectorOptions) { - const messages = await collectMessages({ - key: memberId, - channelId, - createdAt: Date.now(), - filter: options?.filter || ((msg) => memberId === msg.authorId), - amount: options?.amount || 1, - duration: options?.duration || (1000 * 60 * 5), - }); + const messages = await collectMessages({ + key: memberId, + channelId, + createdAt: Date.now(), + filter: options?.filter || ((msg) => memberId === msg.authorId), + amount: options?.amount || 1, + duration: options?.duration || 1000 * 60 * 5, + }); - return (options?.amount || 1) > 1 ? messages : messages[0]; + return (options?.amount || 1) > 1 ? messages : messages[0]; } export async function collectMessages(options: CollectMessagesOptions): Promise { - return await new Promise((resolve, reject) => { - bot.collectors.messages.get(options.key)?.reject( - "A new collector began before the user responded to the previous one.", - ); + return await new Promise((resolve, reject) => { + bot.collectors.messages + .get(options.key) + ?.reject('A new collector began before the user responded to the previous one.'); - bot.collectors.messages.set(options.key, { - ...options, - messages: [], - resolve, - reject, - }); - }); + bot.collectors.messages.set(options.key, { + ...options, + messages: [], + resolve, + reject, + }); + }); } export function processMessageCollectors(message: Message) { - // IGNORE DMS - if (!message.guildId) return; + // IGNORE DMS + if (!message.guildId) return; - const collector = bot.collectors.messages.get(message.authorId); - // This user has no collectors pending or the message is in a different channel - if (!collector || message.channelId !== collector.channelId) return; - // This message is a response to a collector. Now running the filter function. - if (!collector.filter(message)) return; + const collector = bot.collectors.messages.get(message.authorId); + // This user has no collectors pending or the message is in a different channel + if (!collector || message.channelId !== collector.channelId) return; + // This message is a response to a collector. Now running the filter function. + if (!collector.filter(message)) return; - // If the necessary amount has been collected - if (collector.amount === 1 || collector.amount === collector.messages.length + 1) { - // Remove the collector - bot.collectors.messages.delete(message.authorId); - // Resolve the collector - return collector.resolve([...collector.messages, message]); - } + // If the necessary amount has been collected + if (collector.amount === 1 || collector.amount === collector.messages.length + 1) { + // Remove the collector + bot.collectors.messages.delete(message.authorId); + // Resolve the collector + return collector.resolve([...collector.messages, message]); + } - // More messages still need to be collected - collector.messages.push(message); + // More messages still need to be collected + collector.messages.push(message); } export interface BaseCollectorOptions { - /** The amount of messages to collect before resolving. Defaults to 1 */ - amount?: number; - /** The amount of milliseconds this should collect for before expiring. Defaults to 5 minutes. */ - duration?: number; + /** The amount of messages to collect before resolving. Defaults to 1 */ + amount?: number; + /** The amount of milliseconds this should collect for before expiring. Defaults to 5 minutes. */ + duration?: number; } export interface MessageCollectorOptions extends BaseCollectorOptions { - /** Function that will filter messages to determine whether to collect this message. Defaults to making sure the message is sent by the same member. */ - filter?: (message: Message) => boolean; - /** The amount of messages to collect before resolving. Defaults to 1 */ - amount?: number; - /** The amount of milliseconds this should collect for before expiring. Defaults to 5 minutes. */ - duration?: number; + /** Function that will filter messages to determine whether to collect this message. Defaults to making sure the message is sent by the same member. */ + filter?: (message: Message) => boolean; + /** The amount of messages to collect before resolving. Defaults to 1 */ + amount?: number; + /** The amount of milliseconds this should collect for before expiring. Defaults to 5 minutes. */ + duration?: number; } export interface ReactionCollectorOptions extends BaseCollectorOptions { - /** Function that will filter messages to determine whether to collect this message. Defaults to making sure the message is sent by the same member. */ - filter?: (userId: bigint, reaction: string, message: Message | { id: string }) => boolean; + /** Function that will filter messages to determine whether to collect this message. Defaults to making sure the message is sent by the same member. */ + filter?: (userId: bigint, reaction: string, message: Message | { id: string }) => boolean; } export interface BaseCollectorCreateOptions { - /** The unique key that will be used to get responses for this. Ideally, meant to be for member id. */ - key: bigint; - /** The amount of messages to collect before resolving. */ - amount: number; - /** The timestamp when this collector was created */ - createdAt: number; - /** The duration in milliseconds how long this collector should last. */ - duration: number; + /** The unique key that will be used to get responses for this. Ideally, meant to be for member id. */ + key: bigint; + /** The amount of messages to collect before resolving. */ + amount: number; + /** The timestamp when this collector was created */ + createdAt: number; + /** The duration in milliseconds how long this collector should last. */ + duration: number; } export interface CollectMessagesOptions extends BaseCollectorCreateOptions { - /** The channel Id where this is listening to */ - channelId: bigint; - /** Function that will filter messages to determine whether to collect this message */ - filter: (message: Message) => boolean; + /** The channel Id where this is listening to */ + channelId: bigint; + /** Function that will filter messages to determine whether to collect this message */ + filter: (message: Message) => boolean; } export interface CollectReactionsOptions extends BaseCollectorCreateOptions { - /** The message Id where this is listening to */ - messageId: bigint; - /** Function that will filter messages to determine whether to collect this message */ - filter: (userId: bigint, reaction: string, message: Message | { id: string }) => boolean; + /** The message Id where this is listening to */ + messageId: bigint; + /** Function that will filter messages to determine whether to collect this message */ + filter: (userId: bigint, reaction: string, message: Message | { id: string }) => boolean; } export interface MessageCollector extends CollectMessagesOptions { - resolve: (value: Message[] | PromiseLike) => void; - // deno-lint-ignore no-explicit-any - reject: (reason?: any) => void; - /** Where the messages are stored if the amount to collect is more than 1. */ - messages: Message[]; + resolve: (value: Message[] | PromiseLike) => void; + // deno-lint-ignore no-explicit-any + reject: (reason?: any) => void; + /** Where the messages are stored if the amount to collect is more than 1. */ + messages: Message[]; } export interface ReactionCollector extends CollectReactionsOptions { - resolve: (value: string[] | PromiseLike) => void; - // deno-lint-ignore no-explicit-any - reject: (reason?: any) => void; - /** Where the reactions are stored if the amount to collect is more than 1. */ - reactions: string[]; + resolve: (value: string[] | PromiseLike) => void; + // deno-lint-ignore no-explicit-any + reject: (reason?: any) => void; + /** Where the reactions are stored if the amount to collect is more than 1. */ + reactions: string[]; } export interface CollectButtonOptions extends BaseCollectorCreateOptions { - /** The message Id where this is listening to */ - messageId: bigint; - /** Function that will filter messages to determine whether to collect this message */ - filter: (message: Message, member?: Member) => boolean; + /** The message Id where this is listening to */ + messageId: bigint; + /** Function that will filter messages to determine whether to collect this message */ + filter: (message: Message, member?: Member) => boolean; } export interface ButtonCollector extends CollectButtonOptions { - resolve: (value: ButtonCollectorReturn[] | PromiseLike) => void; - // deno-lint-ignore no-explicit-any - reject: (reason?: any) => void; - /** Where the buttons are stored if the amount to collect is more than 1. */ - buttons: ButtonCollectorReturn[]; + resolve: (value: ButtonCollectorReturn[] | PromiseLike) => void; + // deno-lint-ignore no-explicit-any + reject: (reason?: any) => void; + /** Where the buttons are stored if the amount to collect is more than 1. */ + buttons: ButtonCollectorReturn[]; } export interface ButtonCollectorOptions extends BaseCollectorOptions { - /** Function that will filter messages to determine whether to collect this message. Defaults to making sure the message is sent by the same member. */ - filter?: (message: Message, member?: Member) => boolean; + /** Function that will filter messages to determine whether to collect this message. Defaults to making sure the message is sent by the same member. */ + filter?: (message: Message, member?: Member) => boolean; } export interface ButtonCollectorReturn { - customId: string; - interaction: Omit; - member?: Member; + customId: string; + interaction: Omit; + member?: Member; } diff --git a/examples/bigbot/src/bot/utils/internals/mod.ts b/examples/bigbot/src/bot/utils/internals/mod.ts index d5ee2dcdd..d9508bc27 100644 --- a/examples/bigbot/src/bot/utils/internals/mod.ts +++ b/examples/bigbot/src/bot/utils/internals/mod.ts @@ -1,6 +1,6 @@ -import type { BotWithCustomProps } from "../../bot.js"; -import { customizeTransformers } from "./transformers/mod.js"; +import type { BotWithCustomProps } from '../../bot.js'; +import { customizeTransformers } from './transformers/mod.js'; export function customizeInternals(bot: BotWithCustomProps) { - customizeTransformers(bot); + customizeTransformers(bot); } diff --git a/examples/bigbot/src/bot/utils/internals/transformers/guild.ts b/examples/bigbot/src/bot/utils/internals/transformers/guild.ts index 48e0c8f67..a614ead07 100644 --- a/examples/bigbot/src/bot/utils/internals/transformers/guild.ts +++ b/examples/bigbot/src/bot/utils/internals/transformers/guild.ts @@ -2,28 +2,28 @@ // Only keep the properties your bot uses. If your bot does not use emojis in cache, you can save all that memory. // This file is currently disabled, but you can enable it should you choose when you go the customizer file. // Feel free to delete this comment or file as you wish. -import type { Guild } from "discordeno"; -import { Collection } from "discordeno"; -import type { BotWithCustomProps } from "../../../bot.js"; +import type { Guild } from 'discordeno'; +import { Collection } from 'discordeno'; +import type { BotWithCustomProps } from '../../../bot.js'; export function customizeGuildTransformer(bot: BotWithCustomProps) { - bot.transformers.guild = function (bot, payload) { - const guildId = bot.transformers.snowflake(payload.guild.id); + bot.transformers.guild = function (bot, payload) { + const guildId = bot.transformers.snowflake(payload.guild.id); - return { - name: payload.guild.name, - joinedAt: payload.guild.joined_at ? Date.parse(payload.guild.joined_at) : undefined, - memberCount: payload.guild.member_count ?? 0, - shardId: payload.shardId, - icon: payload.guild.icon ? bot.utils.iconHashToBigInt(payload.guild.icon) : undefined, - roles: new Collection( - payload.guild.roles?.map((role) => { - const result = bot.transformers.role(bot, { role, guildId }); - return [result.id, result]; - }), - ), - id: guildId, - ownerId: bot.transformers.snowflake(payload.guild.owner_id), - } as unknown as Guild; - }; + return { + name: payload.guild.name, + joinedAt: payload.guild.joined_at ? Date.parse(payload.guild.joined_at) : undefined, + memberCount: payload.guild.member_count ?? 0, + shardId: payload.shardId, + icon: payload.guild.icon ? bot.utils.iconHashToBigInt(payload.guild.icon) : undefined, + roles: new Collection( + payload.guild.roles?.map((role) => { + const result = bot.transformers.role(bot, { role, guildId }); + return [result.id, result]; + }), + ), + id: guildId, + ownerId: bot.transformers.snowflake(payload.guild.owner_id), + } as unknown as Guild; + }; } diff --git a/examples/bigbot/src/bot/utils/internals/transformers/interaction.ts b/examples/bigbot/src/bot/utils/internals/transformers/interaction.ts index 7e944803f..5129e5485 100644 --- a/examples/bigbot/src/bot/utils/internals/transformers/interaction.ts +++ b/examples/bigbot/src/bot/utils/internals/transformers/interaction.ts @@ -1,40 +1,40 @@ // SETUP-DD-TEMP: This file serves as an example, of how to customize internal discordeno objects. Feel free to use, add more or remove as desired. -import type { InteractionCallbackData, InteractionResponse} from "discordeno"; -import { InteractionResponseTypes } from "discordeno"; -import type { BotWithCustomProps } from "../../../bot.js"; +import type { InteractionCallbackData, InteractionResponse } from 'discordeno'; +import { InteractionResponseTypes } from 'discordeno'; +import type { BotWithCustomProps } from '../../../bot.js'; export function customizeInteractionTransformer(bot: BotWithCustomProps) { - // Store the internal transformer function - const oldInteraction = bot.transformers.interaction; + // Store the internal transformer function + const oldInteraction = bot.transformers.interaction; - // Overwrite the internal function. - bot.transformers.interaction = function (_, payload) { - // Run the old function to get the internal value. - const interaction = oldInteraction(bot, payload); + // Overwrite the internal function. + bot.transformers.interaction = function (_, payload) { + // Run the old function to get the internal value. + const interaction = oldInteraction(bot, payload); - // Add anything to this object. In this case we add a Interaction.reply() method. - Object.defineProperty(interaction, "reply", { - value: function (response: InteractionResponse | string) { - if (typeof response === "string") { - response = { type: InteractionResponseTypes.ChannelMessageWithSource, data: { content: response } }; - } + // Add anything to this object. In this case we add a Interaction.reply() method. + Object.defineProperty(interaction, 'reply', { + value: function (response: InteractionResponse | string) { + if (typeof response === 'string') { + response = { type: InteractionResponseTypes.ChannelMessageWithSource, data: { content: response } }; + } - return bot.helpers.sendInteractionResponse(interaction.id, interaction.token, response); - }, - }); - Object.defineProperty(interaction, "editReply", { - value: function (response: InteractionCallbackData | string) { - if (typeof response === "string") { - response = { content: response }; - } + return bot.helpers.sendInteractionResponse(interaction.id, interaction.token, response); + }, + }); + Object.defineProperty(interaction, 'editReply', { + value: function (response: InteractionCallbackData | string) { + if (typeof response === 'string') { + response = { content: response }; + } - return bot.helpers.editOriginalInteractionResponse(interaction.token, response); - }, - }); - // Add as many properties or methods you would like here. - // NOTE: Whenever you add anything here, in order to get nice autocomplete you should also add it to the src/types/discordeno.ts file. + return bot.helpers.editOriginalInteractionResponse(interaction.token, response); + }, + }); + // Add as many properties or methods you would like here. + // NOTE: Whenever you add anything here, in order to get nice autocomplete you should also add it to the src/types/discordeno.ts file. - // Return the new customized object. - return interaction; - }; + // Return the new customized object. + return interaction; + }; } diff --git a/examples/bigbot/src/bot/utils/internals/transformers/mod.ts b/examples/bigbot/src/bot/utils/internals/transformers/mod.ts index bcf7160ea..f3c3d4c84 100644 --- a/examples/bigbot/src/bot/utils/internals/transformers/mod.ts +++ b/examples/bigbot/src/bot/utils/internals/transformers/mod.ts @@ -1,10 +1,10 @@ -import type { BotWithCustomProps } from "../../../bot.js"; +import type { BotWithCustomProps } from '../../../bot.js'; // SETUP-DD-TEMP: Enable this comment if you want to enable this customizer. // import { customizeGuildTransformer } from "./guild.js"; -import { customizeInteractionTransformer } from "./interaction.js"; +import { customizeInteractionTransformer } from './interaction.js'; export function customizeTransformers(bot: BotWithCustomProps) { - customizeInteractionTransformer(bot); - // SETUP-DD-TEMP: Enable this comment if you want to enable this customizer. - // customizeGuildTransformer(bot); + customizeInteractionTransformer(bot); + // SETUP-DD-TEMP: Enable this comment if you want to enable this customizer. + // customizeGuildTransformer(bot); } diff --git a/examples/bigbot/src/bot/utils/slash/createCommand.ts b/examples/bigbot/src/bot/utils/slash/createCommand.ts index a48a6f5a1..0d2747a23 100644 --- a/examples/bigbot/src/bot/utils/slash/createCommand.ts +++ b/examples/bigbot/src/bot/utils/slash/createCommand.ts @@ -1,21 +1,21 @@ import type { - ApplicationCommandOptionTypes, - ApplicationCommandTypes, - Bot, - Channel, - Interaction, - Member, - PermissionStrings, - Role, - User, -} from "discordeno"; -import type english from "../../languages/english.js"; -import type { translationKeys } from "../../languages/translate.js"; -import type { InteractionWithCustomProps } from "../../typings/discordeno.js"; -import type { PermissionLevelHandlers } from "./permLevels.js"; + ApplicationCommandOptionTypes, + ApplicationCommandTypes, + Bot, + Channel, + Interaction, + Member, + PermissionStrings, + Role, + User, +} from 'discordeno'; +import type english from '../../languages/english.js'; +import type { translationKeys } from '../../languages/translate.js'; +import type { InteractionWithCustomProps } from '../../typings/discordeno.js'; +import type { PermissionLevelHandlers } from './permLevels.js'; export function createCommand(command: Command) { - return command; + return command; } type UnionToIntersection = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never; @@ -25,268 +25,283 @@ type Identity = { [P in keyof T]: T[P] }; // TODO: make required by default true // Define each of the types here interface BaseDefinition { - description: translationKeys; + description: translationKeys; } // Subcommand type SubcommandArgumentDefinition = BaseDefinition & { - name: N; - type: ApplicationCommandOptionTypes.SubCommand; - // options: Omit[] - options?: readonly ArgumentDefinition[]; + name: N; + type: ApplicationCommandOptionTypes.SubCommand; + // options: Omit[] + options?: readonly ArgumentDefinition[]; }; // SubcommandGroup type SubcommandGroupArgumentDefinition = BaseDefinition & { - name: N; - type: ApplicationCommandOptionTypes.SubCommandGroup; - options: readonly SubcommandArgumentDefinition[]; + name: N; + type: ApplicationCommandOptionTypes.SubCommandGroup; + options: readonly SubcommandArgumentDefinition[]; }; // String type StringArgumentDefinition = BaseDefinition & { - name: N; - type: ApplicationCommandOptionTypes.String; - choices?: ReadonlyArray<{ name: string; value: string }>; - required?: true; + name: N; + type: ApplicationCommandOptionTypes.String; + choices?: ReadonlyArray<{ name: string; value: string }>; + required?: true; }; type StringOptionalArgumentDefinition = BaseDefinition & { - name: N; - type: ApplicationCommandOptionTypes.String; - choices?: ReadonlyArray<{ name: string; value: string }>; - required?: false; + name: N; + type: ApplicationCommandOptionTypes.String; + choices?: ReadonlyArray<{ name: string; value: string }>; + required?: false; }; // Integer type IntegerArgumentDefinition = BaseDefinition & { - name: N; - type: ApplicationCommandOptionTypes.Integer; - choices?: ReadonlyArray<{ name: string; value: number }>; - required: true; + name: N; + type: ApplicationCommandOptionTypes.Integer; + choices?: ReadonlyArray<{ name: string; value: number }>; + required: true; }; type IntegerOptionalArgumentDefinition = BaseDefinition & { - name: N; - type: ApplicationCommandOptionTypes.Integer; - choices?: ReadonlyArray<{ name: string; value: number }>; - required?: false; + name: N; + type: ApplicationCommandOptionTypes.Integer; + choices?: ReadonlyArray<{ name: string; value: number }>; + required?: false; }; // BOOLEAN type BooleanArgumentDefinition = BaseDefinition & { - name: N; - type: ApplicationCommandOptionTypes.Boolean; - required: true; + name: N; + type: ApplicationCommandOptionTypes.Boolean; + required: true; }; type BooleanOptionalArgumentDefinition = BaseDefinition & { - name: N; - type: ApplicationCommandOptionTypes.Boolean; - required?: false; + name: N; + type: ApplicationCommandOptionTypes.Boolean; + required?: false; }; // USER type UserArgumentDefinition = BaseDefinition & { - name: N; - type: ApplicationCommandOptionTypes.User; - required: true; + name: N; + type: ApplicationCommandOptionTypes.User; + required: true; }; type UserOptionalArgumentDefinition = BaseDefinition & { - name: N; - type: ApplicationCommandOptionTypes.User; - required?: false; + name: N; + type: ApplicationCommandOptionTypes.User; + required?: false; }; // CHANNEL type ChannelArgumentDefinition = BaseDefinition & { - name: N; - type: ApplicationCommandOptionTypes.Channel; - required: true; + name: N; + type: ApplicationCommandOptionTypes.Channel; + required: true; }; type ChannelOptionalArgumentDefinition = BaseDefinition & { - name: N; - type: ApplicationCommandOptionTypes.Channel; - required?: false; + name: N; + type: ApplicationCommandOptionTypes.Channel; + required?: false; }; // ROLE type RoleArgumentDefinition = BaseDefinition & { - name: N; - type: ApplicationCommandOptionTypes.Role; - required: true; + name: N; + type: ApplicationCommandOptionTypes.Role; + required: true; }; type RoleOptionalArgumentDefinition = BaseDefinition & { - name: N; - type: ApplicationCommandOptionTypes.Role; - required?: false; + name: N; + type: ApplicationCommandOptionTypes.Role; + required?: false; }; // MENTIONABLE type MentionableArgumentDefinition = BaseDefinition & { - name: N; - type: ApplicationCommandOptionTypes.Mentionable; - required: true; + name: N; + type: ApplicationCommandOptionTypes.Mentionable; + required: true; }; type MentionableOptionalArgumentDefinition = BaseDefinition & { - name: N; - type: ApplicationCommandOptionTypes.Mentionable; - required?: false; + name: N; + type: ApplicationCommandOptionTypes.Mentionable; + required?: false; }; // Add each of known ArgumentDefinitions to this union. export type ArgumentDefinition = - | StringArgumentDefinition - | StringOptionalArgumentDefinition - | IntegerArgumentDefinition - | IntegerOptionalArgumentDefinition - | BooleanArgumentDefinition - | BooleanOptionalArgumentDefinition - | UserArgumentDefinition - | UserOptionalArgumentDefinition - | ChannelArgumentDefinition - | ChannelOptionalArgumentDefinition - | RoleArgumentDefinition - | RoleOptionalArgumentDefinition - | MentionableArgumentDefinition - | MentionableOptionalArgumentDefinition - | SubcommandArgumentDefinition - | SubcommandGroupArgumentDefinition; + | StringArgumentDefinition + | StringOptionalArgumentDefinition + | IntegerArgumentDefinition + | IntegerOptionalArgumentDefinition + | BooleanArgumentDefinition + | BooleanOptionalArgumentDefinition + | UserArgumentDefinition + | UserOptionalArgumentDefinition + | ChannelArgumentDefinition + | ChannelOptionalArgumentDefinition + | RoleArgumentDefinition + | RoleOptionalArgumentDefinition + | MentionableArgumentDefinition + | MentionableOptionalArgumentDefinition + | SubcommandArgumentDefinition + | SubcommandGroupArgumentDefinition; type getName = typeof english[K] extends string ? typeof english[K] : never; // OPTIONALS MUST BE FIRST!!! export type ConvertArgumentDefinitionsToArgs = Identity< - UnionToIntersection< - { - [P in keyof T]: T[P] extends StringOptionalArgumentDefinition // STRING - ? { - // @ts-expect-error TODO: fix this some day - [_ in getName]?: T[P]["choices"] extends ReadonlyArray<{ name: string; value: string }> // @ts-expect-error - ? T[P]["choices"][number]["value"] - : string; - } - : T[P] extends StringArgumentDefinition ? { - // @ts-expect-error TODO: fix this some day - [_ in getName]: T[P]["choices"] extends ReadonlyArray<{ name: string; value: string }> // @ts-expect-error - ? T[P]["choices"][number]["value"] - : string; - } - // INTEGER - : T[P] extends IntegerOptionalArgumentDefinition ? { - [_ in getName]?: T[P]["choices"] extends ReadonlyArray<{ name: string; value: number }> // @ts-expect-error - ? T[P]["choices"][number]["value"] - : number; - } - : T[P] extends IntegerArgumentDefinition ? { - [_ in getName]: T[P]["choices"] extends ReadonlyArray<{ name: string; value: number }> // @ts-expect-error - ? T[P]["choices"][number]["value"] - : number; - } - // BOOLEAN - : T[P] extends BooleanOptionalArgumentDefinition ? { [_ in getName]?: boolean } - : T[P] extends BooleanArgumentDefinition ? { [_ in getName]: boolean } - // USER - : T[P] extends UserOptionalArgumentDefinition ? { - [_ in getName]?: { - user: User; - member: Member; - }; - } - : T[P] extends UserArgumentDefinition ? { - [_ in getName]: { - user: User; - member: Member; - }; - } - // CHANNEL - : T[P] extends ChannelOptionalArgumentDefinition ? { [_ in getName]?: Channel } - : T[P] extends ChannelArgumentDefinition ? { [_ in getName]: Channel } - // ROLE - : T[P] extends RoleOptionalArgumentDefinition ? { [_ in getName]?: Role } - : T[P] extends RoleArgumentDefinition ? { [_ in getName]: Role } - // MENTIONABLE - : T[P] extends MentionableOptionalArgumentDefinition ? { - [_ in getName]?: - | Role - | { - user: User; - member: Member; - }; - } - : T[P] extends MentionableArgumentDefinition ? { - [_ in getName]: - | Role - | { - user: User; - member: Member; - }; - } - // SUBCOMMAND - : T[P] extends SubcommandArgumentDefinition ? { - [_ in getName]?: T[P]["options"] extends readonly ArgumentDefinition[] // @ts-expect-error somehow this check does not work - ? ConvertArgumentDefinitionsToArgs - : {}; - } - // SUBCOMMANDGROUP - : T[P] extends SubcommandGroupArgumentDefinition ? { - [_ in getName]?: ConvertArgumentDefinitionsToArgs; - } - : never; - }[number] - > + UnionToIntersection< + { + [P in keyof T]: T[P] extends StringOptionalArgumentDefinition // STRING + ? { + // @ts-expect-error TODO: fix this some day + [_ in getName]?: T[P]['choices'] extends ReadonlyArray<{ name: string; value: string }> // @ts-expect-error + ? T[P]['choices'][number]['value'] + : string; + } + : T[P] extends StringArgumentDefinition + ? { + // @ts-expect-error TODO: fix this some day + [_ in getName]: T[P]['choices'] extends ReadonlyArray<{ name: string; value: string }> // @ts-expect-error + ? T[P]['choices'][number]['value'] + : string; + } + : // INTEGER + T[P] extends IntegerOptionalArgumentDefinition + ? { + [_ in getName]?: T[P]['choices'] extends ReadonlyArray<{ name: string; value: number }> // @ts-expect-error + ? T[P]['choices'][number]['value'] + : number; + } + : T[P] extends IntegerArgumentDefinition + ? { + [_ in getName]: T[P]['choices'] extends ReadonlyArray<{ name: string; value: number }> // @ts-expect-error + ? T[P]['choices'][number]['value'] + : number; + } + : // BOOLEAN + T[P] extends BooleanOptionalArgumentDefinition + ? { [_ in getName]?: boolean } + : T[P] extends BooleanArgumentDefinition + ? { [_ in getName]: boolean } + : // USER + T[P] extends UserOptionalArgumentDefinition + ? { + [_ in getName]?: { + user: User; + member: Member; + }; + } + : T[P] extends UserArgumentDefinition + ? { + [_ in getName]: { + user: User; + member: Member; + }; + } + : // CHANNEL + T[P] extends ChannelOptionalArgumentDefinition + ? { [_ in getName]?: Channel } + : T[P] extends ChannelArgumentDefinition + ? { [_ in getName]: Channel } + : // ROLE + T[P] extends RoleOptionalArgumentDefinition + ? { [_ in getName]?: Role } + : T[P] extends RoleArgumentDefinition + ? { [_ in getName]: Role } + : // MENTIONABLE + T[P] extends MentionableOptionalArgumentDefinition + ? { + [_ in getName]?: + | Role + | { + user: User; + member: Member; + }; + } + : T[P] extends MentionableArgumentDefinition + ? { + [_ in getName]: + | Role + | { + user: User; + member: Member; + }; + } + : // SUBCOMMAND + T[P] extends SubcommandArgumentDefinition + ? { + [_ in getName]?: T[P]['options'] extends readonly ArgumentDefinition[] // @ts-expect-error somehow this check does not work + ? ConvertArgumentDefinitionsToArgs + : {}; + } + : // SUBCOMMANDGROUP + T[P] extends SubcommandGroupArgumentDefinition + ? { + [_ in getName]?: ConvertArgumentDefinitionsToArgs; + } + : never; + }[number] + > >; export interface Command { - /** The name of the command, used for both slash and message commands. */ - name: translationKeys; - /** The type of command. */ - type?: ApplicationCommandTypes; - /** The description of the command */ - description: translationKeys; - // TODO: consider type being a string like "number" | "user" for better ux - /** The options for the command, used for both slash and message commands. */ - // options?: ApplicationCommandOption[]; - options?: T; - execute: (bot: Bot, data: InteractionWithCustomProps, args: ConvertArgumentDefinitionsToArgs) => unknown; - subcommands?: Record, "subcommands"> & { group?: string }>; - /** Whether the command should have a cooldown */ - cooldown?: { - /** How long the user needs to wait after the first execution until he can use the command again */ - seconds: number; - /** How often the user is allowed to use the command until he is in cooldown */ - allowedUses?: number; - }; - nsfw?: boolean; - /** By default false */ - global?: boolean; - /** Dm only by default false */ - dmOnly?: boolean; + /** The name of the command, used for both slash and message commands. */ + name: translationKeys; + /** The type of command. */ + type?: ApplicationCommandTypes; + /** The description of the command */ + description: translationKeys; + // TODO: consider type being a string like "number" | "user" for better ux + /** The options for the command, used for both slash and message commands. */ + // options?: ApplicationCommandOption[]; + options?: T; + execute: (bot: Bot, data: InteractionWithCustomProps, args: ConvertArgumentDefinitionsToArgs) => unknown; + subcommands?: Record, 'subcommands'> & { group?: string }>; + /** Whether the command should have a cooldown */ + cooldown?: { + /** How long the user needs to wait after the first execution until he can use the command again */ + seconds: number; + /** How often the user is allowed to use the command until he is in cooldown */ + allowedUses?: number; + }; + nsfw?: boolean; + /** By default false */ + global?: boolean; + /** Dm only by default false */ + dmOnly?: boolean; - /** VIP only by default false */ - vipOnly?: boolean; + /** VIP only by default false */ + vipOnly?: boolean; - advanced?: boolean; + advanced?: boolean; - /** Whether or not this slash command should be enabled right now. Defaults to true. */ - enabled?: boolean; - /** Whether or not this command is still in development and should be setup in the dev server for testing. */ - dev?: boolean; - /** Whether or not this command will take longer than 3s and need to acknowledge to discord. */ - acknowledge?: boolean; + /** Whether or not this slash command should be enabled right now. Defaults to true. */ + enabled?: boolean; + /** Whether or not this command is still in development and should be setup in the dev server for testing. */ + dev?: boolean; + /** Whether or not this command will take longer than 3s and need to acknowledge to discord. */ + acknowledge?: boolean; - permissionLevels?: - | Array - | ((data: Interaction, command: Command) => boolean | Promise); - botServerPermissions?: PermissionStrings[]; - botChannelPermissions?: PermissionStrings[]; - userServerPermissions?: PermissionStrings[]; - userChannelPermissions?: PermissionStrings[]; + permissionLevels?: + | Array + | ((data: Interaction, command: Command) => boolean | Promise); + botServerPermissions?: PermissionStrings[]; + botChannelPermissions?: PermissionStrings[]; + userServerPermissions?: PermissionStrings[]; + userChannelPermissions?: PermissionStrings[]; } export enum PermissionLevels { - Member, - Moderator, - Admin, - ServerOwner, - BotSupporter, - BotDev, - BotOwner, + Member, + Moderator, + Admin, + ServerOwner, + BotSupporter, + BotDev, + BotOwner, } diff --git a/examples/bigbot/src/bot/utils/slash/limiter.ts b/examples/bigbot/src/bot/utils/slash/limiter.ts index 07533466c..d6cb48ccc 100644 --- a/examples/bigbot/src/bot/utils/slash/limiter.ts +++ b/examples/bigbot/src/bot/utils/slash/limiter.ts @@ -1,29 +1,31 @@ -import COMMANDS from "../../commands/mod.js"; +import COMMANDS from '../../commands/mod.js'; export async function validateSlashLimits() { - const MAX_ALLOWED_CHARACTERS = 4000; + const MAX_ALLOWED_CHARACTERS = 4000; - const commands = await fetch("https://cmd-counter-play.deno.dev/", { - body: JSON.stringify(COMMANDS), - headers: { - "content-type": "application/json", - }, - }).then(async (res) => await res.json()).catch(() => undefined); + const commands = await fetch('https://cmd-counter-play.deno.dev/', { + body: JSON.stringify(COMMANDS), + headers: { + 'content-type': 'application/json', + }, + }) + .then(async (res) => await res.json()) + .catch(() => undefined); - if (!commands) return; + if (!commands) return; - const invalidCommandNames: string[] = []; + const invalidCommandNames: string[] = []; - if (commands[0]?.characters > MAX_ALLOWED_CHARACTERS) { - for (const command of commands) { - if (command.characters <= MAX_ALLOWED_CHARACTERS) continue; + if (commands[0]?.characters > MAX_ALLOWED_CHARACTERS) { + for (const command of commands) { + if (command.characters <= MAX_ALLOWED_CHARACTERS) continue; - invalidCommandNames.push(command.name); - console.log( - `[Invalid Command] The ${command.name} is not a valid command. It's total characters are (${command.characters}) which is more than the max allowed ${MAX_ALLOWED_CHARACTERS}.`, - ); - } - } + invalidCommandNames.push(command.name); + console.log( + `[Invalid Command] The ${command.name} is not a valid command. It's total characters are (${command.characters}) which is more than the max allowed ${MAX_ALLOWED_CHARACTERS}.`, + ); + } + } - if (invalidCommandNames.length) throw new Error(`[Startup] Invalid commands: ${invalidCommandNames.join(", ")}`); + if (invalidCommandNames.length) throw new Error(`[Startup] Invalid commands: ${invalidCommandNames.join(', ')}`); } diff --git a/examples/bigbot/src/bot/utils/slash/permLevels.ts b/examples/bigbot/src/bot/utils/slash/permLevels.ts index 1dd939ee4..38cc3a70f 100644 --- a/examples/bigbot/src/bot/utils/slash/permLevels.ts +++ b/examples/bigbot/src/bot/utils/slash/permLevels.ts @@ -1,48 +1,48 @@ -import type { Interaction } from "discordeno"; -import { validatePermissions } from "discordeno/permissions-plugin"; -import type { Command } from "./createCommand.js"; +import type { Interaction } from 'discordeno'; +import { validatePermissions } from 'discordeno/permissions-plugin'; +import type { Command } from './createCommand.js'; export default async function hasPermissionLevel(command: Command, payload: Interaction) { - // This command doesnt require a perm level so allow the command. - if (!command.permissionLevels) return true; + // This command doesnt require a perm level so allow the command. + if (!command.permissionLevels) return true; - // If a custom function was provided - if (typeof command.permissionLevels === "function") { - return await command.permissionLevels(payload, command); - } + // If a custom function was provided + if (typeof command.permissionLevels === 'function') { + return await command.permissionLevels(payload, command); + } - // If an array of perm levels was provided - for (const permlevel of command.permissionLevels) { - // If this user has one of the allowed perm level, the loop is canceled and command is allowed. - if (await PermissionLevelHandlers[permlevel](payload, command)) return true; - } + // If an array of perm levels was provided + for (const permlevel of command.permissionLevels) { + // If this user has one of the allowed perm level, the loop is canceled and command is allowed. + if (await PermissionLevelHandlers[permlevel](payload, command)) return true; + } - // None of the perm levels were met. So cancel the command - return false; + // None of the perm levels were met. So cancel the command + return false; } export const PermissionLevelHandlers: Record< - keyof typeof PermissionLevels, - (payload: Interaction, command: Command) => boolean | Promise + keyof typeof PermissionLevels, + (payload: Interaction, command: Command) => boolean | Promise > = { - MEMBER: () => true, - MODERATOR: (payload) => - Boolean(payload.member?.permissions) && validatePermissions(payload.member!.permissions!, ["MANAGE_GUILD"]), - ADMIN: (payload) => - Boolean(payload.member?.permissions) && validatePermissions(payload.member!.permissions!, ["ADMINISTRATOR"]), - // TODO(cache): fix this - SERVER_OWNER: () => false, - BOT_SUPPORT: () => false, - BOT_DEVS: () => false, - BOT_OWNERS: (payload) => [130136895395987456n, 615542460151496705n].includes(payload.user.id), + MEMBER: () => true, + MODERATOR: (payload) => + Boolean(payload.member?.permissions) && validatePermissions(payload.member!.permissions!, ['MANAGE_GUILD']), + ADMIN: (payload) => + Boolean(payload.member?.permissions) && validatePermissions(payload.member!.permissions!, ['ADMINISTRATOR']), + // TODO(cache): fix this + SERVER_OWNER: () => false, + BOT_SUPPORT: () => false, + BOT_DEVS: () => false, + BOT_OWNERS: (payload) => [130136895395987456n, 615542460151496705n].includes(payload.user.id), }; export enum PermissionLevels { - MEMBER, - MODERATOR, - ADMIN, - SERVER_OWNER, - BOT_SUPPORT, - BOT_DEVS, - BOT_OWNERS, + MEMBER, + MODERATOR, + ADMIN, + SERVER_OWNER, + BOT_SUPPORT, + BOT_DEVS, + BOT_OWNERS, } diff --git a/examples/bigbot/src/bot/utils/slash/updateCommands.ts b/examples/bigbot/src/bot/utils/slash/updateCommands.ts index a4f82a9bd..43bc9d69a 100644 --- a/examples/bigbot/src/bot/utils/slash/updateCommands.ts +++ b/examples/bigbot/src/bot/utils/slash/updateCommands.ts @@ -1,43 +1,43 @@ -import type { ApplicationCommandOption, Bot } from "discordeno"; -import { ApplicationCommandTypes } from "discordeno"; -import { prisma } from "../../../prisma.js"; -import { bot } from "../../bot.js"; -import COMMANDS from "../../commands/mod.js"; -import { serverLanguages, translate } from "../../languages/translate.js"; -import type { ArgumentDefinition } from "./createCommand.js"; +import type { ApplicationCommandOption, Bot } from 'discordeno'; +import { ApplicationCommandTypes } from 'discordeno'; +import { prisma } from '../../../prisma.js'; +import { bot } from '../../bot.js'; +import COMMANDS from '../../commands/mod.js'; +import { serverLanguages, translate } from '../../languages/translate.js'; +import type { ArgumentDefinition } from './createCommand.js'; const DEV_SERVER_ID = process.env.DEV_SERVER_ID as string; export async function updateDevCommands(bot: Bot) { - const cmds = Object.entries(COMMANDS) - // ONLY DEV COMMANDS - .filter(([_name, command]) => command?.dev); + const cmds = Object.entries(COMMANDS) + // ONLY DEV COMMANDS + .filter(([_name, command]) => command?.dev); - if (!cmds.length) return; + if (!cmds.length) return; - // DEV RELATED COMMANDS, USE upsertGlobalApplicationCommands TO UPDATE GLOBALLY - await bot.helpers.upsertGuildApplicationCommands( - bot.transformers.snowflake(DEV_SERVER_ID), - cmds.map(([name, command]) => { - const translatedName = translate(DEV_SERVER_ID, command.name); - const translatedDescription = command.description ? translate(DEV_SERVER_ID, command.description) : ""; + // DEV RELATED COMMANDS, USE upsertGlobalApplicationCommands TO UPDATE GLOBALLY + await bot.helpers.upsertGuildApplicationCommands( + bot.transformers.snowflake(DEV_SERVER_ID), + cmds.map(([name, command]) => { + const translatedName = translate(DEV_SERVER_ID, command.name); + const translatedDescription = command.description ? translate(DEV_SERVER_ID, command.description) : ''; - if (command.type && command.type !== ApplicationCommandTypes.ChatInput) { - return { - name: (translatedName || name).toLowerCase(), - type: command.type, - }; - } + if (command.type && command.type !== ApplicationCommandTypes.ChatInput) { + return { + name: (translatedName || name).toLowerCase(), + type: command.type, + }; + } - return { - name: (translatedName || name).toLowerCase(), - description: translatedDescription || command.description, - options: command.options - ? createOptions(bot.transformers.snowflake(DEV_SERVER_ID), command.options, command.name) - : undefined, - }; - }), - ); + return { + name: (translatedName || name).toLowerCase(), + description: translatedDescription || command.description, + options: command.options + ? createOptions(bot.transformers.snowflake(DEV_SERVER_ID), command.options, command.name) + : undefined, + }; + }), + ); } // SETUP-DD-TEMP: You can make this able to be updated dynicamally by moving this value to something in the database and having a command to update it on the fly or as part of CI. @@ -45,63 +45,63 @@ export const CURRENT_SLASH_COMMAND_VERSION = 1; /** Whether the guild has the latest slash command version */ export async function usesLatestCommandVersion(guildId: bigint): Promise { - return (await getCurrentCommandVersion(guildId)) === CURRENT_SLASH_COMMAND_VERSION; + return (await getCurrentCommandVersion(guildId)) === CURRENT_SLASH_COMMAND_VERSION; } /** Get the current slash command version for this guild */ export async function getCurrentCommandVersion(guildId: bigint): Promise { - if (bot.commandVersions.has(guildId)) return bot.commandVersions.get(guildId)!; + if (bot.commandVersions.has(guildId)) return bot.commandVersions.get(guildId)!; - const commandVersion = await prisma.commands.findUnique({ where: { id: guildId } }); - if (commandVersion) bot.commandVersions.set(guildId, commandVersion.version); + const commandVersion = await prisma.commands.findUnique({ where: { id: guildId } }); + if (commandVersion) bot.commandVersions.set(guildId, commandVersion.version); - return commandVersion?.version ?? 0; + return commandVersion?.version ?? 0; } export async function updateCommandVersion(guildId: bigint): Promise { - // UPDATE THE VERSION SAVED IN THE DB - await prisma.commands.upsert({ - where: { id: guildId }, - create: { id: guildId, version: CURRENT_SLASH_COMMAND_VERSION }, - update: { version: CURRENT_SLASH_COMMAND_VERSION }, - }); + // UPDATE THE VERSION SAVED IN THE DB + await prisma.commands.upsert({ + where: { id: guildId }, + create: { id: guildId, version: CURRENT_SLASH_COMMAND_VERSION }, + update: { version: CURRENT_SLASH_COMMAND_VERSION }, + }); - bot.commandVersions.set(guildId, CURRENT_SLASH_COMMAND_VERSION); - return CURRENT_SLASH_COMMAND_VERSION; + bot.commandVersions.set(guildId, CURRENT_SLASH_COMMAND_VERSION); + return CURRENT_SLASH_COMMAND_VERSION; } export async function updateGuildCommands(bot: Bot, guildId: bigint) { - if (guildId === 547046977578336286n) return await updateDevCommands(bot); + if (guildId === 547046977578336286n) return await updateDevCommands(bot); - await updateCommandVersion(guildId); + await updateCommandVersion(guildId); - // GUILD RELATED COMMANDS - await bot.helpers.upsertGuildApplicationCommands( - guildId, - Object.entries(COMMANDS) - // ONLY GUILD COMMANDS - .filter(([_name, command]) => !command.global && !command.dev) - .map(([name, command]) => { - // USER OPTED TO USE BASIC VERSION ONLY - if (command.advanced === false) { - return { - name, - description: translate("english", command.description), - options: command.options ? createOptions("english", command.options, command.name) : undefined, - }; - } + // GUILD RELATED COMMANDS + await bot.helpers.upsertGuildApplicationCommands( + guildId, + Object.entries(COMMANDS) + // ONLY GUILD COMMANDS + .filter(([_name, command]) => !command.global && !command.dev) + .map(([name, command]) => { + // USER OPTED TO USE BASIC VERSION ONLY + if (command.advanced === false) { + return { + name, + description: translate('english', command.description), + options: command.options ? createOptions('english', command.options, command.name) : undefined, + }; + } - // ADVANCED VERSION WILL ALLOW TRANSLATION - const translatedName = translate(guildId, command.name); - const translatedDescription = translate(guildId, command.description); + // ADVANCED VERSION WILL ALLOW TRANSLATION + const translatedName = translate(guildId, command.name); + const translatedDescription = translate(guildId, command.description); - return { - name: translatedName.toLowerCase(), - description: translatedDescription, - options: command.options ? createOptions(guildId, command.options, command.name) : undefined, - }; - }), - ); + return { + name: translatedName.toLowerCase(), + description: translatedDescription, + options: command.options ? createOptions(guildId, command.options, command.name) : undefined, + }; + }), + ); } // USED TO CACHE CONVERTED COMMANDS AFTER START TO PREVENT UNNECESSARY LOOPS @@ -109,41 +109,41 @@ const convertedCache = new Map(); /** Creates the commands options including subcommands. Also translates them. */ function createOptions( - guildId: bigint | "english", - options: readonly ArgumentDefinition[], - commandName?: string, + guildId: bigint | 'english', + options: readonly ArgumentDefinition[], + commandName?: string, ): ApplicationCommandOption[] | undefined { - const language = guildId === "english" ? "english" : serverLanguages.get(guildId) ?? "english"; - if (commandName && convertedCache.has(`${language}-${commandName}`)) { - return convertedCache.get(`${language}-${commandName}`)!; - } + const language = guildId === 'english' ? 'english' : serverLanguages.get(guildId) ?? 'english'; + if (commandName && convertedCache.has(`${language}-${commandName}`)) { + return convertedCache.get(`${language}-${commandName}`)!; + } - const newOptions: ApplicationCommandOption[] = []; + const newOptions: ApplicationCommandOption[] = []; - for (const option of options || []) { - const optionName = translate(guildId, option.name); - const optionDescription = translate(guildId, option.description); + for (const option of options || []) { + const optionName = translate(guildId, option.name); + const optionDescription = translate(guildId, option.description); - // TODO: remove this ts ignore - // @ts-expect-error - const choices = option.choices?.map((choice) => ({ - ...choice, - name: translate(guildId, choice.name), - })); + // TODO: remove this ts ignore + // @ts-expect-error + const choices = option.choices?.map((choice) => ({ + ...choice, + name: translate(guildId, choice.name), + })); - newOptions.push({ - ...option, - name: optionName.toLowerCase(), - description: optionDescription || "No description available.", - choices, - // @ts-expect-error fix this - options: option.options - // @ts-expect-error fix this - ? createOptions(bot, guildId, option.options) - : undefined, - } as ApplicationCommandOption); - } - if (commandName) convertedCache.set(`${language}-${commandName}`, newOptions); + newOptions.push({ + ...option, + name: optionName.toLowerCase(), + description: optionDescription || 'No description available.', + choices, + // @ts-expect-error fix this + options: option.options + ? // @ts-expect-error fix this + createOptions(bot, guildId, option.options) + : undefined, + } as ApplicationCommandOption); + } + if (commandName) convertedCache.set(`${language}-${commandName}`, newOptions); - return newOptions; + return newOptions; } diff --git a/examples/bigbot/src/bot/utils/webhook.ts b/examples/bigbot/src/bot/utils/webhook.ts index 079fee05e..b4897f0a6 100644 --- a/examples/bigbot/src/bot/utils/webhook.ts +++ b/examples/bigbot/src/bot/utils/webhook.ts @@ -1,11 +1,9 @@ /** Get the webhook id and token from a webhook url. */ export function webhookURLToIDAndToken(url: string) { - const [id, token] = url.substring(url.indexOf("webhooks/") + 9).split( - "/", - ); + const [id, token] = url.substring(url.indexOf('webhooks/') + 9).split('/'); - return { - id, - token, - }; + return { + id, + token, + }; } diff --git a/examples/bigbot/src/configs.ts b/examples/bigbot/src/configs.ts index f9bc3a955..dc185ea76 100644 --- a/examples/bigbot/src/configs.ts +++ b/examples/bigbot/src/configs.ts @@ -1,5 +1,5 @@ -import { getBotIdFromToken, Intents } from "discordeno"; -import dotenv from "dotenv"; +import { getBotIdFromToken, Intents } from 'discordeno'; +import dotenv from 'dotenv'; dotenv.config(); /** The bot id, derived from the bot token. */ @@ -11,19 +11,19 @@ export const GATEWAY_URL = `http://${process.env.GATEWAY_HOST}:${process.env.GAT // Gateway Proxy Configurations /** The gateway intents you would like to use. */ export const INTENTS: Intents = - // SETUP-DD-TEMP: Add the intents you want enabled here. Or Delete the intents you don't want in your bot. - Intents.DirectMessageReactions | - Intents.DirectMessageTyping | - Intents.DirectMessages | - Intents.GuildBans | - Intents.GuildEmojis | - Intents.GuildIntegrations | - Intents.GuildInvites | - Intents.GuildMembers | - Intents.GuildMessageReactions | - Intents.GuildMessageTyping | - Intents.GuildMessages | - Intents.GuildPresences | - Intents.GuildVoiceStates | - Intents.GuildWebhooks | - Intents.Guilds; + // SETUP-DD-TEMP: Add the intents you want enabled here. Or Delete the intents you don't want in your bot. + Intents.DirectMessageReactions | + Intents.DirectMessageTyping | + Intents.DirectMessages | + Intents.GuildBans | + Intents.GuildEmojis | + Intents.GuildIntegrations | + Intents.GuildInvites | + Intents.GuildMembers | + Intents.GuildMessageReactions | + Intents.GuildMessageTyping | + Intents.GuildMessages | + Intents.GuildPresences | + Intents.GuildVoiceStates | + Intents.GuildWebhooks | + Intents.Guilds; diff --git a/examples/bigbot/src/gateway/index.ts b/examples/bigbot/src/gateway/index.ts index f10247c28..3ca1eece8 100644 --- a/examples/bigbot/src/gateway/index.ts +++ b/examples/bigbot/src/gateway/index.ts @@ -1,12 +1,18 @@ -import dotenv from "dotenv"; +import dotenv from 'dotenv'; -import { Collection, createBot, createGatewayManager, createRestManager } from "discordeno"; -import { createLogger } from "discordeno/logger"; -import fastify from "fastify"; -import { nanoid } from "nanoid"; -import { Worker } from "worker_threads"; -import { EVENT_HANDLER_URL, INTENTS, REST_URL } from "../configs.js"; -import type { WorkerCreateData, WorkerGetShardInfo, WorkerMessage, WorkerShardInfo, WorkerShardPayload } from "./worker.js"; +import { Collection, createBot, createGatewayManager, createRestManager } from 'discordeno'; +import { createLogger } from 'discordeno/logger'; +import fastify from 'fastify'; +import { nanoid } from 'nanoid'; +import { Worker } from 'worker_threads'; +import { EVENT_HANDLER_URL, INTENTS, REST_URL } from '../configs.js'; +import type { + WorkerCreateData, + WorkerGetShardInfo, + WorkerMessage, + WorkerShardInfo, + WorkerShardPayload, +} from './worker.js'; dotenv.config(); const DISCORD_TOKEN = process.env.DISCORD_TOKEN as string; @@ -18,181 +24,181 @@ const SHARDS_PER_WORKER = Number(process.env.SHARDS_PER_WORKER as string); const TOTAL_SHARDS = process.env.TOTAL_SHARDS ? Number(process.env.TOTAL_SHARDS) : undefined; const TOTAL_WORKERS = Number(process.env.TOTAL_WORKERS as string); -const log = createLogger({ name: "[MANAGER]" }); +const log = createLogger({ name: '[MANAGER]' }); const bot = createBot({ - token: DISCORD_TOKEN, + token: DISCORD_TOKEN, }); bot.rest = createRestManager({ - token: DISCORD_TOKEN, - secretKey: REST_AUTHORIZATION, - customUrl: REST_URL, + token: DISCORD_TOKEN, + secretKey: REST_AUTHORIZATION, + customUrl: REST_URL, }); const gatewayBot = await bot.helpers.getGatewayBot(); const gateway = createGatewayManager({ - gatewayBot, - gatewayConfig: { - token: DISCORD_TOKEN, - intents: INTENTS, - }, - // force the total amount of shards - totalShards: TOTAL_SHARDS, - shardsPerWorker: SHARDS_PER_WORKER, - totalWorkers: TOTAL_WORKERS, + gatewayBot, + gatewayConfig: { + token: DISCORD_TOKEN, + intents: INTENTS, + }, + // force the total amount of shards + totalShards: TOTAL_SHARDS, + shardsPerWorker: SHARDS_PER_WORKER, + totalWorkers: TOTAL_WORKERS, - handleDiscordPayload: () => {}, + handleDiscordPayload: () => {}, - tellWorkerToIdentify: async (_gateway, workerId, shardId, _bucketId) => { - log.info("TELL TO IDENTIFY", { workerId, shardId, _bucketId }); + tellWorkerToIdentify: async (_gateway, workerId, shardId, _bucketId) => { + log.info('TELL TO IDENTIFY', { workerId, shardId, _bucketId }); - let worker = workers.get(workerId); - if (!worker) { - worker = createWorker(workerId); - workers.set(workerId, worker); - } + let worker = workers.get(workerId); + if (!worker) { + worker = createWorker(workerId); + workers.set(workerId, worker); + } - const identify: WorkerMessage = { - type: "IDENTIFY_SHARD", - shardId, - }; + const identify: WorkerMessage = { + type: 'IDENTIFY_SHARD', + shardId, + }; - worker.postMessage(identify); - }, + worker.postMessage(identify); + }, }); const workers = new Collection(); const nonces = new Collection void>(); function createWorker(workerId: number) { - console.log(TOTAL_SHARDS, gateway.manager.totalShards, "SHARDS"); + console.log(TOTAL_SHARDS, gateway.manager.totalShards, 'SHARDS'); - const workerData: WorkerCreateData = { - intents: gateway.manager.gatewayConfig.intents ?? 0, - token: DISCORD_TOKEN, - handlerUrls: [EVENT_HANDLER_URL], - handlerAuthorization: EVENT_HANDLER_AUTHORIZATION, - path: "./worker.ts", - totalShards: gateway.manager.totalShards, - workerId, - }; + const workerData: WorkerCreateData = { + intents: gateway.manager.gatewayConfig.intents ?? 0, + token: DISCORD_TOKEN, + handlerUrls: [EVENT_HANDLER_URL], + handlerAuthorization: EVENT_HANDLER_AUTHORIZATION, + path: './worker.ts', + totalShards: gateway.manager.totalShards, + workerId, + }; - const worker = new Worker("./dist/gateway/worker.js", { - workerData, - }); + const worker = new Worker('./dist/gateway/worker.js', { + workerData, + }); - worker.on("message", async (data: ManagerMessage) => { - log.info({ data }); - switch (data.type) { - case "REQUEST_IDENTIFY": { - log.info("REQUESTING IDENTIFY #", data.shardId); - await gateway.manager.requestIdentify(data.shardId); + worker.on('message', async (data: ManagerMessage) => { + log.info({ data }); + switch (data.type) { + case 'REQUEST_IDENTIFY': { + log.info('REQUESTING IDENTIFY #', data.shardId); + await gateway.manager.requestIdentify(data.shardId); - const allowIdentify: WorkerMessage = { - type: "ALLOW_IDENTIFY", - shardId: data.shardId, - }; + const allowIdentify: WorkerMessage = { + type: 'ALLOW_IDENTIFY', + shardId: data.shardId, + }; - worker.postMessage(allowIdentify); + worker.postMessage(allowIdentify); - break; - } - case "NONCE_REPLY": { - nonces.get(data.nonce)?.(data.data); - } - } - }); + break; + } + case 'NONCE_REPLY': { + nonces.get(data.nonce)?.(data.data); + } + } + }); - return worker; + return worker; } gateway.spawnShards(); const server = fastify(); -server.post("/", async (request, reply) => { - if (request.headers.authorization !== GATEWAY_AUTHORIZATION) { - reply.code(StatusCodes.Unauthorized); +server.post('/', async (request, reply) => { + if (request.headers.authorization !== GATEWAY_AUTHORIZATION) { + reply.code(StatusCodes.Unauthorized); - return reply.send({ processing: false, error: false, message: "Invalid authorization header." }); - } + return reply.send({ processing: false, error: false, message: 'Invalid authorization header.' }); + } - if (!request.body) { - reply.code(StatusCodes.BadRequest); + if (!request.body) { + reply.code(StatusCodes.BadRequest); - return reply.send({ processing: false, error: false, message: "Empty body." }); - } + return reply.send({ processing: false, error: false, message: 'Empty body.' }); + } - try { - const data = request.body as WorkerShardPayload | Omit; - switch (data.type) { - case "SHARD_PAYLOAD": { - const workerId = gateway.calculateWorkerId(data.shardId); - const worker = workers.get(workerId); + try { + const data = request.body as WorkerShardPayload | Omit; + switch (data.type) { + case 'SHARD_PAYLOAD': { + const workerId = gateway.calculateWorkerId(data.shardId); + const worker = workers.get(workerId); - worker?.postMessage(data); + worker?.postMessage(data); - break; - } - case "GET_SHARD_INFO": { - const infos = await Promise.all( - workers.map(async (worker) => { - const nonce = nanoid(); + break; + } + case 'GET_SHARD_INFO': { + const infos = await Promise.all( + workers.map(async (worker) => { + const nonce = nanoid(); - return await new Promise((resolve) => { - worker.postMessage({ type: "GET_SHARD_INFO", nonce }); + return await new Promise((resolve) => { + worker.postMessage({ type: 'GET_SHARD_INFO', nonce }); - nonces.set(nonce, resolve); - }); - }), - ).then((res) => - res.reduce((acc, cur) => { - acc.push(...cur); - return acc; - }, [] as WorkerShardInfo[]) - ); + nonces.set(nonce, resolve); + }); + }), + ).then((res) => + res.reduce((acc, cur) => { + acc.push(...cur); + return acc; + }, [] as WorkerShardInfo[]), + ); - reply.code(StatusCodes.Ok); + reply.code(StatusCodes.Ok); - return reply.send(infos); - } - } + return reply.send(infos); + } + } - reply.code(StatusCodes.Ok); + reply.code(StatusCodes.Ok); - return reply.send({ processing: true }); - } catch { - reply.code(StatusCodes.BadRequest); + return reply.send({ processing: true }); + } catch { + reply.code(StatusCodes.BadRequest); - return reply.send({ processing: false, error: true, message: "Failed to parse body." }); - } + return reply.send({ processing: false, error: true, message: 'Failed to parse body.' }); + } }); server.listen({ port: GATEWAY_PORT }).catch((error) => { - log.error(["[FASTIFY ERROR", error].join("\n")); - process.exit(1); + log.error(['[FASTIFY ERROR', error].join('\n')); + process.exit(1); }); export type ManagerMessage = ManagerRequestIdentify | ManagerNonceReply; export interface ManagerRequestIdentify { - type: "REQUEST_IDENTIFY"; - shardId: number; + type: 'REQUEST_IDENTIFY'; + shardId: number; } export interface ManagerNonceReply { - type: "NONCE_REPLY"; - nonce: string; - data: T; + type: 'NONCE_REPLY'; + nonce: string; + data: T; } enum StatusCodes { - Ok = 200, + Ok = 200, - BadRequest = 400, - Unauthorized = 401, + BadRequest = 400, + Unauthorized = 401, - InternalServerError = 500, + InternalServerError = 500, } diff --git a/examples/bigbot/src/gateway/worker.ts b/examples/bigbot/src/gateway/worker.ts index 904b45d79..7987af85a 100644 --- a/examples/bigbot/src/gateway/worker.ts +++ b/examples/bigbot/src/gateway/worker.ts @@ -1,26 +1,24 @@ -import dotenv from "dotenv"; +import dotenv from 'dotenv'; -import amqplib from "amqplib"; +import amqplib from 'amqplib'; import type { - DiscordGuild, - DiscordReady, - DiscordUnavailableGuild, - Shard, - ShardSocketRequest, - ShardState} from "discordeno"; -import { - createShardManager, - GatewayEventNames -} from "discordeno"; -import { createLogger } from "discordeno/logger"; -import fetch from "node-fetch"; -import crypto from "node:crypto"; -import { parentPort, workerData } from "worker_threads"; + DiscordGuild, + DiscordReady, + DiscordUnavailableGuild, + Shard, + ShardSocketRequest, + ShardState, +} from 'discordeno'; +import { createShardManager, GatewayEventNames } from 'discordeno'; +import { createLogger } from 'discordeno/logger'; +import fetch from 'node-fetch'; +import crypto from 'node:crypto'; +import { parentPort, workerData } from 'worker_threads'; import type { ManagerMessage } from './index.js'; dotenv.config(); if (!parentPort) { - throw new Error("Parent port is null"); + throw new Error('Parent port is null'); } const script: WorkerCreateData = workerData; @@ -31,211 +29,202 @@ const identifyPromises = new Map void>(); let channel: amqplib.Channel | undefined; -const useMessageQueue = process.env.MESSAGEQUEUE_ENABLE === "true"; +const useMessageQueue = process.env.MESSAGEQUEUE_ENABLE === 'true'; // Store guild ids, loading guild ids to change GUILD_CREATE event to GUILD_LOADED_DD if needed. const guildIds: Set = new Set(); const loadingGuildIds: Set = new Set(); const manager = createShardManager({ - gatewayConfig: { - intents: script.intents, - token: script.token, - }, - shardIds: [], - totalShards: script.totalShards, - handleMessage: async (shard, message) => { - const url = script.handlerUrls[shard.id % script.handlerUrls.length]; - if (!url) return console.log("ERROR: NO URL FOUND TO SEND MESSAGE"); + gatewayConfig: { + intents: script.intents, + token: script.token, + }, + shardIds: [], + totalShards: script.totalShards, + handleMessage: async (shard, message) => { + const url = script.handlerUrls[shard.id % script.handlerUrls.length]; + if (!url) return console.log('ERROR: NO URL FOUND TO SEND MESSAGE'); - if (message.t === "READY") { - // Marks which guilds the bot in when initial loading in cache. - (message.d as DiscordReady).guilds.forEach((g) => loadingGuildIds.add(BigInt(g.id))); - } + if (message.t === 'READY') { + // Marks which guilds the bot in when initial loading in cache. + (message.d as DiscordReady).guilds.forEach((g) => loadingGuildIds.add(BigInt(g.id))); + } - // If GUILD_CREATE event came from a shard loaded event, change event to GUILD_LOADED_DD. - if (message.t === "GUILD_CREATE") { - const guild = message.d as DiscordGuild; - const id = BigInt(guild.id); + // If GUILD_CREATE event came from a shard loaded event, change event to GUILD_LOADED_DD. + if (message.t === 'GUILD_CREATE') { + const guild = message.d as DiscordGuild; + const id = BigInt(guild.id); - const existing = guildIds.has(id); - if (existing) return; + const existing = guildIds.has(id); + if (existing) return; - if (loadingGuildIds.has(id)) { - (message.t ) = "GUILD_LOADED_DD"; + if (loadingGuildIds.has(id)) { + message.t = 'GUILD_LOADED_DD'; - loadingGuildIds.delete(id); - } + loadingGuildIds.delete(id); + } - guildIds.add(id); - } + guildIds.add(id); + } - // Delete guild id from cache so GUILD_CREATE from the same guild later works properly. - if (message.t === "GUILD_DELETE") { - const guild = message.d as DiscordUnavailableGuild; + // Delete guild id from cache so GUILD_CREATE from the same guild later works properly. + if (message.t === 'GUILD_DELETE') { + const guild = message.d as DiscordUnavailableGuild; - if (guild.unavailable) return; + if (guild.unavailable) return; - guildIds.delete(BigInt(guild.id)); - } + guildIds.delete(BigInt(guild.id)); + } - if (useMessageQueue) { - if (!channel) return; - await channel.publish( - "gatewayMessage", - "", - Buffer.from(JSON.stringify({ shard, message })), - { - contentType: "application/json", - headers: { - "x-deduplication-header": crypto.createHash("md5").update(JSON.stringify(message.d)).digest("hex"), - }, - }, - ); - } else { - await fetch(url, { - method: "POST", - body: JSON.stringify({ message, shardId: shard.id }), - headers: { "Content-Type": "application/json", Authorization: script.handlerAuthorization }, - }).catch((error) => log.error(error)); - } + if (useMessageQueue) { + if (!channel) return; + await channel.publish('gatewayMessage', '', Buffer.from(JSON.stringify({ shard, message })), { + contentType: 'application/json', + headers: { + 'x-deduplication-header': crypto.createHash('md5').update(JSON.stringify(message.d)).digest('hex'), + }, + }); + } else { + await fetch(url, { + method: 'POST', + body: JSON.stringify({ message, shardId: shard.id }), + headers: { 'Content-Type': 'application/json', Authorization: script.handlerAuthorization }, + }).catch((error) => log.error(error)); + } - log.debug({ shardId: shard.id, message }); - }, - requestIdentify: async function (shardId: number): Promise { - return await new Promise((resolve) => { - identifyPromises.set(shardId, resolve); + log.debug({ shardId: shard.id, message }); + }, + requestIdentify: async function (shardId: number): Promise { + return await new Promise((resolve) => { + identifyPromises.set(shardId, resolve); - const identifyRequest: ManagerMessage = { - type: "REQUEST_IDENTIFY", - shardId, - }; + const identifyRequest: ManagerMessage = { + type: 'REQUEST_IDENTIFY', + shardId, + }; - parentPort?.postMessage(identifyRequest); - }); - }, + parentPort?.postMessage(identifyRequest); + }); + }, }); function buildShardInfo(shard: Shard): WorkerShardInfo { - return { - workerId: script.workerId, - shardId: shard.id, - rtt: shard.heart.rtt || -1, - state: shard.state, - }; + return { + workerId: script.workerId, + shardId: shard.id, + rtt: shard.heart.rtt || -1, + state: shard.state, + }; } -parentPort.on("message", async (data: WorkerMessage) => { - switch (data.type) { - case "IDENTIFY_SHARD": { - log.info(`starting to identify shard #${data.shardId}`); - await manager.identify(data.shardId); +parentPort.on('message', async (data: WorkerMessage) => { + switch (data.type) { + case 'IDENTIFY_SHARD': { + log.info(`starting to identify shard #${data.shardId}`); + await manager.identify(data.shardId); - break; - } - case "ALLOW_IDENTIFY": { - identifyPromises.get(data.shardId)?.(); - identifyPromises.delete(data.shardId); + break; + } + case 'ALLOW_IDENTIFY': { + identifyPromises.get(data.shardId)?.(); + identifyPromises.delete(data.shardId); - break; - } - case "SHARD_PAYLOAD": { - manager.shards.get(data.shardId)?.send(data.data); + break; + } + case 'SHARD_PAYLOAD': { + manager.shards.get(data.shardId)?.send(data.data); - break; - } - case "GET_SHARD_INFO": { - const infos = manager.shards.map(buildShardInfo); + break; + } + case 'GET_SHARD_INFO': { + const infos = manager.shards.map(buildShardInfo); - parentPort?.postMessage({ type: "NONCE_REPLY", nonce: data.nonce, data: infos }); - } - } + parentPort?.postMessage({ type: 'NONCE_REPLY', nonce: data.nonce, data: infos }); + } + } }); export type WorkerMessage = WorkerIdentifyShard | WorkerAllowIdentify | WorkerShardPayload | WorkerGetShardInfo; export interface WorkerIdentifyShard { - type: "IDENTIFY_SHARD"; - shardId: number; + type: 'IDENTIFY_SHARD'; + shardId: number; } export interface WorkerAllowIdentify { - type: "ALLOW_IDENTIFY"; - shardId: number; + type: 'ALLOW_IDENTIFY'; + shardId: number; } export interface WorkerShardPayload { - type: "SHARD_PAYLOAD"; - shardId: number; - data: ShardSocketRequest; + type: 'SHARD_PAYLOAD'; + shardId: number; + data: ShardSocketRequest; } export interface WorkerGetShardInfo { - type: "GET_SHARD_INFO"; - nonce: string; + type: 'GET_SHARD_INFO'; + nonce: string; } export interface WorkerCreateData { - intents: number; - token: string; - handlerUrls: string[]; - handlerAuthorization: string; - path: string; - totalShards: number; - workerId: number; + intents: number; + token: string; + handlerUrls: string[]; + handlerAuthorization: string; + path: string; + totalShards: number; + workerId: number; } export interface WorkerShardInfo { - workerId: number; - shardId: number; - rtt: number; - state: ShardState; + workerId: number; + shardId: number; + rtt: number; + state: ShardState; } const connectRabbitmq = async () => { - let connection: amqplib.Connection | undefined; + let connection: amqplib.Connection | undefined; - try { - connection = await amqplib.connect( - `amqp://${process.env.MESSAGEQUEUE_USERNAME}:${process.env.MESSAGEQUEUE_PASSWORD}@${process.env.MESSAGEQUEUE_URL}`, - ); - } catch (error) { - channel = undefined; - log.error(error); - setTimeout(connectRabbitmq, 1000); - } + try { + connection = await amqplib.connect( + `amqp://${process.env.MESSAGEQUEUE_USERNAME}:${process.env.MESSAGEQUEUE_PASSWORD}@${process.env.MESSAGEQUEUE_URL}`, + ); + } catch (error) { + channel = undefined; + log.error(error); + setTimeout(connectRabbitmq, 1000); + } - if (!connection) return; - connection.on("error", (err) => { - channel = undefined; - log.error(err); - setTimeout(connectRabbitmq, 1000); - }); + if (!connection) return; + connection.on('error', (err) => { + channel = undefined; + log.error(err); + setTimeout(connectRabbitmq, 1000); + }); - connection.on("close", () => { - channel = undefined; - setTimeout(connectRabbitmq, 1000); - }); + connection.on('close', () => { + channel = undefined; + setTimeout(connectRabbitmq, 1000); + }); - try { - channel = await connection.createChannel(); - await channel.assertExchange( - "gatewayMessage", - "x-message-deduplication", - { - durable: true, - arguments: { - "x-cache-size": 1000, - "x-cache-ttl": 500, - }, - }, - ); - } catch (error) { - log.error(error); - channel = undefined; - } + try { + channel = await connection.createChannel(); + await channel.assertExchange('gatewayMessage', 'x-message-deduplication', { + durable: true, + arguments: { + 'x-cache-size': 1000, + 'x-cache-ttl': 500, + }, + }); + } catch (error) { + log.error(error); + channel = undefined; + } }; if (useMessageQueue) { - connectRabbitmq(); + connectRabbitmq(); } diff --git a/examples/bigbot/src/prisma.ts b/examples/bigbot/src/prisma.ts index 901f3a0d9..9b6c4ce30 100644 --- a/examples/bigbot/src/prisma.ts +++ b/examples/bigbot/src/prisma.ts @@ -1,3 +1,3 @@ -import { PrismaClient } from "@prisma/client"; +import { PrismaClient } from '@prisma/client'; export const prisma = new PrismaClient(); diff --git a/examples/bigbot/src/rest/index.ts b/examples/bigbot/src/rest/index.ts index 0f0d03ac6..4521baa46 100644 --- a/examples/bigbot/src/rest/index.ts +++ b/examples/bigbot/src/rest/index.ts @@ -1,9 +1,9 @@ -import dotenv from "dotenv"; +import dotenv from 'dotenv'; -import { BASE_URL, createRestManager } from "discordeno"; -import express from "express"; -import { setupAnalyticsHooks } from "../analytics.js"; -import { REST_URL } from "../configs.js"; +import { BASE_URL, createRestManager } from 'discordeno'; +import express from 'express'; +import { setupAnalyticsHooks } from '../analytics.js'; +import { REST_URL } from '../configs.js'; dotenv.config(); const DISCORD_TOKEN = process.env.DISCORD_TOKEN as string; @@ -11,10 +11,10 @@ const REST_AUTHORIZATION = process.env.REST_AUTHORIZATION as string; const REST_PORT = process.env.REST_PORT as string; const rest = createRestManager({ - token: DISCORD_TOKEN, - secretKey: REST_AUTHORIZATION, - customUrl: REST_URL, - debug: console.log, + token: DISCORD_TOKEN, + secretKey: REST_AUTHORIZATION, + customUrl: REST_URL, + debug: console.log, }); // Add send fetching analytics hook to rest @@ -22,39 +22,39 @@ setupAnalyticsHooks(rest); // @ts-expect-error rest.convertRestError = (errorStack, data) => { - if (!data) return { message: errorStack.message }; - return { ...data, message: errorStack.message }; + if (!data) return { message: errorStack.message }; + return { ...data, message: errorStack.message }; }; const app = express(); app.use( - express.urlencoded({ - extended: true, - }), + express.urlencoded({ + extended: true, + }), ); app.use(express.json()); -app.all("/*", async (req, res) => { - if (!REST_AUTHORIZATION || REST_AUTHORIZATION !== req.headers.authorization) { - return res.status(401).json({ error: "Invalid authorization key." }); - } +app.all('/*', async (req, res) => { + if (!REST_AUTHORIZATION || REST_AUTHORIZATION !== req.headers.authorization) { + return res.status(401).json({ error: 'Invalid authorization key.' }); + } - try { - const result = await rest.runMethod(rest, req.method , `${BASE_URL}${req.url}`, req.body); + try { + const result = await rest.runMethod(rest, req.method, `${BASE_URL}${req.url}`, req.body); - if (result) { - res.status(200).json(result); - } else { - res.status(204).json(); - } - } catch (error: any) { - console.log(error); - res.status(500).json(error); - } + if (result) { + res.status(200).json(result); + } else { + res.status(204).json(); + } + } catch (error: any) { + console.log(error); + res.status(500).json(error); + } }); app.listen(REST_PORT, () => { - console.log(`REST listening at ${REST_URL}`); + console.log(`REST listening at ${REST_URL}`); }); diff --git a/examples/minimal/configs.ts b/examples/minimal/configs.ts index 113ae6e56..5409e62f4 100644 --- a/examples/minimal/configs.ts +++ b/examples/minimal/configs.ts @@ -1,5 +1,5 @@ -import { dotEnvConfig } from './deps.ts.js'; +import { dotEnvConfig } from './deps.ts.js' -dotEnvConfig({ export: true }); -export const BOT_TOKEN = process.env.BOT_TOKEN || ""; -export const BOT_ID = BigInt(atob(BOT_TOKEN.split(".")[0])); +dotEnvConfig({ export: true }) +export const BOT_TOKEN = process.env.BOT_TOKEN || '' +export const BOT_ID = BigInt(atob(BOT_TOKEN.split('.')[0])) diff --git a/examples/minimal/deps.ts b/examples/minimal/deps.ts index 2daf246f3..d78783606 100644 --- a/examples/minimal/deps.ts +++ b/examples/minimal/deps.ts @@ -1,4 +1,4 @@ -export * from "https://deno.land/x/discordeno@17.0.0/mod.ts"; -export * from "https://deno.land/x/discordeno@17.0.0/plugins/mod.ts"; -export { config as dotEnvConfig } from "https://deno.land/x/dotenv@v3.1.0/mod.ts"; -export * from "https://deno.land/std@0.117.0/fmt/colors.ts"; +export * from 'https://deno.land/x/discordeno@17.0.0/mod.ts' +export * from 'https://deno.land/x/discordeno@17.0.0/plugins/mod.ts' +export { config as dotEnvConfig } from 'https://deno.land/x/dotenv@v3.1.0/mod.ts' +export * from 'https://deno.land/std@0.117.0/fmt/colors.ts' diff --git a/examples/minimal/mod.ts b/examples/minimal/mod.ts index 9314c587a..67ecc25d2 100644 --- a/examples/minimal/mod.ts +++ b/examples/minimal/mod.ts @@ -1,27 +1,19 @@ -import { - ActivityTypes, - createBot, - enableCachePlugin, - enableCacheSweepers, - fastFileLoader, - GatewayIntents, - startBot, -} from './deps.ts.js'; -import { BOT_ID, BOT_TOKEN } from './configs.ts.js'; -import { logger } from './src/utils/logger.ts.js'; -import { events } from './src/events/mod.ts.js'; -import { updateCommands } from './src/utils/helpers.ts.js'; +import { ActivityTypes, createBot, enableCachePlugin, enableCacheSweepers, fastFileLoader, GatewayIntents, startBot } from './deps.ts.js' +import { BOT_ID, BOT_TOKEN } from './configs.ts.js' +import { logger } from './src/utils/logger.ts.js' +import { events } from './src/events/mod.ts.js' +import { updateCommands } from './src/utils/helpers.ts.js' -const log = logger({ name: "Main" }); +const log = logger({ name: 'Main' }) -log.info("Starting Bot, this might take a while..."); +log.info('Starting Bot, this might take a while...') -const paths = ["./src/events", "./src/commands"]; +const paths = ['./src/events', './src/commands'] await fastFileLoader(paths).catch((err) => { - log.fatal(`Unable to Import ${paths}`); - log.fatal(err); - Deno.exit(1); -}); + log.fatal(`Unable to Import ${paths}`) + log.fatal(err) + Deno.exit(1) +}) export const bot = enableCachePlugin( createBot({ @@ -30,25 +22,25 @@ export const bot = enableCachePlugin( intents: GatewayIntents.Guilds, events, }), -); +) // @ts-nocheck: no-updated-depencdencies -enableCacheSweepers(bot); +enableCacheSweepers(bot) bot.gateway.manager.createShardOptions.makePresence = (shardId: number) => { return { shardId, - status: "online", + status: 'online', activities: [ { - name: "Discordeno is the Best Lib", + name: 'Discordeno is the Best Lib', type: ActivityTypes.Game, createdAt: Date.now(), }, ], - }; -}; + } +} -await startBot(bot); +await startBot(bot) -await updateCommands(bot); +await updateCommands(bot) diff --git a/examples/minimal/src/commands/mod.ts b/examples/minimal/src/commands/mod.ts index 6b87af077..e4390adc8 100644 --- a/examples/minimal/src/commands/mod.ts +++ b/examples/minimal/src/commands/mod.ts @@ -1,25 +1,25 @@ -import type { ApplicationCommandOption, ApplicationCommandTypes, Bot, Interaction } from '../../deps.ts.js'; -import { Collection } from '../../deps.ts.js'; +import type { ApplicationCommandOption, ApplicationCommandTypes, Bot, Interaction } from '../../deps.ts.js' +import { Collection } from '../../deps.ts.js' -export type subCommand = Omit; +export type subCommand = Omit export interface subCommandGroup { - name: string; - subCommands: subCommand[]; + name: string + subCommands: subCommand[] } 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: (bot: Bot, interaction: Interaction) => unknown; - subcommands?: Array; + scope?: 'Global' | 'Guild' + execute: (bot: Bot, interaction: Interaction) => unknown + subcommands?: Array } -export const commands = new Collection(); +export const commands = new Collection() export function createCommand(command: Command) { - commands.set(command.name, command); + commands.set(command.name, command) } diff --git a/examples/minimal/src/commands/ping.ts b/examples/minimal/src/commands/ping.ts index 13aca77fd..e3ae23803 100644 --- a/examples/minimal/src/commands/ping.ts +++ b/examples/minimal/src/commands/ping.ts @@ -1,23 +1,19 @@ -import { ApplicationCommandTypes, InteractionResponseTypes } from '../../deps.ts.js'; -import { humanizeMilliseconds, snowflakeToTimestamp } from '../utils/helpers.ts.js'; -import { createCommand } from './mod.ts.js'; +import { ApplicationCommandTypes, InteractionResponseTypes } from '../../deps.ts.js' +import { humanizeMilliseconds, snowflakeToTimestamp } from '../utils/helpers.ts.js' +import { createCommand } from './mod.ts.js' createCommand({ - name: "ping", - description: "Ping the Bot!", + name: 'ping', + description: 'Ping the Bot!', type: ApplicationCommandTypes.ChatInput, - scope: "Global", + scope: 'Global', execute: async (bot, interaction) => { - const ping = Date.now() - snowflakeToTimestamp(interaction.id); - await bot.helpers.sendInteractionResponse( - interaction.id, - interaction.token, - { - type: InteractionResponseTypes.ChannelMessageWithSource, - data: { - content: `🏓 Pong! Ping ${ping}ms (${humanizeMilliseconds(ping)})`, - }, + const ping = Date.now() - snowflakeToTimestamp(interaction.id) + await bot.helpers.sendInteractionResponse(interaction.id, interaction.token, { + type: InteractionResponseTypes.ChannelMessageWithSource, + data: { + content: `🏓 Pong! Ping ${ping}ms (${humanizeMilliseconds(ping)})`, }, - ); + }) }, -}); +}) diff --git a/examples/minimal/src/events/guildCreate.ts b/examples/minimal/src/events/guildCreate.ts index b33540fbf..a7f2e892c 100644 --- a/examples/minimal/src/events/guildCreate.ts +++ b/examples/minimal/src/events/guildCreate.ts @@ -1,4 +1,4 @@ -import { events } from './mod.ts.js'; -import { updateGuildCommands } from '../utils/helpers.ts.js'; +import { events } from './mod.ts.js' +import { updateGuildCommands } from '../utils/helpers.ts.js' -events.guildCreate = async (bot, guild) => await updateGuildCommands(bot, guild); +events.guildCreate = async (bot, guild) => await updateGuildCommands(bot, guild) diff --git a/examples/minimal/src/events/interactionCreate.ts b/examples/minimal/src/events/interactionCreate.ts index 90ee4b0f1..4772d2ad2 100644 --- a/examples/minimal/src/events/interactionCreate.ts +++ b/examples/minimal/src/events/interactionCreate.ts @@ -1,135 +1,111 @@ -import type { - BotWithCache, - Guild} from '../../deps.ts.js'; -import { - ApplicationCommandOptionTypes, - bgBlack, - bgYellow, - black, - green, - red, - white, - yellow, -} from '../../deps.ts.js'; -import { events } from './mod.ts.js'; -import { logger } from '../utils/logger.ts.js'; -import { getGuildFromId, isSubCommand, isSubCommandGroup } from '../utils/helpers.ts.js'; -import type { Command} from '../commands/mod.ts.js'; -import { commands } from '../commands/mod.ts.js'; +import type { BotWithCache, Guild } from '../../deps.ts.js' +import { ApplicationCommandOptionTypes, bgBlack, bgYellow, black, green, red, white, yellow } from '../../deps.ts.js' +import { events } from './mod.ts.js' +import { logger } from '../utils/logger.ts.js' +import { getGuildFromId, isSubCommand, isSubCommandGroup } from '../utils/helpers.ts.js' +import type { Command } from '../commands/mod.ts.js' +import { commands } from '../commands/mod.ts.js' -const log = logger({ name: "Event: InteractionCreate" }); +const log = logger({ name: 'Event: InteractionCreate' }) events.interactionCreate = async (rawBot, interaction) => { - const bot = rawBot as BotWithCache; + const bot = rawBot as BotWithCache if (interaction.data && interaction.id) { - let guildName = "Direct Message"; - let guild = {} as Guild; + let guildName = 'Direct Message' + let guild = {} as 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(bot, interaction.guildId).catch( - (err) => { - log.error(err); - }, - ); + const guildOrVoid = await getGuildFromId(bot, interaction.guildId).catch((err) => { + log.error(err) + }) if (guildOrVoid) { - guild = guildOrVoid; - guildName = guild.name; + guild = guildOrVoid + guildName = guild.name } } log.info( - `[Command: ${bgYellow(black(String(interaction.data.name)))} - ${ - bgBlack(white(`Trigger`)) - }] by ${interaction.user.username}#${interaction.user.discriminator} in ${guildName}${ - guildName !== "Direct Message" ? ` (${guild.id})` : `` - }`, - ); + `[Command: ${bgYellow(black(String(interaction.data.name)))} - ${bgBlack(white(`Trigger`))}] by ${interaction.user.username}#${ + interaction.user.discriminator + } in ${guildName}${guildName !== 'Direct Message' ? ` (${guild.id})` : ``}`, + ) - let command: undefined | Command = interaction.data.name ? commands.get(interaction.data.name) : undefined; - let commandName = command?.name; + let command: undefined | Command = interaction.data.name ? commands.get(interaction.data.name) : undefined + let commandName = command?.name if (command !== undefined) { if (interaction.data.name) { 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) - commandName += ` ${subCommandGroup.name} ${command?.name}`; + commandName += ` ${subCommandGroup.name} ${command?.name}` // Normal } if (optionType === ApplicationCommandOptionTypes.SubCommandGroup) { // 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; - commandName += ` ${command?.name}`; + command = found + commandName += ` ${command?.name}` } } try { if (command) { - command.execute(rawBot, interaction); + command.execute(rawBot, interaction) log.info( - `[Command: ${bgYellow(black(String(interaction.data.name)))} - ${ - bgBlack(green(`Success`)) - }] by ${interaction.user.username}#${interaction.user.discriminator} in ${guildName}${ - guildName !== "Direct Message" ? ` (${guild.id})` : `` - }`, - ); + `[Command: ${bgYellow(black(String(interaction.data.name)))} - ${bgBlack(green(`Success`))}] by ${interaction.user.username}#${ + interaction.user.discriminator + } in ${guildName}${guildName !== 'Direct Message' ? ` (${guild.id})` : ``}`, + ) } else { - throw ""; + throw '' } } catch (err) { log.error( - `[Command: ${bgYellow(black(String(interaction.data.name)))} - ${ - bgBlack(red(`Error`)) - }] by ${interaction.user.username}#${interaction.user.discriminator} in ${guildName}${ - guildName !== "Direct Message" ? ` (${guild.id})` : `` - }`, - ); - err.length ? log.error(err) : undefined; + `[Command: ${bgYellow(black(String(interaction.data.name)))} - ${bgBlack(red(`Error`))}] by ${interaction.user.username}#${ + interaction.user.discriminator + } in ${guildName}${guildName !== 'Direct Message' ? ` (${guild.id})` : ``}`, + ) + err.length ? log.error(err) : undefined } } else { log.warn( - `[Command: ${bgYellow(black(String(interaction.data.name)))} - ${ - bgBlack(yellow(`Not Found`)) - }] by ${interaction.user.username}#${interaction.user.discriminator} in ${guildName}${ - guildName !== "Direct Message" ? ` (${guild.id})` : `` - }`, - ); + `[Command: ${bgYellow(black(String(interaction.data.name)))} - ${bgBlack(yellow(`Not Found`))}] by ${interaction.user.username}#${ + interaction.user.discriminator + } in ${guildName}${guildName !== 'Direct Message' ? ` (${guild.id})` : ``}`, + ) } } } -}; +} /* // Handle subcommands diff --git a/examples/minimal/src/events/mod.ts b/examples/minimal/src/events/mod.ts index 271881422..e7861048e 100644 --- a/examples/minimal/src/events/mod.ts +++ b/examples/minimal/src/events/mod.ts @@ -1,3 +1,3 @@ -import type { EventHandlers } from '../../deps.ts.js'; +import type { EventHandlers } from '../../deps.ts.js' -export const events: Partial = {}; +export const events: Partial = {} diff --git a/examples/minimal/src/events/ready.ts b/examples/minimal/src/events/ready.ts index 70f6ed8f0..324bc42eb 100644 --- a/examples/minimal/src/events/ready.ts +++ b/examples/minimal/src/events/ready.ts @@ -1,8 +1,8 @@ -import { events } from './mod.ts.js'; -import { logger } from '../utils/logger.ts.js'; +import { events } from './mod.ts.js' +import { logger } from '../utils/logger.ts.js' -const log = logger({ name: "Event: Ready" }); +const log = logger({ name: 'Event: Ready' }) events.ready = () => { - log.info("Bot Ready"); -}; + log.info('Bot Ready') +} diff --git a/examples/minimal/src/utils/helpers.ts b/examples/minimal/src/utils/helpers.ts index 419839b0d..93490835a 100644 --- a/examples/minimal/src/utils/helpers.ts +++ b/examples/minimal/src/utils/helpers.ts @@ -1,41 +1,32 @@ -import type { - Bot, - BotWithCache, - CreateApplicationCommand, - Guild, - MakeRequired} from '../../deps.ts.js'; -import { - getGuild, - hasProperty, - upsertGuildApplicationCommands, -} from '../../deps.ts.js'; -import { logger } from './logger.ts.js'; -import type { subCommand, subCommandGroup } from '../commands/mod.ts.js'; -import { commands } from '../commands/mod.ts.js'; +import type { Bot, BotWithCache, CreateApplicationCommand, Guild, MakeRequired } from '../../deps.ts.js' +import { getGuild, hasProperty, upsertGuildApplicationCommands } from '../../deps.ts.js' +import { logger } from './logger.ts.js' +import type { subCommand, subCommandGroup } from '../commands/mod.ts.js' +import { commands } from '../commands/mod.ts.js' -const log = logger({ name: "Helpers" }); +const log = logger({ name: 'Helpers' }) /** This function will update all commands, or the defined scope */ -export async function updateCommands(bot: BotWithCache, scope?: "Guild" | "Global") { - const globalCommands: Array> = []; - const perGuildCommands: Array> = []; +export async function updateCommands(bot: BotWithCache, scope?: 'Guild' | 'Global') { + const globalCommands: Array> = [] + const perGuildCommands: Array> = [] for (const command of commands.values()) { if (command.scope) { - if (command.scope === "Guild") { + if (command.scope === 'Guild') { perGuildCommands.push({ name: command.name, description: command.description, type: command.type, options: command.options ? command.options : undefined, - }); - } else if (command.scope === "Global") { + }) + } else if (command.scope === 'Global') { globalCommands.push({ name: command.name, description: command.description, type: command.type, options: command.options ? command.options : undefined, - }); + }) } } else { perGuildCommands.push({ @@ -43,87 +34,87 @@ export async function updateCommands(bot: BotWithCache, scope?: "Guild" | "Globa description: command.description, type: command.type, options: command.options ? command.options : undefined, - }); + }) } } - if (globalCommands.length && (scope === "Global" || scope === undefined)) { - log.info("Updating Global Commands, changes should apply in short..."); - await bot.helpers.upsertGlobalApplicationCommands(globalCommands).catch(log.error); + if (globalCommands.length && (scope === 'Global' || scope === undefined)) { + log.info('Updating Global Commands, changes should apply in short...') + await bot.helpers.upsertGlobalApplicationCommands(globalCommands).catch(log.error) } - if (perGuildCommands.length && (scope === "Guild" || scope === undefined)) { + if (perGuildCommands.length && (scope === 'Guild' || scope === undefined)) { await bot.guilds.forEach(async (guild: Guild) => { - await upsertGuildApplicationCommands(bot, guild.id, perGuildCommands); - }); + await upsertGuildApplicationCommands(bot, guild.id, perGuildCommands) + }) } } /** Update commands for a guild */ export async function updateGuildCommands(bot: Bot, guild: Guild) { - const perGuildCommands: Array> = []; + const perGuildCommands: Array> = [] for (const command of commands.values()) { if (command.scope) { - if (command.scope === "Guild") { + if (command.scope === 'Guild') { perGuildCommands.push({ name: command.name, description: command.description, type: command.type, options: command.options ? command.options : undefined, - }); + }) } } } if (perGuildCommands.length) { - await upsertGuildApplicationCommands(bot, guild.id, perGuildCommands); + await upsertGuildApplicationCommands(bot, guild.id, perGuildCommands) } } export async function getGuildFromId(bot: BotWithCache, guildId: bigint): Promise { - let returnValue: Guild = {} as Guild; + let returnValue: Guild = {} as Guild if (guildId !== 0n) { if (bot.guilds.get(guildId)) { - returnValue = bot.guilds.get(guildId) as Guild; + returnValue = bot.guilds.get(guildId) as Guild } await getGuild(bot, guildId).then((guild) => { - if (guild) bot.guilds.set(guildId, guild); - if (guild) returnValue = guild; - }); + if (guild) bot.guilds.set(guildId, guild) + if (guild) returnValue = guild + }) } - return returnValue; + return returnValue } export function snowflakeToTimestamp(id: bigint) { - return Number(id / 4194304n + 1420070400000n); + return Number(id / 4194304n + 1420070400000n) } export function humanizeMilliseconds(milliseconds: number) { // 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') } diff --git a/examples/minimal/src/utils/logger.ts b/examples/minimal/src/utils/logger.ts index f711138de..9228b7074 100644 --- a/examples/minimal/src/utils/logger.ts +++ b/examples/minimal/src/utils/logger.ts @@ -1,5 +1,5 @@ // deno-lint-ignore-file no-explicit-any -import { bold, cyan, gray, italic, red, yellow } from '../../deps.ts.js'; +import { bold, cyan, gray, italic, red, yellow } from '../../deps.ts.js' export enum LogLevels { Debug, @@ -10,81 +10,81 @@ export enum LogLevels { } const prefixes = new Map([ - [LogLevels.Debug, "DEBUG"], - [LogLevels.Info, "INFO"], - [LogLevels.Warn, "WARN"], - [LogLevels.Error, "ERROR"], - [LogLevels.Fatal, "FATAL"], -]); + [LogLevels.Debug, 'DEBUG'], + [LogLevels.Info, 'INFO'], + [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 logger({ logLevel = LogLevels.Info, name, }: { - logLevel?: LogLevels; - name?: string; + 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 = [ `[${date.toLocaleDateString()} ${date.toLocaleTimeString()}]`, - color(prefixes.get(level) || "DEBUG"), - name ? `${name} >` : ">", + 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 { @@ -95,7 +95,7 @@ export function logger({ warn, error, fatal, - }; + } } -export const log = logger(); +export const log = logger() diff --git a/packages/bot/src/bot.ts b/packages/bot/src/bot.ts index 4db5cb29c..282a9d972 100644 --- a/packages/bot/src/bot.ts +++ b/packages/bot/src/bot.ts @@ -1,4 +1,4 @@ -import type { CreateGatewayManagerOptions, GatewayManager, Shard } from '@discordeno/gateway' +import type { CreateGatewayManagerOptions, GatewayManager, DiscordenoShard } from '@discordeno/gateway' import { createGatewayManager, ShardSocketCloseCodes } from '@discordeno/gateway' import type { CreateRestManagerOptions, RestManager } from '@discordeno/rest' import { createRestManager } from '@discordeno/rest' @@ -61,22 +61,22 @@ import { createLogger } from '@discordeno/utils' */ export function createBot(options: CreateBotOptions): Bot { if (!options.rest) options.rest = { token: options.token } - if (!options.gateway) options.gateway = { token: options.token, events: {} }; + if (!options.gateway) options.gateway = { token: options.token, events: {} } if (!options.gateway.events.message) { options.gateway.events.message = async (shard, data) => { - // TRIGGER RAW EVENT - bot.events.raw?.(data, shard) + // TRIGGER RAW EVENT + bot.events.raw?.(data, shard) - if (!data.t) return + if (!data.t) return - // RUN DISPATCH CHECK - await bot.events.dispatchRequirements?.(data, shard) - bot.events[ - data.t.toLowerCase().replace(/_([a-z])/g, function (g) { - return g[1].toUpperCase() - }) as keyof EventHandlers - // @ts-expect-error as any gets removed by linter - ]?.(data.d, shard) + // RUN DISPATCH CHECK + await bot.events.dispatchRequirements?.(data, shard) + bot.events[ + data.t.toLowerCase().replace(/_([a-z])/g, function (g) { + return g[1].toUpperCase() + }) as keyof EventHandlers + // @ts-expect-error as any gets removed by linter + ]?.(data.d, shard) } } @@ -134,68 +134,68 @@ export interface Bot { export interface EventHandlers { // Custom events here - dispatchRequirements: (payload: Camelize, shard: Shard) => unknown - raw: (payload: Camelize, shard: Shard) => unknown + dispatchRequirements: (payload: Camelize, shard: DiscordenoShard) => unknown + raw: (payload: Camelize, shard: DiscordenoShard) => unknown // Gateway events below this - applicationCommandPermissionsUpdate: (payload: Camelize, shard: Shard) => unknown - auditLogEntryCreate: (payload: Camelize, shard: Shard) => unknown - autoModerationRuleCreate: (payload: Camelize, shard: Shard) => unknown - autoModerationRuleUpdate: (payload: Camelize, shard: Shard) => unknown - autoModerationRuleDelete: (payload: Camelize, shard: Shard) => unknown - autoModerationActionExecution: (payload: Camelize, shard: Shard) => unknown - channelCreate: (payload: Camelize, shard: Shard) => unknown - channelUpdate: (payload: Camelize, shard: Shard) => unknown - channelDelete: (payload: Camelize, shard: Shard) => unknown - channelPinsUpdate: (payload: Camelize, shard: Shard) => unknown - threadCreate: (payload: Camelize, shard: Shard) => unknown - threadUpdate: (payload: Camelize, shard: Shard) => unknown - threadDelete: (payload: Camelize, shard: Shard) => unknown - threadListSync: (payload: Camelize, shard: Shard) => unknown - threadMemberUpdate: (payload: Camelize, shard: Shard) => unknown - threadMembersUpdate: (payload: Camelize, shard: Shard) => unknown - guildCreate: (payload: Camelize, shard: Shard) => unknown - guildUpdate: (payload: Camelize, shard: Shard) => unknown - guildDelete: (payload: Camelize, shard: Shard) => unknown - guildBanAdd: (payload: Camelize, shard: Shard) => unknown - guildBanRemove: (payload: Camelize, shard: Shard) => unknown - guildEmojisUpdate: (payload: Camelize, shard: Shard) => unknown - guildStickersUpdate: (payload: Camelize, shard: Shard) => unknown - guildIntegrationsUpdate: (payload: Camelize, shard: Shard) => unknown - guildMemberAdd: (payload: Camelize, shard: Shard) => unknown - guildMemberRemove: (payload: Camelize, shard: Shard) => unknown - guildMemberUpdate: (payload: Camelize, shard: Shard) => unknown - guildMembersChunk: (payload: Camelize, shard: Shard) => unknown - guildRoleCreate: (payload: Camelize, shard: Shard) => unknown - guildRoleUpdate: (payload: Camelize, shard: Shard) => unknown - guildRoleDelete: (payload: Camelize, shard: Shard) => unknown - guildScheduledEventCreate: (payload: Camelize, shard: Shard) => unknown - guildScheduledEventUpdate: (payload: Camelize, shard: Shard) => unknown - guildScheduledEventDelete: (payload: Camelize, shard: Shard) => unknown - guildScheduledEventUserAdd: (payload: Camelize, shard: Shard) => unknown - guildScheduledEventUserRemove: (payload: Camelize, shard: Shard) => unknown - integrationCreate: (payload: Camelize, shard: Shard) => unknown - integrationUpdate: (payload: Camelize, shard: Shard) => unknown - integrationDelete: (payload: Camelize, shard: Shard) => unknown - interactionCreate: (payload: Camelize, shard: Shard) => unknown - inviteCreate: (payload: Camelize, shard: Shard) => unknown - inviteDelete: (payload: Camelize, shard: Shard) => unknown - messageCreate: (payload: Camelize, shard: Shard) => unknown - messageUpdate: (payload: Camelize, shard: Shard) => unknown - messageDelete: (payload: Camelize, shard: Shard) => unknown - messageDeleteBulk: (payload: Camelize, shard: Shard) => unknown - messageReactionAdd: (payload: Camelize, shard: Shard) => unknown - messageReactionRemove: (payload: Camelize, shard: Shard) => unknown - messageReactionRemoveAll: (payload: Camelize, shard: Shard) => unknown - messageReactionRemoveEmoji: (payload: Camelize, shard: Shard) => unknown - presenceUpdate: (payload: Camelize, shard: Shard) => unknown - ready: (payload: Camelize, shard: Shard) => unknown - stageInstanceCreate: (payload: Camelize, shard: Shard) => unknown - stageInstanceUpdate: (payload: Camelize, shard: Shard) => unknown - stageInstanceDelete: (payload: Camelize, shard: Shard) => unknown - typingStart: (payload: Camelize, shard: Shard) => unknown - userUpdate: (payload: Camelize, shard: Shard) => unknown - voiceStateUpdate: (payload: Camelize, shard: Shard) => unknown - voiceServerUpdate: (payload: Camelize, shard: Shard) => unknown - webhooksUpdate: (payload: Camelize, shard: Shard) => unknown + applicationCommandPermissionsUpdate: (payload: Camelize, shard: DiscordenoShard) => unknown + auditLogEntryCreate: (payload: Camelize, shard: DiscordenoShard) => unknown + autoModerationRuleCreate: (payload: Camelize, shard: DiscordenoShard) => unknown + autoModerationRuleUpdate: (payload: Camelize, shard: DiscordenoShard) => unknown + autoModerationRuleDelete: (payload: Camelize, shard: DiscordenoShard) => unknown + autoModerationActionExecution: (payload: Camelize, shard: DiscordenoShard) => unknown + channelCreate: (payload: Camelize, shard: DiscordenoShard) => unknown + channelUpdate: (payload: Camelize, shard: DiscordenoShard) => unknown + channelDelete: (payload: Camelize, shard: DiscordenoShard) => unknown + channelPinsUpdate: (payload: Camelize, shard: DiscordenoShard) => unknown + threadCreate: (payload: Camelize, shard: DiscordenoShard) => unknown + threadUpdate: (payload: Camelize, shard: DiscordenoShard) => unknown + threadDelete: (payload: Camelize, shard: DiscordenoShard) => unknown + threadListSync: (payload: Camelize, shard: DiscordenoShard) => unknown + threadMemberUpdate: (payload: Camelize, shard: DiscordenoShard) => unknown + threadMembersUpdate: (payload: Camelize, shard: DiscordenoShard) => unknown + guildCreate: (payload: Camelize, shard: DiscordenoShard) => unknown + guildUpdate: (payload: Camelize, shard: DiscordenoShard) => unknown + guildDelete: (payload: Camelize, shard: DiscordenoShard) => unknown + guildBanAdd: (payload: Camelize, shard: DiscordenoShard) => unknown + guildBanRemove: (payload: Camelize, shard: DiscordenoShard) => unknown + guildEmojisUpdate: (payload: Camelize, shard: DiscordenoShard) => unknown + guildStickersUpdate: (payload: Camelize, shard: DiscordenoShard) => unknown + guildIntegrationsUpdate: (payload: Camelize, shard: DiscordenoShard) => unknown + guildMemberAdd: (payload: Camelize, shard: DiscordenoShard) => unknown + guildMemberRemove: (payload: Camelize, shard: DiscordenoShard) => unknown + guildMemberUpdate: (payload: Camelize, shard: DiscordenoShard) => unknown + guildMembersChunk: (payload: Camelize, shard: DiscordenoShard) => unknown + guildRoleCreate: (payload: Camelize, shard: DiscordenoShard) => unknown + guildRoleUpdate: (payload: Camelize, shard: DiscordenoShard) => unknown + guildRoleDelete: (payload: Camelize, shard: DiscordenoShard) => unknown + guildScheduledEventCreate: (payload: Camelize, shard: DiscordenoShard) => unknown + guildScheduledEventUpdate: (payload: Camelize, shard: DiscordenoShard) => unknown + guildScheduledEventDelete: (payload: Camelize, shard: DiscordenoShard) => unknown + guildScheduledEventUserAdd: (payload: Camelize, shard: DiscordenoShard) => unknown + guildScheduledEventUserRemove: (payload: Camelize, shard: DiscordenoShard) => unknown + integrationCreate: (payload: Camelize, shard: DiscordenoShard) => unknown + integrationUpdate: (payload: Camelize, shard: DiscordenoShard) => unknown + integrationDelete: (payload: Camelize, shard: DiscordenoShard) => unknown + interactionCreate: (payload: Camelize, shard: DiscordenoShard) => unknown + inviteCreate: (payload: Camelize, shard: DiscordenoShard) => unknown + inviteDelete: (payload: Camelize, shard: DiscordenoShard) => unknown + messageCreate: (payload: Camelize, shard: DiscordenoShard) => unknown + messageUpdate: (payload: Camelize, shard: DiscordenoShard) => unknown + messageDelete: (payload: Camelize, shard: DiscordenoShard) => unknown + messageDeleteBulk: (payload: Camelize, shard: DiscordenoShard) => unknown + messageReactionAdd: (payload: Camelize, shard: DiscordenoShard) => unknown + messageReactionRemove: (payload: Camelize, shard: DiscordenoShard) => unknown + messageReactionRemoveAll: (payload: Camelize, shard: DiscordenoShard) => unknown + messageReactionRemoveEmoji: (payload: Camelize, shard: DiscordenoShard) => unknown + presenceUpdate: (payload: Camelize, shard: DiscordenoShard) => unknown + ready: (payload: Camelize, shard: DiscordenoShard) => unknown + stageInstanceCreate: (payload: Camelize, shard: DiscordenoShard) => unknown + stageInstanceUpdate: (payload: Camelize, shard: DiscordenoShard) => unknown + stageInstanceDelete: (payload: Camelize, shard: DiscordenoShard) => unknown + typingStart: (payload: Camelize, shard: DiscordenoShard) => unknown + userUpdate: (payload: Camelize, shard: DiscordenoShard) => unknown + voiceStateUpdate: (payload: Camelize, shard: DiscordenoShard) => unknown + voiceServerUpdate: (payload: Camelize, shard: DiscordenoShard) => unknown + webhooksUpdate: (payload: Camelize, shard: DiscordenoShard) => unknown } diff --git a/packages/bot/tests/e2e/resetguilds.spec.ts b/packages/bot/tests/e2e/resetguilds.spec.ts index ee77fea8f..84e47c955 100644 --- a/packages/bot/tests/e2e/resetguilds.spec.ts +++ b/packages/bot/tests/e2e/resetguilds.spec.ts @@ -3,7 +3,7 @@ import { delay, logger } from '@discordeno/utils' import chai from 'chai' import chaiAsPromised from 'chai-as-promised' import { describe, it } from 'mocha' -import type { EventHandlers } from '../../src/bot.js'; +import type { EventHandlers } from '../../src/bot.js' import { createBot } from '../../src/bot.js' import { token } from './constants.js' chai.use(chaiAsPromised) @@ -35,12 +35,12 @@ describe('[Bot] Delete any guild owned guilds', () => { }, events: { async guildCreate(payload, shard) { - if (payload.joinedAt && (Date.now() - Date.parse(payload.joinedAt)) < 360000) { - return; + if (payload.joinedAt && Date.now() - Date.parse(payload.joinedAt) < 360000) { + return } if (bot.rest.applicationId.toString() === payload.ownerId) { - logger.debug(`Deleting one of the bot created guilds.`, payload.id); + logger.debug(`Deleting one of the bot created guilds.`, payload.id) await bot.rest.deleteGuild(payload.id) } }, diff --git a/packages/client/src/Collection.ts b/packages/client/src/Collection.ts index 25221485b..1773be368 100644 --- a/packages/client/src/Collection.ts +++ b/packages/client/src/Collection.ts @@ -1,140 +1,140 @@ export class Collection extends Map { - limit: number | undefined; - - set(key: K, value: V): this { - // When this collection is limitd make sure we can add first - if ((this.limit ?? this.limit === 0) && this.size >= this.limit) { - return this; - } - - return super.set(key, value); + limit: number | undefined + + set(key: K, value: V): this { + // When this collection is limitd make sure we can add first + if ((this.limit ?? this.limit === 0) && this.size >= this.limit) { + return this } - - forceSet(key: K, value: V): this { - return super.set(key, value); - } - - array(): V[] { - return [...this.values()]; - } - - /** Retrieve the value of the first element in this collection */ - first(): V | undefined { - return this.values().next().value; - } - - last(): V | undefined { - return [...this.values()][this.size - 1]; - } - - random(): V | undefined { - const array = [...this.values()]; - return array[Math.floor(Math.random() * array.length)]; - } - - find(callback: (value: V, key: K) => boolean): V | undefined { - for (const key of this.keys()) { - const value = this.get(key)!; - if (callback(value, key)) return value; - } - } - - filter(callback: (value: V, key: K) => boolean, returnArray?: true): V[]; - filter(callback: (value: V, key: K) => boolean, returnArray: false): Collection; - filter(callback: (value: V, key: K) => boolean, returnArray = true): Collection | V[] { - const relevant = new Collection(); - this.forEach((value, key) => { - if (callback(value, key)) relevant.set(key, value); - }); - - return returnArray ? relevant.array() : relevant; - } - - map(callback: (value: V, key: K) => T): T[] { - const results = []; - for (const key of this.keys()) { - const value = this.get(key)!; - results.push(callback(value, key)); - } - return results; - } - - 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; - } - - return false; - } - - 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; - } - - return true; - } - - reduce(callback: (accumulator: T, value: V, key: K) => T, initialValue?: T): T { - let accumulator: T = initialValue!; - - for (const key of this.keys()) { - const value = this.get(key)!; - accumulator = callback(accumulator, value, key); - } - - return accumulator; - } - - /** - * Adds a object to the collection. - * @deprecated Recommend using Collection.set(). Keeping for the sake of Eris API. - * @deprecated extra parameter. No longer used, keeping for sake of Eris API. - */ - add(obj: V & { id: K }, extra?: unknown, replace?: boolean): V { - if (this.limit === 0) return obj; - - const existing = this.get(obj.id); - if (existing && !replace) { - return existing; - } - - this.set(obj.id, obj); - return obj; - } - - remove(obj: { id: K }): V | undefined { - const item = this.get(obj.id); - if (!item) return; - - this.delete(obj.id); - return item; - } - - update(obj: V & { id: K }, extra?: unknown, replace?: boolean): V { - const item = this.get(obj.id); - if (!item) { - this.set(obj.id, obj); - return obj; - } - - // @ts-expect-error some eris magic at play here - item.update?.(obj, extra); - return item; - } - - toRecord(): Record { - const record: Record = {}; - for (const [key, value] of this.entries()) { - // @ts-expect-error should work fine - const finalKey = typeof key === 'string' ? key : key.toString(); - record[finalKey] = value; - } - - return record; + + return super.set(key, value) + } + + forceSet(key: K, value: V): this { + return super.set(key, value) + } + + array(): V[] { + return [...this.values()] + } + + /** Retrieve the value of the first element in this collection */ + first(): V | undefined { + return this.values().next().value + } + + last(): V | undefined { + return [...this.values()][this.size - 1] + } + + random(): V | undefined { + const array = [...this.values()] + return array[Math.floor(Math.random() * array.length)] + } + + find(callback: (value: V, key: K) => boolean): V | undefined { + for (const key of this.keys()) { + const value = this.get(key)! + if (callback(value, key)) return value } } - - export default Collection; \ No newline at end of file + + filter(callback: (value: V, key: K) => boolean, returnArray?: true): V[] + filter(callback: (value: V, key: K) => boolean, returnArray: false): Collection + filter(callback: (value: V, key: K) => boolean, returnArray = true): Collection | V[] { + const relevant = new Collection() + this.forEach((value, key) => { + if (callback(value, key)) relevant.set(key, value) + }) + + return returnArray ? relevant.array() : relevant + } + + map(callback: (value: V, key: K) => T): T[] { + const results = [] + for (const key of this.keys()) { + const value = this.get(key)! + results.push(callback(value, key)) + } + return results + } + + 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 + } + + return false + } + + 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 + } + + return true + } + + reduce(callback: (accumulator: T, value: V, key: K) => T, initialValue?: T): T { + let accumulator: T = initialValue! + + for (const key of this.keys()) { + const value = this.get(key)! + accumulator = callback(accumulator, value, key) + } + + return accumulator + } + + /** + * Adds a object to the collection. + * @deprecated Recommend using Collection.set(). Keeping for the sake of Eris API. + * @deprecated extra parameter. No longer used, keeping for sake of Eris API. + */ + add(obj: V & { id: K }, extra?: unknown, replace?: boolean): V { + if (this.limit === 0) return obj + + const existing = this.get(obj.id) + if (existing && !replace) { + return existing + } + + this.set(obj.id, obj) + return obj + } + + remove(obj: { id: K }): V | undefined { + const item = this.get(obj.id) + if (!item) return + + this.delete(obj.id) + return item + } + + update(obj: V & { id: K }, extra?: unknown, replace?: boolean): V { + const item = this.get(obj.id) + if (!item) { + this.set(obj.id, obj) + return obj + } + + // @ts-expect-error some eris magic at play here + item.update?.(obj, extra) + return item + } + + toRecord(): Record { + const record: Record = {} + for (const [key, value] of this.entries()) { + // @ts-expect-error should work fine + const finalKey = typeof key === 'string' ? key : key.toString() + record[finalKey] = value + } + + return record + } +} + +export default Collection diff --git a/packages/client/src/Structures/channels/Stage.ts b/packages/client/src/Structures/channels/Stage.ts index c07be32a9..bfce0e2b0 100644 --- a/packages/client/src/Structures/channels/Stage.ts +++ b/packages/client/src/Structures/channels/Stage.ts @@ -1,10 +1,9 @@ /* eslint-disable no-useless-call */ /* eslint-disable @typescript-eslint/return-await */ -import type { DiscordChannel } from "@discordeno/types" -import type { StageInstanceOptions } from "../../typings.js" -import type StageInstance from "../guilds/StageInstance.js" -import VoiceChannel from "./Voice.js" - +import type { DiscordChannel } from '@discordeno/types' +import type { StageInstanceOptions } from '../../typings.js' +import type StageInstance from '../guilds/StageInstance.js' +import VoiceChannel from './Voice.js' export class StageChannel extends VoiceChannel { /** The topic of the channel */ diff --git a/packages/client/src/Structures/channels/threads/Member.ts b/packages/client/src/Structures/channels/threads/Member.ts index b4a2b1f0a..99a0a5484 100644 --- a/packages/client/src/Structures/channels/threads/Member.ts +++ b/packages/client/src/Structures/channels/threads/Member.ts @@ -1,9 +1,8 @@ /* eslint-disable no-useless-call */ -import type { BigString, DiscordThreadMember } from "@discordeno/types" -import Base from "../../../Base.js" -import type Client from "../../../Client.js" -import type Member from "../../guilds/Member.js" - +import type { BigString, DiscordThreadMember } from '@discordeno/types' +import Base from '../../../Base.js' +import type Client from '../../../Client.js' +import type Member from '../../guilds/Member.js' export class ThreadMember extends Base { client: Client diff --git a/packages/client/src/Structures/channels/threads/PrivateThread.ts b/packages/client/src/Structures/channels/threads/PrivateThread.ts index 2cac590b3..0dd7a2e3e 100644 --- a/packages/client/src/Structures/channels/threads/PrivateThread.ts +++ b/packages/client/src/Structures/channels/threads/PrivateThread.ts @@ -1,26 +1,25 @@ -import type { DiscordChannel } from "@discordeno/types"; -import type Client from "../../../Client.js"; -import ThreadChannel from "./Thread.js"; - +import type { DiscordChannel } from '@discordeno/types' +import type Client from '../../../Client.js' +import ThreadChannel from './Thread.js' export class PrivateThreadChannel extends ThreadChannel { - constructor(data: DiscordChannel, client: Client, messageLimit?: number) { - super(data, client, messageLimit); + constructor(data: DiscordChannel, client: Client, messageLimit?: number) { + super(data, client, messageLimit) - this.update(data); - } + this.update(data) + } - update(data: DiscordChannel): void { - if(data.thread_metadata !== undefined) { - this.threadMetadata = { - archiveTimestamp: Date.parse(data.thread_metadata.archive_timestamp), - archived: data.thread_metadata.archived, - autoArchiveDuration: data.thread_metadata.auto_archive_duration, - invitable: data.thread_metadata.invitable, - locked: data.thread_metadata.locked - }; - } + update(data: DiscordChannel): void { + if (data.thread_metadata !== undefined) { + this.threadMetadata = { + archiveTimestamp: Date.parse(data.thread_metadata.archive_timestamp), + archived: data.thread_metadata.archived, + autoArchiveDuration: data.thread_metadata.auto_archive_duration, + invitable: data.thread_metadata.invitable, + locked: data.thread_metadata.locked, + } } + } } -export default PrivateThreadChannel; \ No newline at end of file +export default PrivateThreadChannel diff --git a/packages/client/src/Structures/guilds/StageInstance.ts b/packages/client/src/Structures/guilds/StageInstance.ts index 4d14369b3..a31cdb97d 100644 --- a/packages/client/src/Structures/guilds/StageInstance.ts +++ b/packages/client/src/Structures/guilds/StageInstance.ts @@ -1,6 +1,6 @@ /* eslint-disable @typescript-eslint/explicit-function-return-type */ /* eslint-disable no-useless-call */ -import Base from '../../Base.js'; +import Base from '../../Base.js' import type { DiscordStageInstance } from '@discordeno/types' import type Client from '../../Client.js' diff --git a/packages/client/src/Structures/guilds/Unavailable.ts b/packages/client/src/Structures/guilds/Unavailable.ts index f05060ab1..8109817d2 100644 --- a/packages/client/src/Structures/guilds/Unavailable.ts +++ b/packages/client/src/Structures/guilds/Unavailable.ts @@ -1,7 +1,6 @@ -import type { DiscordUnavailableGuild } from "@discordeno/types" -import Base from "../../Base.js" -import type Client from "../../Client.js" - +import type { DiscordUnavailableGuild } from '@discordeno/types' +import Base from '../../Base.js' +import type Client from '../../Client.js' export class UnavailableGuild extends Base { /** Whether or not the guild is unavailable. */ diff --git a/packages/client/src/Structures/interactions/Command.ts b/packages/client/src/Structures/interactions/Command.ts index 30bf12066..25a45534c 100644 --- a/packages/client/src/Structures/interactions/Command.ts +++ b/packages/client/src/Structures/interactions/Command.ts @@ -2,15 +2,15 @@ /* eslint-disable @typescript-eslint/explicit-function-return-type */ /* eslint-disable no-useless-call */ /* eslint-disable @typescript-eslint/return-await */ -import { ApplicationCommandTypes, InteractionResponseTypes } from '@discordeno/types'; +import { ApplicationCommandTypes, InteractionResponseTypes } from '@discordeno/types' -import Collection from '../../Collection.js'; -import Channel from '../channels/Channel.js'; -import Member from '../guilds/Member.js'; -import Role from '../guilds/Role.js'; -import Message from '../Message.js'; -import User from '../users/User.js'; -import Interaction from './Interaction.js'; +import Collection from '../../Collection.js' +import Channel from '../channels/Channel.js' +import Member from '../guilds/Member.js' +import Role from '../guilds/Role.js' +import Message from '../Message.js' +import User from '../users/User.js' +import Interaction from './Interaction.js' import type { BigString, diff --git a/packages/client/src/Structures/toggles/Voice.ts b/packages/client/src/Structures/toggles/Voice.ts index c391a2e39..2e8b5d03a 100644 --- a/packages/client/src/Structures/toggles/Voice.ts +++ b/packages/client/src/Structures/toggles/Voice.ts @@ -1,7 +1,6 @@ /* eslint-disable @typescript-eslint/explicit-function-return-type */ -import type { DiscordVoiceState } from "@discordeno/types" -import { ToggleBitfield } from "./Toggle.js" - +import type { DiscordVoiceState } from '@discordeno/types' +import { ToggleBitfield } from './Toggle.js' export const VoiceStateToggle = { /** Whether this user is deafened by the server */ diff --git a/packages/client/src/Structures/users/Extended.ts b/packages/client/src/Structures/users/Extended.ts index 7a55cb90b..4b49e5aa8 100644 --- a/packages/client/src/Structures/users/Extended.ts +++ b/packages/client/src/Structures/users/Extended.ts @@ -1,7 +1,6 @@ -import type { PremiumTypes, DiscordUser } from "@discordeno/types" -import type Client from "../../Client.js" -import User from "./User.js" - +import type { PremiumTypes, DiscordUser } from '@discordeno/types' +import type Client from '../../Client.js' +import User from './User.js' export class ExtendedUser extends User { email?: string | null diff --git a/packages/client/src/gateway/Shard.ts b/packages/client/src/gateway/Shard.ts index ff39ac435..db5e6fb26 100644 --- a/packages/client/src/gateway/Shard.ts +++ b/packages/client/src/gateway/Shard.ts @@ -4,7 +4,7 @@ /* eslint-disable @typescript-eslint/no-dynamic-delete */ /* eslint-disable @typescript-eslint/restrict-plus-operands */ /* eslint-disable @typescript-eslint/explicit-function-return-type */ -import { Shard as DiscordenoShard, ShardState } from '@discordeno/gateway' +import { DiscordenoShard, ShardState } from '@discordeno/gateway' import type { DiscordGuildStickersUpdate, DiscordThreadMemberUpdate } from '@discordeno/types' import { ActivityTypes, diff --git a/packages/client/src/typings.ts b/packages/client/src/typings.ts index 5f0671ef7..278ef640b 100644 --- a/packages/client/src/typings.ts +++ b/packages/client/src/typings.ts @@ -1,5 +1,3 @@ -// // TYPES - import type { ActivityTypes, ApplicationCommandOptionTypes, @@ -40,8 +38,6 @@ import type GuildIntegration from './Structures/guilds/Integration.js' import type Member from './Structures/guilds/Member.js' import type User from './Structures/users/User.js' -// // Application Commands -// export type AnyApplicationCommand = ChatInputApplicationCommand | MessageApplicationCommand | UserApplicationCommand; export type ApplicationCommandStructure = ChatInputApplicationCommandStructure | MessageApplicationCommandStructure | UserApplicationCommandStructure export type ChatInputApplicationCommand = ApplicationCommand export type ChatInputApplicationCommandStructure = Omit @@ -116,193 +112,39 @@ export type ApplicationCommandOptionsWithValue = | ApplicationCommandOptionsRole | ApplicationCommandOptionsMentionable | ApplicationCommandOptionsNumber -// export type ApplicationCommandPermissionTypes = -// Constants["ApplicationCommandPermissionTypes"][keyof Constants["ApplicationCommandPermissionTypes"]]; -// export type ApplicationCommandTypes = Constants["ApplicationCommandTypes"][keyof Constants["ApplicationCommandTypes"]]; -// // Cache export interface Uncached { id: string } -// // Channel export type AnyChannel = AnyGuildChannel | PrivateChannel | PossiblyUncachedTextable export type AnyGuildChannel = GuildTextableChannel | AnyVoiceChannel | CategoryChannel | AnyThreadChannel -// TODO: Add THREADCHANNEL export type AnyThreadChannel = NewsThreadChannel | PrivateThreadChannel | PublicThreadChannel | ThreadChannel; export type AnyThreadChannel = NewsThreadChannel | PrivateThreadChannel | PublicThreadChannel export type AnyVoiceChannel = TextVoiceChannel | StageChannel export type GuildTextableChannel = TextChannel | TextVoiceChannel | NewsChannel -// export type GuildTextableWithThread = GuildTextableChannel | AnyThreadChannel; -// export type InviteChannel = InvitePartialChannel | Exclude; export type PossiblyUncachedTextable = Textable | Uncached -// export type PossiblyUncachedTextableChannel = TextableChannel | Uncached; export type TextableChannel = (GuildTextable & GuildTextableChannel) | (ThreadTextable & AnyThreadChannel) | (Textable & PrivateChannel) export type VideoQualityMode = VideoQualityModes.Auto | VideoQualityModes.Full -// export type ChannelTypes = GuildChannelTypes | PrivateChannelTypes; -// export type GuildChannelTypes = Exclude; -// export type TextChannelTypes = GuildTextChannelTypes | PrivateChannelTypes; -// export type GuildTextChannelTypes = -// Constants["ChannelTypes"][keyof Pick]; -// export type GuildThreadChannelTypes = Constants["ChannelTypes"][ -// keyof Pick -// ]; -// export type GuildPublicThreadChannelTypes = Exclude< -// GuildThreadChannelTypes, -// Constants["ChannelTypes"]["GUILD_PRIVATE_THREAD"] -// >; -// export type PrivateChannelTypes = Constants["ChannelTypes"][keyof Pick]; export type TextVoiceChannelTypes = ChannelTypes.GuildVoice | ChannelTypes.GuildStageVoice - -// // Command -// export type CommandGenerator = CommandGeneratorFunction | MessageContent | MessageContent[] | CommandGeneratorFunction[]; -// export type CommandGeneratorFunction = (msg: Message, args: string[]) => GeneratorFunctionReturn; -// export type GeneratorFunctionReturn = Promise | Promise | MessageContent | void; -// export type GenericCheckFunction = (msg: Message) => T | Promise; -// export type ReactionButtonsFilterFunction = (msg: Message, emoji: Emoji, userID: string) => boolean; -// export type ReactionButtonsGenerator = -// | ReactionButtonsGeneratorFunction -// | MessageContent -// | MessageContent[] -// | ReactionButtonsGeneratorFunction[]; -// export type ReactionButtonsGeneratorFunction = (msg: Message, args: string[], userID: string) => GeneratorFunctionReturn; - -// // Gateway/REST -// export type IntentStrings = keyof Constants["Intents"]; -// export type ReconnectDelayFunction = (lastDelay: number, attempts: number) => number; -// export type RequestMethod = "GET" | "PATCH" | "DELETE" | "POST" | "PUT"; - -// // Guild -// export type DefaultNotifications = -// Constants["DefaultMessageNotificationLevels"][keyof Constants["DefaultMessageNotificationLevels"]]; -// export type ExplicitContentFilter = Constants["ExplicitContentFilterLevels"][keyof Constants["ExplicitContentFilterLevels"]]; -// export type GuildFeatures = Constants["GuildFeatures"][number]; -// export type NSFWLevel = Constants["GuildNSFWLevels"][keyof Constants["GuildNSFWLevels"]]; -// export type PossiblyUncachedGuild = Guild | Uncached; -// export type PremiumTier = Constants["PremiumTiers"][keyof Constants["PremiumTiers"]]; -// export type VerificationLevel = Constants["VerificationLevels"][keyof Constants["VerificationLevels"]]; -// export type SystemChannelFlags = Constants["SystemChannelFlags"][keyof Constants["SystemChannelFlags"]]; -// export type GuildIntegrationTypes = Constants["GuildIntegrationTypes"][number]; -// export type GuildIntegrationExpireBehavior = -// Constants["GuildIntegrationExpireBehavior"][keyof Constants["GuildIntegrationExpireBehavior"]]; - -// // Interaction -// export type AnyInteraction = PingInteraction | CommandInteraction | ComponentInteraction | AutocompleteInteraction; -// export type InteractionCallbackData = InteractionAutocomplete | InteractionContent; export type InteractionContent = Pick export type InteractionContentEdit = Pick -// export type InteractionDataOptions = -// | InteractionDataOptionsSubCommand -// | InteractionDataOptionsSubCommandGroup -// | InteractionDataOptionsWithValue; -// export type InteractionDataOptionsBoolean = InteractionDataOptionWithValue< -// Constants["ApplicationCommandOptionTypes"]["BOOLEAN"], -// boolean -// >; -// export type InteractionDataOptionsChannel = InteractionDataOptionWithValue< -// Constants["ApplicationCommandOptionTypes"]["CHANNEL"], -// string -// >; -// export type InteractionDataOptionsInteger = InteractionDataOptionWithValue< -// Constants["ApplicationCommandOptionTypes"]["INTEGER"], -// number -// >; -// export type InteractionDataOptionsMentionable = InteractionDataOptionWithValue< -// Constants["ApplicationCommandOptionTypes"]["MENTIONABLE"], -// string -// >; -// export type InteractionDataOptionsNumber = InteractionDataOptionWithValue< -// ApplicationCommandOptionTypes.Number, -// number -// >; -// export type InteractionDataOptionsRole = InteractionDataOptionWithValue< -// Constants["ApplicationCommandOptionTypes"]["ROLE"], -// string -// >; -// export type InteractionDataOptionsString = InteractionDataOptionWithValue< -// ApplicationCommandOptionTypes.String, -// string -// >; -// export type InteractionDataOptionsUser = InteractionDataOptionWithValue< -// Constants["ApplicationCommandOptionTypes"]["USER"], -// string -// >; -// export type InteractionDataOptionsWithValue = -// | InteractionDataOptionsString -// | InteractionDataOptionsInteger -// | InteractionDataOptionsBoolean -// | InteractionDataOptionsUser -// | InteractionDataOptionsChannel -// | InteractionDataOptionsRole -// | InteractionDataOptionsMentionable -// | InteractionDataOptionsNumber; -// export type InteractionResponseTypes = Constants["InteractionResponseTypes"][keyof Constants["InteractionResponseTypes"]]; -// export type InteractionTypes = Constants["InteractionTypes"][keyof Constants["InteractionTypes"]]; - -// // Invite -// export type InviteTargetTypes = Constants["InviteTargetTypes"][keyof Constants["InviteTargetTypes"]]; - -// // Message export type ActionRowComponents = Button | SelectMenu export type Button = InteractionButton | URLButton -// export type ButtonStyles = Constants["ButtonStyles"][keyof Constants["ButtonStyles"]]; -// export type Component = ActionRow | ActionRowComponents; -// export type ImageFormat = Constants["ImageFormats"][number]; -// export type MessageActivityFlags = Constants["MessageActivityFlags"][keyof Constants["MessageActivityFlags"]]; export type MessageContent = string | AdvancedMessageContent export type MessageContentEdit = string | AdvancedMessageContentEdit -// export type MFALevel = Constants["MFALevels"][keyof Constants["MFALevels"]]; -// export type PossiblyUncachedMessage = Message | { -// channel: TextableChannel | { id: string; guild?: Uncached }; -// guildID?: string; -// id: string; -// }; - -// // Permission -// export type PermissionType = Constants["PermissionOverwriteTypes"][keyof Constants["PermissionOverwriteTypes"]]; - -// // Presence/Relationship export type ActivityType = ActivityTypes export type BotActivityType = Exclude - -// export type FriendSuggestionReasons = { name: string; platform_type: string; type: number }[]; export type Status = 'online' | 'idle' | 'dnd' export type SelfStatus = Status | 'invisible' -// export type UserStatus = Status | "offline"; - -// // Selfbot -// export type ConnectionVisibilityTypes = Constants["ConnectionVisibilityTypes"][keyof Constants["ConnectionVisibilityTypes"]]; - -// // Sticker -// export type StickerTypes = Constants["StickerTypes"][keyof Constants["StickerTypes"]]; -// export type StickerFormats = Constants["StickerFormats"][keyof Constants["StickerFormats"]]; - -// // Thread export type AutoArchiveDuration = 60 | 1440 | 4320 | 10080 - -// // User -// export type PremiumTypes = Constants["PremiumTypes"][keyof Constants["PremiumTypes"]]; - -// // Voice -// export type ConverterCommand = "./ffmpeg" | "./avconv" | "ffmpeg" | "avconv"; -// export type StageInstancePrivacyLevel = Constants["StageInstancePrivacyLevel"][keyof Constants["StageInstancePrivacyLevel"]]; - -// // Webhook export type MessageWebhookContent = Pick -// export type WebhookTypes = Constants["WebhookTypes"][keyof Constants["WebhookTypes"]]; - -// // INTERFACES -// // Internals export interface JSONCache { [s: string]: unknown } -// export interface NestedJSON { -// toJSON(arg?: unknown, cache?: (string | unknown)[]): JSONCache; -// } export interface SimpleJSON { toJSON: (props?: string[]) => JSONCache } -// // Application Commands export interface ApplicationCommand { application_id: string defaultPermission?: boolean @@ -325,19 +167,6 @@ export interface ApplicationCommandOptionsSubCommandGroup { options?: Array type: ApplicationCommandOptionTypes.SubCommandGroup } -// export interface ApplicationCommandOptionChoice< -// T extends -// | Constants["ApplicationCommandOptionTypes"][ -// keyof Pick -// ] -// | unknown = unknown, -// > { -// name: string; -// value: T extends ApplicationCommandOptionTypes.String ? string -// : T extends ApplicationCommandOptionTypes.Number ? number -// : T extends Constants["ApplicationCommandOptionTypes"]["INTEGER"] ? number -// : number | string; -// } export interface ApplicationCommandOptionWithChoices< T extends ApplicationCommandOptionTypes.String | ApplicationCommandOptionTypes.Integer | ApplicationCommandOptionTypes.Number = | ApplicationCommandOptionTypes.String @@ -351,22 +180,6 @@ export interface ApplicationCommandOptionWithChoices< required?: boolean type: T } -// export interface ApplicationCommandOptionWithMinMax< -// T extends Constants["ApplicationCommandOptionTypes"][ -// keyof Pick -// ] = Constants["ApplicationCommandOptionTypes"][ -// keyof Pick -// ], -// > { -// autocomplete?: boolean; -// choices?: ApplicationCommandOptionChoice[]; -// description: string; -// max_value?: number; -// min_value?: number; -// name: string; -// required?: boolean; -// type: T; -// } export interface ApplicationCommandOption< T extends Exclude, > { @@ -401,7 +214,6 @@ export interface GuildApplicationCommandPermissions { permissions?: ApplicationCommandPermissions[] } -// // Channel export interface ChannelFollow { channel_id: string webhook_id: string @@ -445,10 +257,6 @@ export interface GetMessagesOptions { before?: string limit?: number } -// export interface GuildPinnable extends Pinnable { -// lastPinTimestamp: number | null; -// topic?: string | null; -// } export interface GuildTextable extends Textable { rateLimitPerUser: number createWebhook: (options: { name: string; avatar?: string | null }, reason?: string) => Promise @@ -497,7 +305,6 @@ export interface Textable { sendTyping: () => Promise unsendMessage: (messageID: string) => Promise } -// // @ts-ignore ts(2430) - ThreadTextable can't properly extend Textable because of getMessageReaction deprecated overload export interface ThreadTextable extends Textable, Pinnable { lastPinTimestamp?: number deleteMessages: (messageIDs: string[], reason?: string) => Promise @@ -508,52 +315,7 @@ export interface ThreadTextable extends Textable, Pinnable { removeMessageReactionEmoji: (messageID: string, reaction: string) => Promise removeMessageReactions: (messageID: string) => Promise } -// export interface WebhookData { -// channelID: string; -// guildID: string; -// } - -// // Client -// export interface ClientOptions { -// allowedMentions?: AllowedMentions; -// autoreconnect?: boolean; -// compress?: boolean; -// connectionTimeout?: number; -// defaultImageFormat?: string; -// defaultImageSize?: number; -// disableEvents?: { [s: string]: boolean }; -// firstShardID?: number; -// getAllUsers?: boolean; -// guildCreateTimeout?: number; -// intents: number | IntentStrings[]; -// largeThreshold?: number; -// lastShardID?: number; -// maxReconnectAttempts?: number; -// maxResumeAttempts?: number; -// maxShards?: number | "auto"; -// messageLimit?: number; -// opusOnly?: boolean; -// reconnectDelay?: ReconnectDelayFunction; -// requestTimeout?: number; -// rest?: RequestHandlerOptions; -// restMode?: boolean; -// seedVoiceConnections?: boolean; -// shardConcurrency?: number | "auto"; -// ws?: unknown; -// } -// export interface CommandClientOptions { -// argsSplitter?: (str: string) => string[]; -// defaultCommandOptions?: CommandOptions; -// defaultHelpCommand?: boolean; -// description?: string; -// ignoreBots?: boolean; -// ignoreSelf?: boolean; -// name?: string; -// owner?: string; -// prefix?: string | string[]; -// } export interface RequestHandlerOptions { - // agent?: HTTPSAgent; baseURL?: string decodeReasons?: boolean disableLatencyCompensation?: boolean @@ -563,75 +325,6 @@ export interface RequestHandlerOptions { requestTimeout?: number } -// // Command -// export interface CommandCooldownExclusions { -// channelIDs?: string[]; -// guildIDs?: string[]; -// userIDs?: string[]; -// } -// export interface CommandOptions { -// aliases?: string[]; -// argsRequired?: boolean; -// caseInsensitive?: boolean; -// cooldown?: number; -// cooldownExclusions?: CommandCooldownExclusions; -// cooldownMessage?: MessageContent | GenericCheckFunction | false; -// cooldownReturns?: number; -// defaultSubcommandOptions?: CommandOptions; -// deleteCommand?: boolean; -// description?: string; -// dmOnly?: boolean; -// errorMessage?: MessageContent | GenericCheckFunction; -// fullDescription?: string; -// guildOnly?: boolean; -// hidden?: boolean; -// hooks?: Hooks; -// invalidUsageMessage?: MessageContent | GenericCheckFunction | false; -// permissionMessage?: MessageContent | GenericCheckFunction | false; -// reactionButtons?: CommandReactionButtonsOptions[] | null; -// reactionButtonTimeout?: number; -// requirements?: CommandRequirements; -// restartCooldown?: boolean; -// usage?: string; -// } -// export interface CommandReactionButtons extends CommandReactionButtonsOptions { -// execute: (msg: Message, args: string[], userID: string) => string | GeneratorFunctionReturn; -// responses: ((() => string) | ReactionButtonsGeneratorFunction)[]; -// } -// export interface CommandReactionButtonsOptions { -// emoji: string; -// filter: ReactionButtonsFilterFunction; -// response: string | ReactionButtonsGeneratorFunction; -// type: "edit" | "cancel"; -// } -// export interface CommandRequirements { -// custom?: GenericCheckFunction; -// permissions?: { [s: string]: boolean } | GenericCheckFunction<{ [s: string]: boolean }>; -// roleIDs?: string[] | GenericCheckFunction; -// roleNames?: string[] | GenericCheckFunction; -// userIDs?: string[] | GenericCheckFunction; -// } -// export interface Hooks { -// postCheck?: (msg: Message, args: string[], checksPassed: boolean) => void; -// postCommand?: (msg: Message, args: string[], sent?: Message) => void; -// postExecution?: (msg: Message, args: string[], executionSuccess: boolean) => void; -// preCommand?: (msg: Message, args: string[]) => void; -// } - -// // Embed -// // Omit used to override -// export interface Embed extends Omit { -// author?: EmbedAuthor; -// footer?: EmbedFooter; -// image?: EmbedImage; -// provider?: EmbedProvider; -// thumbnail?: EmbedImage; -// type: string; -// video?: EmbedVideo; -// } -// export interface EmbedAuthor extends EmbedAuthorOptions { -// proxy_icon_url?: string; -// } export interface EmbedAuthorOptions { icon_url?: string name: string @@ -642,18 +335,10 @@ export interface EmbedField { name: string value: string } -// export interface EmbedFooter extends EmbedFooterOptions { -// proxy_icon_url?: string; -// } export interface EmbedFooterOptions { icon_url?: string text: string } -// export interface EmbedImage extends EmbedImageOptions { -// height?: number; -// proxy_url?: string; -// width?: number; -// } export interface EmbedImageOptions { url?: string } @@ -669,18 +354,6 @@ export interface EmbedOptions { title?: string url?: string } -// export interface EmbedProvider { -// name?: string; -// url?: string; -// } -// export interface EmbedVideo { -// height?: number; -// proxy_url?: string; -// url?: string; -// width?: number; -// } - -// // Emoji export interface Emoji extends EmojiBase { animated: boolean available: boolean @@ -704,278 +377,6 @@ export interface PartialEmoji { animated?: boolean } -// // Events -// export interface OldCall { -// endedTimestamp?: number; -// participants: string[]; -// region: string; -// ringing: string[]; -// unavailable: boolean; -// } -// export interface OldGroupChannel { -// name: string; -// ownerID: string; -// icon: string; -// type: Constants["ChannelTypes"]["GROUP_DM"]; -// } -// export interface OldGuild { -// afkChannelID: string | null; -// afkTimeout: number; -// banner: string | null; -// defaultNotifications: DefaultNotifications; -// description: string | null; -// discoverySplash: string | null; -// emojis: Omit[]; -// explicitContentFilter: ExplicitContentFilter; -// features: GuildFeatures[]; -// icon: string | null; -// large: boolean; -// maxMembers?: number; -// maxVideoChannelUsers?: number; -// mfaLevel: MFALevel; -// name: string; -// nsfwLevel: NSFWLevel; -// ownerID: string; -// preferredLocale?: string; -// premiumSubscriptionCount?: number; -// premiumTier: PremiumTier; -// publicUpdatesChannelID: string | null; -// rulesChannelID: string | null; -// splash: string | null; -// stickers?: Sticker[]; -// systemChannelFlags: SystemChannelFlags; -// systemChannelID: string | null; -// vanityURL: string | null; -// verificationLevel: VerificationLevel; -// } -// export interface OldGuildChannel { -// bitrate?: number; -// name: string; -// nsfw?: boolean; -// parentID: string | null; -// permissionOverwrites: Collection; -// position: number; -// rateLimitPerUser?: number; -// rtcRegion?: string | null; -// topic?: string | null; -// type: GuildChannelTypes; -// } -// export interface OldGuildTextChannel extends OldGuildChannel { -// nsfw: boolean; -// rateLimitPerUser: number; -// topic: string | null; -// type: GuildTextChannelTypes; -// } -// export interface OldMember { -// avatar: string | null; -// communicationDisabledUntil: number | null; -// nick: string | null; -// pending?: boolean; -// premiumSince?: number | null; -// roles: string[]; -// } -// export interface OldMessage { -// attachments: Attachment[]; -// channelMentions: string[]; -// content: string; -// editedTimestamp?: number; -// embeds: Embed[]; -// flags: number; -// mentionedBy?: unknown; -// mentions: User[]; -// pinned: boolean; -// roleMentions: string[]; -// tts: boolean; -// } -// export interface OldRole { -// color: number; -// hoist: boolean; -// icon: string | null; -// managed: boolean; -// mentionable: boolean; -// name: string; -// permissions: Permission; -// position: number; -// unicodeEmoji: string | null; -// } -// export interface OldStageInstance { -// discoverableDisabled: boolean; -// privacyLevel: StageInstancePrivacyLevel; -// topic: string; -// } -// export interface OldTextVoiceChannel extends OldGuildChannel { -// bitrate: number; -// rtcRegion: string | null; -// type: TextVoiceChannelTypes; -// userLimit: number; -// videoQualityMode: VideoQualityMode; -// } -// export interface OldThread { -// name: string; -// rateLimitPerUser: number; -// threadMetadata: ThreadMetadata; -// } -// export interface OldThreadMember { -// flags: number; -// } -// export interface OldVoiceState { -// deaf: boolean; -// mute: boolean; -// selfDeaf: boolean; -// selfMute: boolean; -// selfStream: boolean; -// selfVideo: boolean; -// } -// export interface EventListeners { -// callCreate: [call: Call]; -// callDelete: [call: Call]; -// callRing: [call: Call]; -// callUpdate: [call: Call, oldCall: OldCall]; -// channelCreate: [channel: AnyGuildChannel]; -// channelDelete: [channel: AnyChannel]; -// channelPinUpdate: [channel: TextableChannel, timestamp: number, oldTimestamp: number]; -// channelRecipientAdd: [channel: GroupChannel, user: User]; -// channelRecipientRemove: [channel: GroupChannel, user: User]; -// channelUpdate: -// | [channel: AnyGuildChannel, oldChannel: OldGuildChannel | OldGuildTextChannel | OldTextVoiceChannel] -// | [channel: GroupChannel, oldChannel: OldGroupChannel]; -// connect: [id: number]; -// debug: [message: string, id?: number]; -// disconnect: []; -// error: [err: Error, id?: number]; -// friendSuggestionCreate: [user: User, reasons: FriendSuggestionReasons]; -// friendSuggestionDelete: [user: User]; -// guildAvailable: [guild: Guild]; -// guildBanAdd: [guild: Guild, user: User]; -// guildBanRemove: [guild: Guild, user: User]; -// guildCreate: [guild: Guild]; -// guildDelete: [guild: PossiblyUncachedGuild]; -// guildEmojisUpdate: [guild: PossiblyUncachedGuild, emojis: Emoji[], oldEmojis: Emoji[] | null]; -// guildMemberAdd: [guild: Guild, member: Member]; -// guildMemberChunk: [guild: Guild, member: Member[]]; -// guildMemberRemove: [guild: Guild, member: Member | MemberPartial]; -// guildMemberUpdate: [guild: Guild, member: Member, oldMember: OldMember | null]; -// guildRoleCreate: [guild: Guild, role: Role]; -// guildRoleDelete: [guild: Guild, role: Role]; -// guildRoleUpdate: [guild: Guild, role: Role, oldRole: OldRole]; -// guildStickersUpdate: [guild: PossiblyUncachedGuild, stickers: Sticker[], oldStickers: Sticker[] | null]; -// guildUnavailable: [guild: UnavailableGuild]; -// guildUpdate: [guild: Guild, oldGuild: OldGuild]; -// hello: [trace: string[], id: number]; -// interactionCreate: [ -// interaction: -// | PingInteraction -// | CommandInteraction -// | ComponentInteraction -// | AutocompleteInteraction -// | UnknownInteraction, -// ]; -// inviteCreate: [guild: Guild, invite: Invite]; -// inviteDelete: [guild: Guild, invite: Invite]; -// messageCreate: [message: Message]; -// messageDelete: [message: PossiblyUncachedMessage]; -// messageDeleteBulk: [messages: PossiblyUncachedMessage[]]; -// messageReactionAdd: [message: PossiblyUncachedMessage, emoji: PartialEmoji, reactor: Member | Uncached]; -// messageReactionRemove: [message: PossiblyUncachedMessage, emoji: PartialEmoji, userID: string]; -// messageReactionRemoveAll: [message: PossiblyUncachedMessage]; -// messageReactionRemoveEmoji: [message: PossiblyUncachedMessage, emoji: PartialEmoji]; -// messageUpdate: [message: Message, oldMessage: OldMessage | null]; -// presenceUpdate: [other: Member | Relationship, oldPresence: Presence | null]; -// rawREST: [request: RawRESTRequest]; -// rawWS: [packet: RawPacket, id: number]; -// ready: []; -// relationshipAdd: [relationship: Relationship]; -// relationshipRemove: [relationship: Relationship]; -// relationshipUpdate: [relationship: Relationship, oldRelationship: { type: number }]; -// shardPreReady: [id: number]; -// stageInstanceCreate: [stageInstance: StageInstance]; -// stageInstanceDelete: [stageInstance: StageInstance]; -// stageInstanceUpdate: [stageInstance: StageInstance, oldStageInstance: OldStageInstance | null]; -// threadCreate: [channel: AnyThreadChannel]; -// threadDelete: [channel: AnyThreadChannel]; -// threadListSync: [ -// guild: Guild, -// deletedThreads: (AnyThreadChannel | Uncached)[], -// activeThreads: AnyThreadChannel[], -// joinedThreadsMember: ThreadMember[], -// ]; -// threadMembersUpdate: [ -// channel: AnyThreadChannel, -// addedMembers: ThreadMember[], -// removedMembers: (ThreadMember | Uncached)[], -// ]; -// threadMemberUpdate: [channel: AnyThreadChannel, member: ThreadMember, oldMember: OldThreadMember]; -// threadUpdate: [channel: AnyThreadChannel, oldChannel: OldThread | null]; -// typingStart: -// | [channel: GuildTextableChannel | Uncached, user: User | Uncached, member: Member] -// | [channel: PrivateChannel | Uncached, user: User | Uncached, member: null]; -// unavailableGuildCreate: [guild: UnavailableGuild]; -// unknown: [packet: RawPacket, id?: number]; -// userUpdate: [user: User, oldUser: PartialUser | null]; -// voiceChannelJoin: [member: Member, channel: AnyVoiceChannel]; -// voiceChannelLeave: [member: Member, channel: AnyVoiceChannel]; -// voiceChannelSwitch: [member: Member, newChannel: AnyVoiceChannel, oldChannel: AnyVoiceChannel]; -// voiceStateUpdate: [member: Member, oldState: OldVoiceState]; -// warn: [message: string, id?: number]; -// webhooksUpdate: [data: WebhookData]; -// } -// export interface ClientEvents extends EventListeners { -// shardDisconnect: [err: Error | undefined, id: number]; -// shardReady: [id: number]; -// shardResume: [id: number]; -// } -// export interface ShardEvents extends EventListeners { -// resume: []; -// } -// export interface StreamEvents { -// end: []; -// error: [err: Error]; -// start: []; -// } -// export interface VoiceEvents { -// connect: []; -// debug: [message: string]; -// disconnect: [err?: Error]; -// end: []; -// error: [err: Error]; -// pong: [latency: number]; -// ready: []; -// speakingStart: [userID: string]; -// speakingStop: [userID: string]; -// start: []; -// unknown: [packet: RawPacket]; -// userDisconnect: [userID: string]; -// warn: [message: string]; -// } - -// // Gateway/REST -// export interface HTTPResponse { -// code: number; -// message: string; -// } -// export interface LatencyRef { -// lastTimeOffsetCheck: number; -// latency: number; -// raw: number[]; -// timeOffset: number; -// timeOffsets: number[]; -// } -// export interface RawPacket { -// d?: unknown; -// op: number; -// s?: number; -// t?: string; -// } -// export interface RawRESTRequest { -// auth: boolean; -// body?: unknown; -// file?: FileContent; -// method: string; -// resp: IncomingMessage; -// route: string; -// short: boolean; -// url: string; -// } export interface RequestMembersPromise { members: Member[] received: number @@ -986,7 +387,6 @@ export interface ShardManagerOptions { concurrency?: number | 'auto' } -// // Guild export interface CreateGuildOptions { afkChannelID?: string afkTimeout?: number @@ -1066,7 +466,7 @@ export interface GuildOptions { description?: string discoverySplash?: string explicitContentFilter?: ExplicitContentFilterLevels - features?: GuildFeatures[] // Though only some are editable? + features?: GuildFeatures[] icon?: string name?: string ownerID?: string @@ -1086,14 +486,6 @@ export interface GuildVanity { code: string | null uses: number } -// export interface IntegrationApplication { -// bot?: User; -// description: string; -// icon: string | null; -// id: string; -// name: string; -// summary: string; -// } export interface IntegrationOptions { enableEmoticons?: string expireBehavior?: string @@ -1150,33 +542,6 @@ export interface WidgetMember { username: string } -// // Interaction -// export interface InteractionAutocomplete { -// choices: ApplicationCommandOptionChoice[]; -// } -// export interface InteractionDataOptionsSubCommand { -// name: string; -// options?: InteractionDataOptions[]; -// type: Constants["ApplicationCommandOptionTypes"]["SUB_COMMAND"]; -// } -// export interface InteractionDataOptionsSubCommandGroup { -// name: string; -// options: InteractionDataOptions[]; -// type: Constants["ApplicationCommandOptionTypes"]["SUB_COMMAND_GROUP"]; -// } -// export interface InteractionDataOptionWithValue< -// T extends Constants["ApplicationCommandOptionTypes"][ -// Exclude -// ] = Constants["ApplicationCommandOptionTypes"][ -// Exclude -// ], -// V = unknown, -// > { -// focused?: boolean; -// name: string; -// type: T; -// value: V; -// } /** https://discord.com/developers/docs/interactions/slash-commands#interaction-response */ export interface InteractionResponse { type: InteractionResponseTypes @@ -1201,7 +566,6 @@ export interface ApplicationCommandOptionChoice { value: string | number } -// // Invite export interface CreateChannelInviteOptions extends CreateInviteOptions { targetApplicationID?: string targetType?: InviteTargetTypes @@ -1213,25 +577,6 @@ export interface CreateInviteOptions { temporary?: boolean unique?: boolean } -// export interface Invitable { -// createInvite(options?: CreateInviteOptions, reason?: string): Promise; -// getInvites(): Promise; -// } -// export interface InvitePartialChannel { -// icon?: string | null; -// id: string; -// name: string | null; -// recipients?: { username: string }[]; -// type: Exclude; -// } -// export interface InviteStageInstance { -// members: Member[]; -// participantCount: number; -// speakerCount: number; -// topic: string; -// } - -// // Member/User export interface FetchMembersOptions { limit?: number presences?: boolean @@ -1247,13 +592,6 @@ export interface MemberOptions { nick?: string | null roles?: string[] } -// export interface MemberPartial { -// id: string; -// user: User; -// } -// export interface MemberRoles extends BaseData { -// roles: string[]; -// } export interface PartialUser { accentColor?: number | null avatar: string | null @@ -1266,23 +604,10 @@ export interface RequestGuildMembersOptions extends Omit void; -// timeout: number; -// } - -// // Message export interface ActionRow { components: ActionRowComponents[] type: MessageComponentTypes.ActionRow } -// export interface ActiveMessages { -// args: string[]; -// command: Command; -// timeout: number; -// } export interface AdvancedMessageContent { allowedMentions?: AllowedMentions components?: ActionRow[] @@ -1307,17 +632,6 @@ export interface AllowedMentions { /** The users to allow mentioning by default or enable all users to be able to be mentioned by default. */ users?: boolean | string[] } -// export interface Attachment { -// content_export type?: string; -// ephemeral?: boolean; -// filename: string; -// height?: number; -// id: string; -// proxy_url: string; -// size: number; -// url: string; -// width?: number; -// } export interface ButtonBase { disabled?: boolean emoji?: Partial @@ -1357,33 +671,12 @@ export interface InteractionButton extends ButtonBase { custom_id: string style: Exclude } -// export interface MessageActivity { -// party_id?: string; -// type: MessageActivityFlags; -// } -// export interface MessageApplication { -// cover_image?: string; -// description: string; -// icon: string | null; -// id: string; -// name: string; -// } export interface FileContent { /** The file data. */ file: Buffer | string /** The name of the file, which must include the file suffix. */ name: string } -// export interface MessageInteraction { -// id: string; -// member: Member | null; -// name: string; -// type: InteractionTypes; -// user: User; -// } -// export interface MessageReference extends MessageReferenceBase { -// channelID: string; -// } export interface MessageReferenceBase { channelID?: string guildID?: string @@ -1422,7 +715,6 @@ export interface URLButton extends ButtonBase { url: string } -// // Presence export interface Activity extends ActivityPartial { application_id?: string assets?: { @@ -1442,7 +734,6 @@ export interface Activity extends Activit state?: string timestamps?: { end?: number; start: number } type: T - // the stuff attached to this object apparently varies even more than documented, so... [key: string]: unknown } export interface ActivityPartial { @@ -1456,18 +747,6 @@ export interface ClientPresence { since: number | null status: SelfStatus } -// export interface ClientStatus { -// desktop: UserStatus; -// mobile: UserStatus; -// web: UserStatus; -// } -// export interface Presence { -// activities?: Activity[]; -// clientStatus?: ClientStatus; -// status?: UserStatus; -// } - -// // Role export interface Overwrite { allow: bigint | number deny: bigint | number @@ -1492,13 +771,6 @@ export interface RoleOptions { permissions?: bigint | number | string | Permission unicodeEmoji?: string } -// export interface RoleTags { -// bot_id?: string; -// integration_id?: string; -// premium_subscriber?: true; -// } - -// // Thread export interface CreateThreadOptions { autoArchiveDuration: AutoArchiveDuration name: string @@ -1522,17 +794,6 @@ export interface ListedGuildThreads members: ThreadMember[] threads: T[] } -// export interface PrivateThreadMetadata extends ThreadMetadata { -// invitable: boolean; -// } -// export interface ThreadMetadata { -// archiveTimestamp: number; -// archived: boolean; -// autoArchiveDuration: AutoArchiveDuration; -// locked: boolean; -// } - -// // Voice export interface JoinVoiceChannelOptions { opusOnly?: boolean selfDeaf?: boolean @@ -1543,49 +804,11 @@ export interface StageInstanceOptions { privacyLevel?: ScheduledEventPrivacyLevel topic?: string } -// export interface UncachedMemberVoiceState { -// id: string; -// voiceState: OldVoiceState; -// } -// export interface VoiceConnectData { -// channel_id: string; -// endpoint: string; -// session_id: string; -// token: string; -// user_id: string; -// } -// export interface VoiceResourceOptions { -// encoderArgs?: string[]; -// format?: string; -// frameDuration?: number; -// frameSize?: number; -// inlineVolume?: boolean; -// inputArgs?: string[]; -// pcmSize?: number; -// samplingRate?: number; -// voiceDataTimeout?: number; -// } -// export interface VoiceServerUpdateData extends Omit { -// guild_id: string; -// shard: Shard; -// } export interface VoiceStateOptions { channelID: string requestToSpeakTimestamp?: Date | null suppress?: boolean } -// export interface VoiceStreamCurrent { -// buffer: Buffer | null; -// bufferingTicks: number; -// options: VoiceResourceOptions; -// pausedTime?: number; -// pausedTimestamp?: number; -// playTime: number; -// startTime: number; -// timeout: number | null; -// } - -// // Webhook export interface Webhook { application_id: string | null avatar: string | null @@ -1621,11 +844,6 @@ export interface WebhookPayload { wait?: boolean } -// // TODO: Does this have more stuff? -// export interface BaseData { -// id: string; -// [key: string]: unknown; -// } export interface OAuthApplicationInfo { bot_public: boolean bot_require_code_grant: boolean @@ -1653,261 +871,10 @@ export interface OAuthTeamMember { team_id: string user: PartialUser } -// export interface Constants { -// GATEWAY_VERSION: 9; -// REST_VERSION: 9; -// ActivityTypes: { -// GAME: 0; -// STREAMING: 1; -// LISTENING: 2; -// WATCHING: 3; -// CUSTOM: 4; -// COMPETING: 5; -// }; -// ApplicationCommandOptionTypes: { -// SUB_COMMAND: 1; -// SUB_COMMAND_GROUP: 2; -// STRING: 3; -// INTEGER: 4; -// BOOLEAN: 5; -// USER: 6; -// CHANNEL: 7; -// ROLE: 8; -// MENTIONABLE: 9; -// NUMBER: 10; -// }; -// ApplicationCommandTypes: { -// CHAT_INPUT: 1; -// USER: 2; -// MESSAGE: 3; -// }; -// AuditLogActions: { -// GUILD_UPDATE: 1; - -// CHANNEL_CREATE: 10; -// CHANNEL_UPDATE: 11; -// CHANNEL_DELETE: 12; -// CHANNEL_OVERWRITE_CREATE: 13; -// CHANNEL_OVERWRITE_UPDATE: 14; -// CHANNEL_OVERWRITE_DELETE: 15; - -// MEMBER_KICK: 20; -// MEMBER_PRUNE: 21; -// MEMBER_BAN_ADD: 22; -// MEMBER_BAN_REMOVE: 23; -// MEMBER_UPDATE: 24; -// MEMBER_ROLE_UPDATE: 25; -// MEMBER_MOVE: 26; -// MEMBER_DISCONNECT: 27; -// BOT_ADD: 28; - -// ROLE_CREATE: 30; -// ROLE_UPDATE: 31; -// ROLE_DELETE: 32; - -// INVITE_CREATE: 40; -// INVITE_UPDATE: 41; -// INVITE_DELETE: 42; - -// WEBHOOK_CREATE: 50; -// WEBHOOK_UPDATE: 51; -// WEBHOOK_DELETE: 52; - -// EMOJI_CREATE: 60; -// EMOJI_UPDATE: 61; -// EMOJI_DELETE: 62; - -// MESSAGE_DELETE: 72; -// MESSAGE_BULK_DELETE: 73; -// MESSAGE_PIN: 74; -// MESSAGE_UNPIN: 75; - -// INTEGRATION_CREATE: 80; -// INTEGRATION_UPDATE: 81; -// INTEGRATION_DELETE: 82; -// STAGE_INSTANCE_CREATE: 83; -// STAGE_INSTANCE_UPDATE: 84; -// STAGE_INSTANCE_DELETE: 85; - -// STICKER_CREATE: 90; -// STICKER_UPDATE: 91; -// STICKER_DELETE: 92; - -// GUILD_SCHEDULED_EVENT_CREATE: 100; -// GUILD_SCHEDULED_EVENT_UPDATE: 101; -// GUILD_SCHEDULED_EVENT_DELETE: 102; - -// THREAD_CREATE: 110; -// THREAD_UPDATE: 111; -// THREAD_DELETE: 112; - -// APPLICATION_COMMAND_PERMISSION_UPDATE: 121; -// }; -// ButtonStyles: { -// PRIMARY: 1; -// SECONDARY: 2; -// SUCCESS: 3; -// DANGER: 4; -// LINK: 5; -// }; -// ChannelTypes: { -// GUILD_TEXT: 0; -// DM: 1; -// GUILD_VOICE: 2; -// GROUP_DM: 3; -// GUILD_CATEGORY: 4; -// GUILD_NEWS: 5; -// GUILD_STORE: 6; - -// GUILD_NEWS_THREAD: 10; -// GUILD_PUBLIC_THREAD: 11; -// GUILD_PRIVATE_THREAD: 12; -// GUILD_STAGE_VOICE: 13; -// }; -// ComponentTypes: { -// ACTION_ROW: 1; -// BUTTON: 2; -// SELECT_MENU: 3; -// }; -// ConnectionVisibilityTypes: { -// NONE: 0; -// EVERYONE: 1; -// }; -// DefaultMessageNotificationLevels: { -// ALL_MESSAGES: 0; -// ONLY_MENTIONS: 1; -// }; -// ExplicitContentFilterLevels: { -// DISABLED: 0; -// MEMBERS_WITHOUT_ROLES: 1; -// ALL_MEMBERS: 2; -// }; -// GatewayOPCodes: { -// DISPATCH: 0; -// HEARTBEAT: 1; -// IDENTIFY: 2; -// PRESENCE_UPDATE: 3; -// VOICE_STATE_UPDATE: 4; -// VOICE_SERVER_PING: 5; -// RESUME: 6; -// RECONNECT: 7; -// REQUEST_GUILD_MEMBERS: 8; -// INVALID_SESSION: 9; -// HELLO: 10; -// HEARTBEAT_ACK: 11; -// SYNC_GUILD: 12; -// SYNC_CALL: 13; -// }; -// GuildFeatures: [ -// "ANIMATED_ICON", -// "BANNER", -// "COMMERCE", -// "COMMUNITY", -// "DISCOVERABLE", -// "FEATURABLE", -// "INVITE_SPLASH", -// "MEMBER_VERIFICATION_GATE_ENABLED", -// "MONETIZATION_ENABLED", -// "MORE_STICKERS", -// "NEWS", -// "PARTNERED", -// "PREVIEW_ENABLED", -// "PRIVATE_THREADS", -// "ROLE_ICONS", -// "ROLE_SUBSCRIPTIONS_ENABLED", -// "SEVEN_DAY_THREAD_ARCHIVE", -// "THREE_DAY_THREAD_ARCHIVE", -// "TICKETED_EVENTS_ENABLED", -// "VANITY_URL", -// "VERIFIED", -// "VIP_REGIONS", -// "WELCOME_SCREEN_ENABLED", -// ]; -// GuildIntegrationExpireBehavior: { -// REMOVE_ROLE: 0; -// KICK: 1; -// }; -// GuildIntegrationTypes: [ -// "twitch", -// "youtube", -// "discord", -// ]; -// GuildNSFWLevels: { -// DEFAULT: 0; -// EXPLICIT: 1; -// SAFE: 2; -// AGE_RESTRICTED: 3; -// }; -// ImageFormats: [ -// "jpg", -// "jpeg", -// "png", -// "webp", -// "gif", -// ]; -// ImageSizeBoundaries: { -// MAXIMUM: 4096; -// MINIMUM: 16; -// }; -// Intents: { -// guilds: 1; -// guildMembers: 2; -// guildBans: 4; -// guildEmojisAndStickers: 8; -// guildIntegrations: 16; -// guildWebhooks: 32; -// guildInvites: 64; -// guildVoiceStates: 128; -// guildPresences: 256; -// guildMessages: 512; -// guildMessageReactions: 1024; -// guildMessageTyping: 2048; -// directMessages: 4096; -// directMessageReactions: 8192; -// directMessageTyping: 16384; -// allNonPrivileged: 32509; -// allPrivileged: 258; -// all: 32767; -// }; -// InteractionResponseTypes: { -// PONG: 1; -// CHANNEL_MESSAGE_WITH_SOURCE: 4; -// DEFERRED_CHANNEL_MESSAGE_WITH_SOURCE: 5; -// DEFERRED_UPDATE_MESSAGE: 6; -// UPDATE_MESSAGE: 7; -// APPLICATION_COMMAND_AUTOCOMPLETE_RESULT: 8; -// }; -// InteractionTypes: { -// PING: 1; -// APPLICATION_COMMAND: 2; -// MESSAGE_COMPONENT: 3; -// APPLICATION_COMMAND_AUTOCOMPLETE: 4; -// }; export enum InviteTargetTypes { STREAM = 1, EMBEDDED_APPLICATION, } -// MFALevels: { -// NONE: 0; -// ELEVATED: 1; -// }; -// MessageActivityFlags: { -// INSTANCE: 1; -// JOIN: 2; -// SPECTATE: 4; -// JOIN_REQUEST: 8; -// SYNC: 16; -// PLAY: 32; -// PARTY_PRIVACY_FRIENDS: 64; -// PARTY_PRIVACY_VOICE_CHANNEL: 128; -// EMBEDDED: 256; -// }; -// MessageActivityTypes: { -// JOIN: 1; -// SPECTATE: 2; -// LISTEN: 3; -// JOIN_REQUEST: 5; -// }; export const MessageFlags = { CROSSPOSTED: 1, IS_CROSSPOST: 2, @@ -1918,1935 +885,3 @@ export const MessageFlags = { EPHEMERAL: 64, LOADING: 128, } -// MessageTypes: { -// DEFAULT: 0; -// RECIPIENT_ADD: 1; -// RECIPIENT_REMOVE: 2; -// CALL: 3; -// CHANNEL_NAME_CHANGE: 4; -// CHANNEL_ICON_CHANGE: 5; -// CHANNEL_PINNED_MESSAGE: 6; -// GUILD_MEMBER_JOIN: 7; -// USER_PREMIUM_GUILD_SUBSCRIPTION: 8; -// USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_1: 9; -// USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_2: 10; -// USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_3: 11; -// CHANNEL_FOLLOW_ADD: 12; - -// GUILD_DISCOVERY_DISQUALIFIED: 14; -// GUILD_DISCOVERY_REQUALIFIED: 15; -// GUILD_DISCOVERY_GRACE_PERIOD_INITIAL_WARNING: 16; -// GUILD_DISCOVERY_GRACE_PERIOD_FINAL_WARNING: 17; -// THREAD_CREATED: 18; -// REPLY: 19; -// CHAT_INPUT_COMMAND: 20; -// THREAD_STARTER_MESSAGE: 21; -// GUILD_INVITE_REMINDER: 22; -// CONTEXT_MENU_COMMAND: 23; -// }; -// PermissionOverwriteTypes: { -// ROLE: 0; -// USER: 1; -// }; -// Permissions: { -// createInstantInvite: 1n; -// kickMembers: 2n; -// banMembers: 4n; -// administrator: 8n; -// manageChannels: 16n; -// manageGuild: 32n; -// addReactions: 64n; -// viewAuditLog: 128n; -// voicePrioritySpeaker: 256n; -// voiceStream: 512n; -// viewChannel: 1024n; -// sendMessages: 2048n; -// sendTTSMessages: 4096n; -// manageMessages: 8192n; -// embedLinks: 16384n; -// attachFiles: 32768n; -// readMessageHistory: 65536n; -// mentionEveryone: 131072n; -// useExternalEmojis: 262144n; -// viewGuildInsights: 524288n; -// voiceConnect: 1048576n; -// voiceSpeak: 2097152n; -// voiceMuteMembers: 4194304n; -// voiceDeafenMembers: 8388608n; -// voiceMoveMembers: 16777216n; -// voiceUseVAD: 33554432n; -// changeNickname: 67108864n; -// manageNicknames: 134217728n; -// manageRoles: 268435456n; -// manageWebhooks: 536870912n; -// manageEmojisAndStickers: 1073741824n; -// useApplicationCommands: 2147483648n; -// voiceRequestToSpeak: 4294967296n; -// manageEvents: 8589934592n; -// manageThreads: 17179869184n; -// createPublicThreads: 34359738368n; -// createPrivateThreads: 68719476736n; -// useExternalStickers: 137438953472n; -// sendMessagesInThreads: 274877906944n; -// startEmbeddedActivities: 549755813888n; -// moderateMembers: 1099511627776n; -// allGuild: 1110182461630n; -// allText: 535529258065n; -// allVoice: 554385278737n; -// all: 2199023255551n; -// }; -// PremiumTiers: { -// NONE: 0; -// TIER_1: 1; -// TIER_2: 2; -// TIER_3: 3; -// }; -// PremiumTypes: { -// NONE: 0; -// NITRO_CLASSIC: 1; -// NITRO: 2; -// }; -// StageInstancePrivacyLevel: { -// PUBLIC: 1; -// GUILD_ONLY: 2; -// }; -// StickerFormats: { -// PNG: 1; -// APNG: 2; -// LOTTIE: 3; -// }; -// StickerTypes: { -// STANDARD: 1; -// GUILD: 2; -// }; -// SystemChannelFlags: { -// SUPPRESS_JOIN_NOTIFICATIONS: 1; -// SUPPRESS_PREMIUM_SUBSCRIPTIONS: 2; -// SUPPRESS_GUILD_REMINDER_NOTIFICATIONS: 4; -// SUPPRESS_JOIN_NOTIFICATION_REPLIES: 8; -// }; -// SystemJoinMessages: [ -// "%user% joined the party.", -// "%user% is here.", -// "Welcome, %user%. We hope you brought pizza.", -// "A wild %user% appeared.", -// "%user% just landed.", -// "%user% just slid into the server.", -// "%user% just showed up!", -// "Welcome %user%. Say hi!", -// "%user% hopped into the server.", -// "Everyone welcome %user%!", -// "Glad you're here, %user%.", -// "Good to see you, %user%.", -// "Yay you made it, %user%!", -// ]; -// ThreadMemberFlags: { -// HAS_INTERACTED: 1; -// ALL_MESSAGES: 2; -// ONLY_MENTIONS: 4; -// NO_MESSAGES: 8; -// }; -// UserFlags: { -// NONE: 0; -// DISCORD_STAFF: 1; -// DISCORD_EMPLOYEE: 1; -// PARTNER: 2; -// PARTNERED_SERVER_OWNER: 2; -// HYPESQUAD: 4; -// HYPESQUAD_EVENTS: 4; -// BUG_HUNTER_LEVEL_1: 8; -// HYPESQUAD_ONLINE_HOUSE_1: 64; -// HOUSE_BRAVERY: 64; -// HYPESQUAD_ONLINE_HOUSE_2: 128; -// HOUSE_BRILLIANCE: 128; -// HYPESQUAD_ONLINE_HOUSE_3: 256; -// HOUSE_BALANCE: 256; -// PREMIUM_EARLY_SUPPORTER: 512; -// EARLY_SUPPORTER: 512; -// TEAM_PSEUDO_USER: 1024; -// TEAM_USER: 1024; -// SYSTEM: 4096; -// BUG_HUNTER_LEVEL_2: 16384; -// VERIFIED_BOT: 65536; -// VERIFIED_DEVELOPER: 131072; -// VERIFIED_BOT_DEVELOPER: 131072; -// EARLY_VERIFIED_BOT_DEVELOPER: 131072; -// CERTIFIED_MODERATOR: 262144; -// DISCORD_CERTIFIED_MODERATOR: 262144; -// BOT_HTTP_INTERACTIONS: 524288; -// }; -// VerificationLevels: { -// NONE: 0; -// LOW: 1; -// MEDIUM: 2; -// HIGH: 3; -// VERY_HIGH: 4; -// }; -// VideoQualityModes: { -// AUTO: 1; -// FULL: 2; -// }; -// VoiceOPCodes: { -// IDENTIFY: 0; -// SELECT_PROTOCOL: 1; -// READY: 2; -// HEARTBEAT: 3; -// SESSION_DESCRIPTION: 4; -// SPEAKING: 5; -// HEARTBEAT_ACK: 6; -// RESUME: 7; -// HELLO: 8; -// RESUMED: 9; -// CLIENT_DISCONNECT: 13; -// }; -// WebhookTypes: { -// INCOMING: 1; -// CHANNEL_FOLLOWER: 2; -// APPLICATION: 3; -// }; -// } - -// // Selfbot -// export interface Connection { -// friend_sync: boolean; -// id: string; -// integrations: unknown[]; // TODO ???? -// name: string; -// revoked: boolean; -// type: string; -// verified: boolean; -// visibility: ConnectionVisibilityTypes; -// } -// export interface GuildSettings { -// channel_override: { -// channel_id: string; -// message_notifications: number; -// muted: boolean; -// }[]; -// guild_id: string; -// message_notifications: number; -// mobile_push: boolean; -// muted: boolean; -// suppress_everyone: boolean; -// } -// export interface SearchOptions { -// attachmentExtensions?: string; -// attachmentFilename?: string; -// authorID?: string; -// channelIDs?: string[]; -// content?: string; -// contextSize?: number; -// embedProviders?: string; -// embedTypes?: string; -// has?: string; -// limit?: number; -// maxID?: string; -// minID?: string; -// offset?: number; -// sortBy?: string; -// sortOrder?: string; -// } -// export interface SearchResults { -// results: (Message & { hit?: boolean })[][]; -// totalResults: number; -// } -// export interface UserProfile { -// connected_accounts: { id: string; name: string; type: string; verified: boolean }[]; -// mutual_guilds: { id: string; nick?: string }[]; -// premium_since?: number; -// user: PartialUser & { flags: number }; -// } -// export interface UserSettings { -// afk_timeout: number; -// convert_emojis: boolean; -// default_guilds_restricted: boolean; -// detect_platform_accounts: boolean; -// developer_mode: boolean; -// enable_tts_command: boolean; -// explicit_content_filter: number; -// friend_source_flags: { -// all: boolean; // not sure about other keys, abal heeeelp -// }; -// inline_attachment_media: boolean; -// inline_embed_media: boolean; -// guild_positions: string[]; -// locale: string; -// message_display_compact: boolean; -// render_embeds: boolean; -// render_reactions: boolean; -// restricted_guilds: string[]; -// show_current_game: boolean; -// status: string; -// theme: string; -// } - -// class Base implements SimpleJSON { -// createdAt: number; -// id: string; -// constructor(id: string); -// static getCreatedAt(id: string): number; -// static getDiscordEpoch(id: string): number; -// inspect(): this; -// toString(): string; -// toJSON(props?: string[]): JSONCache; -// } - -// export class Bucket { -// interval: number; -// lastReset: number; -// lastSend: number; -// tokenLimit: number; -// tokens: number; -// constructor( -// tokenLimit: number, -// interval: number, -// options: { latencyRef: { latency: number }; reservedTokens: number }, -// ); -// check(): void; -// queue(func: () => void, priority?: boolean): void; -// } - -// export class BrowserWebSocket extends EventEmitter { -// static CONNECTING: 0; -// static OPEN: 1; -// static CLOSING: 2; -// static CLOSED: 3; -// readyState: number; -// constructor(url: string); -// close(code?: number, reason?: string): void; -// removeEventListener(event: string | symbol, listener: (...args: any[]) => void): this; -// // @ts-ignore: DOM -// send(data: string | ArrayBufferLike | Blob | ArrayBufferView): void; -// terminate(): void; -// } - -// export class BrowserWebSocketError extends Error { -// // @ts-ignore: DOM -// event: Event; -// // @ts-ignore: DOM -// constructor(message: string, event: Event); -// } - -// export class Call extends Base { -// channel: GroupChannel; -// createdAt: number; -// endedTimestamp: number | null; -// id: string; -// participants: string[]; -// region: string | null; -// ringing: string[]; -// unavailable: boolean; -// voiceStates: Collection; -// constructor(data: BaseData, channel: GroupChannel); -// } - -// export class CategoryChannel extends GuildChannel { -// channels: Collection>; -// type: Constants["ChannelTypes"]["GUILD_CATEGORY"]; -// edit(options: Omit, reason?: string): Promise; -// } - -// export class Channel extends Base { -// client: Client; -// createdAt: number; -// id: string; -// mention: string; -// type: ChannelTypes; -// constructor(data: BaseData, client: Client); -// static from(data: BaseData, client: Client): AnyChannel; -// } - -// export class Client extends EventEmitter { -// application?: { id: string; flags: number }; -// bot: boolean; -// channelGuildMap: { [s: string]: string }; -// gatewayURL?: string; -// // groupChannels: Collection; -// guilds: Collection; -// guildShardMap: { [s: string]: number }; -// lastConnect: number; -// lastReconnectDelay: number; -// // notes: { [s: string]: string }; -// options: ClientOptions; -// // presence: ClientPresence; -// privateChannelMap: { [s: string]: string }; -// privateChannels: Collection; -// ready: boolean; -// reconnectAttempts: number; -// // relationships: Collection; -// requestHandler: RequestHandler; -// shards: ShardManager; -// startTime: number; -// threadGuildMap: { [s: string]: string }; -// unavailableGuilds: Collection; -// uptime: number; -// user: ExtendedUser; -// // userGuildSettings: { [s: string]: GuildSettings }; -// users: Collection; -// // userSettings: UserSettings; -// voiceConnections: VoiceConnectionManager; -// constructor(token: string, options?: ClientOptions); -// acceptInvite(inviteID: string): Promise>; -// addGroupRecipient(groupID: string, userID: string): Promise; -// addGuildDiscoverySubcategory( -// guildID: string, -// categoryID: string, -// reason?: string, -// ): Promise; -// addGuildMemberRole(guildID: string, memberID: string, roleID: string, reason?: string): Promise; -// addMessageReaction(channelID: string, messageID: string, reaction: string): Promise; -// addRelationship(userID: string, block?: boolean): Promise; -// addSelfPremiumSubscription(token: string, plan: string): Promise; -// banGuildMember(guildID: string, userID: string, deleteMessageDays?: number, reason?: string): Promise; -// bulkEditCommandPermissions( -// guildID: string, -// permissions: { id: string; permissions: ApplicationCommandPermissions[] }[], -// ): Promise; -// bulkEditCommands(commands: ApplicationCommandStructure[]): Promise; -// bulkEditGuildCommands(guildID: string, commands: ApplicationCommandStructure[]): Promise; -// closeVoiceConnection(guildID: string): void; -// connect(): Promise; -// createChannel(guildID: string, name: string): Promise; -// createChannel( -// guildID: string, -// name: string, -// type: Constants["ChannelTypes"]["GUILD_TEXT"], -// options?: CreateChannelOptions, -// ): Promise; -// createChannel( -// guildID: string, -// name: string, -// type: Constants["ChannelTypes"]["GUILD_VOICE"], -// options?: CreateChannelOptions, -// ): Promise; -// createChannel( -// guildID: string, -// name: string, -// type: Constants["ChannelTypes"]["GUILD_CATEGORY"], -// options?: CreateChannelOptions, -// ): Promise; -// createChannel( -// guildID: string, -// name: string, -// type: Constants["ChannelTypes"]["GUILD_NEWS"], -// options?: CreateChannelOptions, -// ): Promise; -// createChannel( -// guildID: string, -// name: string, -// type: Constants["ChannelTypes"]["GUILD_STORE"], -// options?: CreateChannelOptions, -// ): Promise; -// createChannel( -// guildID: string, -// name: string, -// type: Constants["ChannelTypes"]["GUILD_STAGE"], -// options?: CreateChannelOptions, -// ): Promise; -// createChannel( -// guildID: string, -// name: string, -// export type?: number, -// options?: CreateChannelOptions, -// ): Promise; -// createChannelInvite( -// channelID: string, -// options?: CreateChannelInviteOptions, -// reason?: string, -// ): Promise>; -// createChannelWebhook( -// channelID: string, -// options: { name: string; avatar?: string | null }, -// reason?: string, -// ): Promise; -// createCommand(command: ApplicationCommandStructure): Promise; -// createGroupChannel(userIDs: string[]): Promise; -// createGuild(name: string, options?: CreateGuildOptions): Promise; -// createGuildCommand(guildID: string, command: ApplicationCommandStructure): Promise; -// createGuildEmoji(guildID: string, options: EmojiOptions, reason?: string): Promise; -// createGuildFromTemplate(code: string, name: string, icon?: string): Promise; -// createGuildSticker(guildID: string, options: CreateStickerOptions, reason?: string): Promise; -// createGuildTemplate(guildID: string, name: string, description?: string | null): Promise; -// createInteractionResponse( -// interactionID: string, -// interactionToken: string, -// options: InteractionResponse, -// file?: FileContent | FileContent[], -// ): Promise; -// createMessage(channelID: string, content: MessageContent, file?: FileContent | FileContent[]): Promise; -// createRole(guildID: string, options?: RoleOptions, reason?: string): Promise; -// createRole(guildID: string, options?: Role, reason?: string): Promise; -// createStageInstance(channelID: string, options: StageInstanceOptions): Promise; -// createThreadWithMessage( -// channelID: string, -// messageID: string, -// options: CreateThreadOptions, -// ): Promise; -// createThreadWithoutMessage( -// channelID: string, -// options: CreateThreadWithoutMessageOptions, -// ): Promise; -// crosspostMessage(channelID: string, messageID: string): Promise; -// deleteChannel(channelID: string, reason?: string): Promise; -// deleteChannelPermission(channelID: string, overwriteID: string, reason?: string): Promise; -// deleteCommand(commandID: string): Promise; -// deleteGuild(guildID: string): Promise; -// deleteGuildCommand(guildID: string, commandID: string): Promise; -// deleteGuildDiscoverySubcategory(guildID: string, categoryID: string, reason?: string): Promise; -// deleteGuildEmoji(guildID: string, emojiID: string, reason?: string): Promise; -// deleteGuildIntegration(guildID: string, integrationID: string): Promise; -// deleteGuildSticker(guildID: string, stickerID: string, reason?: string): Promise; -// deleteGuildTemplate(guildID: string, code: string): Promise; -// deleteInvite(inviteID: string, reason?: string): Promise; -// deleteMessage(channelID: string, messageID: string, reason?: string): Promise; -// deleteMessages(channelID: string, messageIDs: string[], reason?: string): Promise; -// deleteRole(guildID: string, roleID: string, reason?: string): Promise; -// deleteSelfConnection(platform: string, id: string): Promise; -// deleteSelfPremiumSubscription(): Promise; -// deleteStageInstance(channelID: string): Promise; -// deleteUserNote(userID: string): Promise; -// deleteWebhook(webhookID: string, token?: string, reason?: string): Promise; -// deleteWebhookMessage(webhookID: string, token: string, messageID: string): Promise; -// disableSelfMFATOTP(code: string): Promise<{ token: string }>; -// disconnect(options: { reconnect?: boolean | "auto" }): void; -// editAFK(afk: boolean): void; -// editChannel( -// channelID: string, -// options: EditChannelOptions, -// reason?: string, -// ): Promise; -// editChannelPermission( -// channelID: string, -// overwriteID: string, -// allow: bigint | number, -// deny: bigint | number, -// type: PermissionType, -// reason?: string, -// ): Promise; -// editChannelPosition(channelID: string, position: number, options?: EditChannelPositionOptions): Promise; -// editChannelPositions(guildID: string, channelPositions: ChannelPosition[]): Promise; -// editCommand(commandID: string, command: ApplicationCommandStructure): Promise; -// editCommandPermissions( -// guildID: string, -// commandID: string, -// permissions: ApplicationCommandPermissions[], -// ): Promise; -// editGuild(guildID: string, options: GuildOptions, reason?: string): Promise; -// editGuildCommand( -// guildID: string, -// commandID: string, -// command: ApplicationCommandStructure, -// ): Promise; -// editGuildDiscovery(guildID: string, options?: DiscoveryOptions): Promise; -// editGuildEmoji( -// guildID: string, -// emojiID: string, -// options: { name?: string; roles?: string[] }, -// reason?: string, -// ): Promise; -// editGuildIntegration(guildID: string, integrationID: string, options: IntegrationOptions): Promise; -// editGuildMember(guildID: string, memberID: string, options: MemberOptions, reason?: string): Promise; -// editGuildSticker(guildID: string, stickerID: string, options?: EditStickerOptions, reason?: string): Promise; -// editGuildTemplate(guildID: string, code: string, options: GuildTemplateOptions): Promise; -// editGuildVanity(guildID: string, code: string | null): Promise; -// editGuildVoiceState(guildID: string, options: VoiceStateOptions, userID?: string): Promise; -// editGuildWelcomeScreen(guildID: string, options: WelcomeScreenOptions): Promise; -// editGuildWidget(guildID: string, options: Widget): Promise; -// editMessage(channelID: string, messageID: string, content: MessageContentEdit): Promise; -// editRole(guildID: string, roleID: string, options: RoleOptions, reason?: string): Promise; // TODO not all options are available? -// editRolePosition(guildID: string, roleID: string, position: number): Promise; -// editSelf(options: { avatar?: string; username?: string }): Promise; -// editSelfConnection( -// platform: string, -// id: string, -// data: { friendSync: boolean; visibility: number }, -// ): Promise; -// editSelfSettings(data: UserSettings): Promise; -// editStageInstance(channelID: string, options: StageInstanceOptions): Promise; -// editStatus( -// status: SelfStatus, -// activities?: ActivityPartial[] | ActivityPartial, -// ): void; -// editStatus(activities?: ActivityPartial[] | ActivityPartial): void; -// editUserNote(userID: string, note: string): Promise; -// editWebhook( -// webhookID: string, -// options: WebhookOptions, -// token?: string, -// reason?: string, -// ): Promise; -// editWebhookMessage( -// webhookID: string, -// token: string, -// messageID: string, -// options: MessageWebhookContent, -// ): Promise>; -// emit(event: K, ...args: ClientEvents[K]): boolean; -// emit(event: string, ...args: any[]): boolean; -// enableSelfMFATOTP( -// secret: string, -// code: string, -// ): Promise<{ backup_codes: { code: string; consumed: boolean }[]; token: string }>; -// executeSlackWebhook( -// webhookID: string, -// token: string, -// options: Record & { auth?: boolean; threadID?: string }, -// ): Promise; -// executeSlackWebhook( -// webhookID: string, -// token: string, -// options: Record & { auth?: boolean; threadID?: string; wait: true }, -// ): Promise>; -// executeWebhook( -// webhookID: string, -// token: string, -// options: WebhookPayload & { wait: true }, -// ): Promise>; -// executeWebhook(webhookID: string, token: string, options: WebhookPayload): Promise; -// followChannel(channelID: string, webhookChannelID: string): Promise; -// getActiveGuildThreads(guildID: string): Promise; -// getArchivedThreads( -// channelID: string, -// type: "private", -// options?: GetArchivedThreadsOptions, -// ): Promise>; -// getArchivedThreads( -// channelID: string, -// type: "public", -// options?: GetArchivedThreadsOptions, -// ): Promise>; -// getBotGateway(): Promise< -// { -// session_start_limit: { max_concurrency: number; remaining: number; reset_after: number; total: number }; -// shards: number; -// url: string; -// } -// >; -// getChannel(channelID: string): AnyChannel; -// getChannelInvites(channelID: string): Promise; -// getChannelWebhooks(channelID: string): Promise; -// getCommand(commandID: string): Promise; -// getCommandPermissions(guildID: string, commandID: string): Promise; -// getCommands(): Promise; -// getDiscoveryCategories(): Promise; -// getDMChannel(userID: string): Promise; -// getEmojiGuild(emojiID: string): Promise; -// getGateway(): Promise<{ url: string }>; -// getGuildAuditLog(guildID: string, options?: GetGuildAuditLogOptions): Promise; -// getGuildBan(guildID: string, userID: string): Promise; -// getGuildBans(guildID: string, options?: GetGuildBansOptions): Promise; -// getGuildCommand(guildID: string, commandID: string): Promise; -// getGuildCommandPermissions(guildID: string): Promise; -// getGuildCommands(guildID: string): Promise; -// getGuildDiscovery(guildID: string): Promise; -// getGuildIntegrations(guildID: string): Promise; -// getGuildInvites(guildID: string): Promise; -// getGuildPreview(guildID: string): Promise; -// getGuildTemplate(code: string): Promise; -// getGuildTemplates(guildID: string): Promise; -// getGuildVanity(guildID: string): Promise; -// getGuildWebhooks(guildID: string): Promise; -// getGuildWelcomeScreen(guildID: string): Promise; -// getGuildWidget(guildID: string): Promise; -// getGuildWidgetSettings(guildID: string): Promise; -// getInvite(inviteID: string, withCounts?: false): Promise>; -// getInvite(inviteID: string, withCounts: true): Promise>; -// getJoinedPrivateArchivedThreads( -// channelID: string, -// options?: GetArchivedThreadsOptions, -// ): Promise>; -// getMessage(channelID: string, messageID: string): Promise; -// getMessageReaction( -// channelID: string, -// messageID: string, -// reaction: string, -// options?: GetMessageReactionOptions, -// ): Promise; -// getMessages(channelID: string, options?: GetMessagesOptions): Promise; -// getNitroStickerPacks(): Promise<{ sticker_packs: StickerPack[] }>; -// getOAuthApplication(appID?: string): Promise; -// getPins(channelID: string): Promise; -// getPruneCount(guildID: string, options?: GetPruneOptions): Promise; -// getRESTChannel(channelID: string): Promise; -// getRESTGuild(guildID: string, withCounts?: boolean): Promise; -// getRESTGuildChannels(guildID: string): Promise; -// getRESTGuildEmoji(guildID: string, emojiID: string): Promise; -// getRESTGuildEmojis(guildID: string): Promise; -// getRESTGuildMember(guildID: string, memberID: string): Promise; -// getRESTGuildMembers(guildID: string, options?: GetRESTGuildMembersOptions): Promise; -// getRESTGuildRoles(guildID: string): Promise; -// getRESTGuilds(options?: GetRESTGuildsOptions): Promise; -// getRESTGuildSticker(guildID: string, stickerID: string): Promise; -// getRESTGuildStickers(guildID: string): Promise; -// getRESTSticker(stickerID: string): Promise; -// getRESTUser(userID: string): Promise; -// getSelf(): Promise; -// getSelfBilling(): Promise<{ -// payment_gateway?: string; -// payment_source?: { -// brand: string; -// expires_month: number; -// expires_year: number; -// invalid: boolean; -// last_4: number; -// type: string; -// }; -// premium_subscription?: { -// canceled_at?: string; -// created_at: string; -// current_period_end?: string; -// current_period_start?: string; -// ended_at?: string; -// plan: string; -// status: number; -// }; -// }>; -// getSelfConnections(): Promise; -// getSelfMFACodes( -// password: string, -// regenerate?: boolean, -// ): Promise<{ backup_codes: { code: string; consumed: boolean }[] }>; -// getSelfPayments(): Promise<{ -// amount: number; -// amount_refunded: number; -// created_at: string; // date -// currency: string; -// description: string; -// status: number; -// }[]>; -// getSelfSettings(): Promise; -// getStageInstance(channelID: string): Promise; -// getThreadMembers(channelID: string): Promise; -// getUserProfile(userID: string): Promise; -// getVoiceRegions(guildID?: string): Promise; -// getWebhook(webhookID: string, token?: string): Promise; -// getWebhookMessage(webhookID: string, token: string, messageID: string): Promise>; -// joinThread(channelID: string, userID?: string): Promise; -// joinVoiceChannel(channelID: string, options?: JoinVoiceChannelOptions): Promise; -// kickGuildMember(guildID: string, userID: string, reason?: string): Promise; -// leaveGuild(guildID: string): Promise; -// leaveThread(channelID: string, userID?: string): Promise; -// leaveVoiceChannel(channelID: string): void; -// off(event: K, listener: (...args: ClientEvents[K]) => void): this; -// off(event: string, listener: (...args: any[]) => void): this; -// once(event: K, listener: (...args: ClientEvents[K]) => void): this; -// once(event: string, listener: (...args: any[]) => void): this; -// pinMessage(channelID: string, messageID: string): Promise; -// pruneMembers(guildID: string, options?: PruneMemberOptions): Promise; -// purgeChannel(channelID: string, options: PurgeChannelOptions): Promise; -// removeGroupRecipient(groupID: string, userID: string): Promise; -// removeGuildMemberRole(guildID: string, memberID: string, roleID: string, reason?: string): Promise; -// removeMessageReaction(channelID: string, messageID: string, reaction: string, userID?: string): Promise; -// removeMessageReactionEmoji(channelID: string, messageID: string, reaction: string): Promise; -// removeMessageReactions(channelID: string, messageID: string): Promise; -// removeRelationship(userID: string): Promise; -// searchChannelMessages(channelID: string, query: SearchOptions): Promise; -// searchGuildMembers(guildID: string, query: string, limit?: number): Promise; -// searchGuildMessages(guildID: string, query: SearchOptions): Promise; -// sendChannelTyping(channelID: string): Promise; -// syncGuildIntegration(guildID: string, integrationID: string): Promise; -// syncGuildTemplate(guildID: string, code: string): Promise; -// unbanGuildMember(guildID: string, userID: string, reason?: string): Promise; -// unpinMessage(channelID: string, messageID: string): Promise; -// validateDiscoverySearchTerm(term: string): Promise<{ valid: boolean }>; -// on(event: K, listener: (...args: ClientEvents[K]) => void): this; -// on(event: string, listener: (...args: any[]) => void): this; -// toString(): string; -// } - -// export class ErisCollection extends Map { -// baseObject: new (...args: any[]) => T; -// limit?: number; -// constructor(baseObject: new (...args: any[]) => T, limit?: number); -// add(obj: T, extra?: unknown, replace?: boolean): T; -// every(func: (i: T) => boolean): boolean; -// filter(func: (i: T) => boolean): T[]; -// find(func: (i: T) => boolean): T | undefined; -// map(func: (i: T) => R): R[]; -// random(): T | undefined; -// reduce(func: (accumulator: U, val: T) => U, initialValue?: U): U; -// remove(obj: T | Uncached): T | null; -// some(func: (i: T) => boolean): boolean; -// update(obj: T, extra?: unknown, replace?: boolean): T; -// } - -// export class Command implements CommandOptions, SimpleJSON { -// aliases: string[]; -// argsRequired: boolean; -// caseInsensitive: boolean; -// cooldown: number; -// cooldownExclusions: CommandCooldownExclusions; -// cooldownMessage: MessageContent | false | GenericCheckFunction; -// cooldownReturns: number; -// defaultSubcommandOptions: CommandOptions; -// deleteCommand: boolean; -// description: string; -// dmOnly: boolean; -// errorMessage: MessageContent | GenericCheckFunction; -// fullDescription: string; -// fullLabel: string; -// guildOnly: boolean; -// hidden: boolean; -// hooks: Hooks; -// invalidUsageMessage: MessageContent | false | GenericCheckFunction; -// label: string; -// parentCommand?: Command; -// permissionMessage: MessageContent | false | GenericCheckFunction; -// reactionButtons: null | CommandReactionButtons[]; -// reactionButtonTimeout: number; -// requirements: CommandRequirements; -// restartCooldown: boolean; -// subcommandAliases: { [alias: string]: string }; -// subcommands: { [s: string]: Command }; -// usage: string; -// constructor(label: string, generate: CommandGenerator, options?: CommandOptions); -// cooldownCheck(msg: Message): boolean; -// cooldownExclusionCheck(msg: Message): boolean; -// executeCommand(msg: Message, args: string[]): Promise; -// permissionCheck(msg: Message): Promise; -// process(args: string[], msg: Message): Promise; -// registerSubcommand(label: string, generator: CommandGenerator, options?: CommandOptions): Command; -// registerSubcommandAlias(alias: string, label: string): void; -// unregisterSubcommand(label: string): void; -// toString(): string; -// toJSON(props?: string[]): JSONCache; -// } - -// export class CommandClient extends Client { -// activeMessages: { [s: string]: ActiveMessages }; -// commandAliases: { [s: string]: string }; -// commandOptions: CommandClientOptions; -// commands: { [s: string]: Command }; -// guildPrefixes: { [s: string]: string | string[] }; -// preReady?: true; -// constructor(token: string, options: ClientOptions, commandOptions?: CommandClientOptions); -// checkPrefix(msg: Message): string; -// onMessageCreate(msg: Message): Promise; -// onMessageReactionEvent(msg: Message, emoji: Emoji, reactor: Member | Uncached | string): Promise; -// registerCommand(label: string, generator: CommandGenerator, options?: CommandOptions): Command; -// registerCommandAlias(alias: string, label: string): void; -// registerGuildPrefix(guildID: string, prefix: string[] | string): void; -// resolveCommand(label: string): Command; -// unregisterCommand(label: string): void; -// unwatchMessage(id: string, channelID: string): void; -// toString(): string; -// } - -// export class DiscordHTTPError extends Error { -// code: number; -// headers: IncomingHttpHeaders; -// name: "DiscordHTTPError"; -// req: ClientRequest; -// res: IncomingMessage; -// response: HTTPResponse; -// constructor(req: ClientRequest, res: IncomingMessage, response: HTTPResponse, stack: string); -// flattenErrors(errors: HTTPResponse, keyPrefix?: string): string[]; -// } - -// export class DiscordRESTError extends Error { -// code: number; -// headers: IncomingHttpHeaders; -// name: string; -// req: ClientRequest; -// res: IncomingMessage; -// response: HTTPResponse; -// constructor(req: ClientRequest, res: IncomingMessage, response: HTTPResponse, stack: string); -// flattenErrors(errors: HTTPResponse, keyPrefix?: string): string[]; -// } - -// export class ExtendedUser extends User { -// email: string; -// mfaEnabled: boolean; -// premiumType: PremiumTypes; -// verified: boolean; -// } - -// export class GroupChannel extends PrivateChannel { -// icon: string | null; -// iconURL: string | null; -// name: string; -// ownerID: string; -// recipients: Collection; -// type: Constants["ChannelTypes"]["GROUP_DM"]; -// addRecipient(userID: string): Promise; -// dynamicIconURL(format?: ImageFormat, size?: number): string | null; -// edit(options: { icon?: string; name?: string; ownerID?: string }): Promise; -// removeRecipient(userID: string): Promise; -// } - -// export class Guild extends Base { -// afkChannelID: string | null; -// afkTimeout: number; -// applicationID: string | null; -// approximateMemberCount?: number; -// approximatePresenceCount?: number; -// autoRemoved?: boolean; -// banner: string | null; -// bannerURL: string | null; -// channels: Collection; -// createdAt: number; -// defaultNotifications: DefaultNotifications; -// description: string | null; -// discoverySplash: string | null; -// discoverySplashURL: string | null; -// emojiCount?: number; -// emojis: Emoji[]; -// explicitContentFilter: ExplicitContentFilter; -// features: GuildFeatures[]; -// icon: string | null; -// iconURL: string | null; -// id: string; -// joinedAt: number; -// large: boolean; -// maxMembers: number; -// maxPresences?: number | null; -// maxVideoChannelUsers?: number; -// memberCount: number; -// members: Collection; -// mfaLevel: MFALevel; -// name: string; -// nsfwLevel: NSFWLevel; -// ownerID: string; -// preferredLocale: string; -// premiumProgressBarEnabled: boolean; -// premiumSubscriptionCount?: number; -// premiumTier: PremiumTier; -// primaryCategory?: DiscoveryCategory; -// primaryCategoryID?: number; -// publicUpdatesChannelID: string; -// roles: Collection; -// rulesChannelID: string | null; -// shard: Shard; -// splash: string | null; -// splashURL: string | null; -// stageInstances: Collection; -// stickers?: Sticker[]; -// systemChannelFlags: number; -// systemChannelID: string | null; -// threads: Collection; -// unavailable: boolean; -// vanityURL: string | null; -// verificationLevel: VerificationLevel; -// voiceStates: Collection; -// welcomeScreen?: WelcomeScreen; -// widgetChannelID?: string | null; -// widgetEnabled?: boolean | null; -// constructor(data: BaseData, client: Client); -// addDiscoverySubcategory(categoryID: string, reason?: string): Promise; -// addMemberRole(memberID: string, roleID: string, reason?: string): Promise; -// banMember(userID: string, deleteMessageDays?: number, reason?: string): Promise; -// bulkEditCommands(commands: ApplicationCommandStructure[]): Promise; -// createChannel(name: string): Promise; -// createChannel( -// name: string, -// type: Constants["ChannelTypes"]["GUILD_TEXT"], -// options?: CreateChannelOptions, -// ): Promise; -// createChannel( -// name: string, -// type: Constants["ChannelTypes"]["GUILD_VOICE"], -// options?: CreateChannelOptions, -// ): Promise; -// createChannel( -// name: string, -// type: Constants["ChannelTypes"]["GUILD_CATEGORY"], -// options?: CreateChannelOptions, -// ): Promise; -// createChannel( -// name: string, -// type: Constants["ChannelTypes"]["GUILD_NEWS"], -// options?: CreateChannelOptions | string, -// ): Promise; -// createChannel( -// name: string, -// type: Constants["ChannelTypes"]["GUILD_STORE"], -// options?: CreateChannelOptions | string, -// ): Promise; -// createChannel( -// name: string, -// type: Constants["ChannelTypes"]["GUILD_STAGE"], -// options?: CreateChannelOptions | string, -// ): Promise; -// createChannel(name: string, export type?: number, options?: CreateChannelOptions): Promise; -// createCommand(command: ApplicationCommandStructure): Promise; -// createEmoji(options: { image: string; name: string; roles?: string[] }, reason?: string): Promise; -// createRole(options: RoleOptions, reason?: string): Promise; -// createRole(options: Role, reason?: string): Promise; -// createSticker(options: CreateStickerOptions, reason?: string): Promise; -// createTemplate(name: string, description?: string | null): Promise; -// delete(): Promise; -// deleteCommand(commandID: string): Promise; -// deleteDiscoverySubcategory(categoryID: string, reason?: string): Promise; -// deleteEmoji(emojiID: string, reason?: string): Promise; -// deleteIntegration(integrationID: string): Promise; -// deleteRole(roleID: string): Promise; -// deleteSticker(stickerID: string, reason?: string): Promise; -// deleteTemplate(code: string): Promise; -// dynamicBannerURL(format?: ImageFormat, size?: number): string | null; -// dynamicDiscoverySplashURL(format?: ImageFormat, size?: number): string | null; -// dynamicIconURL(format?: ImageFormat, size?: number): string | null; -// dynamicSplashURL(format?: ImageFormat, size?: number): string | null; -// edit(options: GuildOptions, reason?: string): Promise; -// editChannelPositions(channelPositions: ChannelPosition[]): Promise; -// editCommand(commandID: string, command: ApplicationCommandStructure): Promise; -// editCommandPermissions(permissions: ApplicationCommandPermissions[]): Promise; -// editDiscovery(options?: DiscoveryOptions): Promise; -// editEmoji(emojiID: string, options: { name: string; roles?: string[] }, reason?: string): Promise; -// editIntegration(integrationID: string, options: IntegrationOptions): Promise; -// editMember(memberID: string, options: MemberOptions, reason?: string): Promise; -// editRole(roleID: string, options: RoleOptions): Promise; -// editSticker(stickerID: string, options?: EditStickerOptions, reason?: string): Promise; -// editTemplate(code: string, options: GuildTemplateOptions): Promise; -// editVanity(code: string | null): Promise; -// editVoiceState(options: VoiceStateOptions, userID?: string): Promise; -// editWelcomeScreen(options: WelcomeScreenOptions): Promise; -// editWidget(options: Widget): Promise; -// fetchAllMembers(timeout?: number): Promise; -// fetchMembers(options?: FetchMembersOptions): Promise; -// getActiveThreads(): Promise; -// getAuditLog(options?: GetGuildAuditLogOptions): Promise; -// getBan(userID: string): Promise; -// getBans(options?: GetGuildBansOptions): Promise; -// getCommand(commandID: string): Promise; -// getCommandPermissions(): Promise; -// getCommands(): Promise; -// getDiscovery(): Promise; -// getIntegrations(): Promise; -// getInvites(): Promise; -// getPruneCount(options?: GetPruneOptions): Promise; -// getRESTChannels(): Promise; -// getRESTEmoji(emojiID: string): Promise; -// getRESTEmojis(): Promise; -// getRESTMember(memberID: string): Promise; -// getRESTMembers(options?: GetRESTGuildMembersOptions): Promise; -// getRESTRoles(): Promise; -// getRESTSticker(stickerID: string): Promise; -// getRESTStickers(): Promise; -// getTemplates(): Promise; -// getVanity(): Promise; -// getVoiceRegions(): Promise; -// getWebhooks(): Promise; -// getWelcomeScreen(): Promise; -// getWidget(): Promise; -// getWidgetSettings(): Promise; -// kickMember(userID: string, reason?: string): Promise; -// leave(): Promise; -// leaveVoiceChannel(): void; -// permissionsOf(memberID: string | Member | MemberRoles): Permission; -// pruneMembers(options?: PruneMemberOptions): Promise; -// removeMemberRole(memberID: string, roleID: string, reason?: string): Promise; -// searchMembers(query: string, limit?: number): Promise; -// syncIntegration(integrationID: string): Promise; -// syncTemplate(code: string): Promise; -// unbanMember(userID: string, reason?: string): Promise; -// } - -// export class GuildAuditLogEntry extends Base { -// actionType: number; -// after: { [key: string]: unknown } | null; -// before: { [key: string]: unknown } | null; -// channel?: AnyGuildChannel; -// count?: number; -// deleteMemberDays?: number; -// guild: Guild; -// id: string; -// member?: Member | Uncached; -// membersRemoved?: number; -// message?: Message; -// reason: string | null; -// role?: Role | { id: string; name: string }; -// target?: Guild | AnyGuildChannel | Member | Role | Invite | Emoji | Sticker | Message | null; -// targetID: string; -// user: User; -// constructor(data: BaseData, guild: Guild); -// } - -// export class GuildChannel extends Channel { -// guild: Guild; -// name: string; -// nsfw: boolean; -// parentID: string | null; -// permissionOverwrites: Collection; -// position: number; -// type: GuildChannelTypes; -// constructor(data: BaseData, client: Client); -// delete(reason?: string): Promise; -// deletePermission(overwriteID: string, reason?: string): Promise; -// edit(options: Omit, reason?: string): Promise; -// editPermission( -// overwriteID: string, -// allow: bigint | number, -// deny: bigint | number, -// type: PermissionType, -// reason?: string, -// ): Promise; -// editPosition(position: number, options?: EditChannelPositionOptions): Promise; -// getInvites(): Promise; -// permissionsOf(memberID: string | Member | MemberRoles): Permission; -// } - -// export class GuildIntegration extends Base { -// account: { id: string; name: string }; -// application?: IntegrationApplication; -// createdAt: number; -// enabled: boolean; -// enableEmoticons?: boolean; -// expireBehavior?: GuildIntegrationExpireBehavior; -// expireGracePeriod?: number; -// id: string; -// name: string; -// revoked?: boolean; -// roleID?: string; -// subscriberCount?: number; -// syncedAt?: number; -// syncing?: boolean; -// type: GuildIntegrationTypes; -// user?: User; -// constructor(data: BaseData, guild: Guild); -// delete(): Promise; -// edit(options: IntegrationOptions): Promise; -// sync(): Promise; -// } - -// export class GuildPreview extends Base { -// approximateMemberCount: number; -// approximatePresenceCount: number; -// description: string | null; -// discoverySplash: string | null; -// discoverySplashURL: string | null; -// emojis: Emoji[]; -// features: GuildFeatures[]; -// icon: string | null; -// iconURL: string | null; -// id: string; -// name: string; -// splash: string | null; -// splashURL: string | null; -// constructor(data: BaseData, client: Client); -// dynamicDiscoverySplashURL(format?: ImageFormat, size?: number): string | null; -// dynamicIconURL(format?: ImageFormat, size?: number): string | null; -// dynamicSplashURL(format?: ImageFormat, size?: number): string | null; -// } - -// export class GuildTemplate { -// code: string; -// createdAt: number; -// creator: User; -// description: string | null; -// isDirty: string | null; -// name: string; -// serializedSourceGuild: Guild; -// sourceGuild: Guild | Uncached; -// updatedAt: number; -// usageCount: number; -// constructor(data: BaseData, client: Client); -// createGuild(name: string, icon?: string): Promise; -// delete(): Promise; -// edit(options: GuildTemplateOptions): Promise; -// sync(): Promise; -// toJSON(props?: string[]): JSONCache; -// } - -// export class TextVoiceChannel extends VoiceChannel implements GuildTextable { -// lastMessageID: string; -// messages: Collection>; -// rateLimitPerUser: number; -// addMessageReaction(messageID: string, reaction: string): Promise; -// createMessage(content: MessageContent, file?: FileContent | FileContent[]): Promise>; -// createWebhook(options: { name: string; avatar?: string | null }, reason?: string): Promise; -// deleteMessage(messageID: string, reason?: string): Promise; -// deleteMessages(messageIDs: string[], reason?: string): Promise; -// editMessage(messageID: string, content: MessageContentEdit): Promise>; -// getMessage(messageID: string): Promise>; -// getMessageReaction(messageID: string, reaction: string, options?: GetMessageReactionOptions): Promise; -// getMessages(options?: GetMessagesOptions): Promise[]>; -// getWebhooks(): Promise; -// purge(options: PurgeChannelOptions): Promise; -// removeMessageReaction(messageID: string, reaction: string, userID?: string): Promise; -// removeMessageReactionEmoji(messageID: string, reaction: string): Promise; -// removeMessageReactions(messageID: string): Promise; -// sendTyping(): Promise; -// unsendMessage(messageID: string): Promise; -// } -// export class Interaction extends Base { -// acknowledged: boolean; -// applicationID: string; -// id: string; -// token: string; -// type: number; -// version: number; -// static from(data: BaseData): AnyInteraction; -// } - -// export class PingInteraction extends Interaction { -// type: Constants["InteractionTypes"]["PING"]; -// acknowledge(): Promise; -// pong(): Promise; -// } - -// export class CommandInteraction extends Interaction { -// channel: T; -// data: { -// id: string; -// name: string; -// type: ApplicationCommandTypes; -// target_id?: string; -// resolved?: { -// users?: Collection; -// members?: Collection>; -// roles?: Collection; -// channels?: Collection; -// messages?: Collection; -// }; -// options?: InteractionDataOptions[]; -// }; -// guildID?: string; -// member?: Member; -// type: Constants["InteractionTypes"]["APPLICATION_COMMAND"]; -// user?: User; -// acknowledge(flags?: number): Promise; -// createFollowup(content: string | InteractionContent, file?: FileContent | FileContent[]): Promise; -// createMessage(content: string | InteractionContent, file?: FileContent | FileContent[]): Promise; -// defer(flags?: number): Promise; -// deleteMessage(messageID: string): Promise; -// deleteOriginalMessage(): Promise; -// editMessage( -// messageID: string, -// content: string | InteractionContentEdit, -// file?: FileContent | FileContent[], -// ): Promise; -// editOriginalMessage(content: string | InteractionContentEdit, file?: FileContent | FileContent[]): Promise; -// getOriginalMessage(): Promise; -// } - -// export interface ComponentInteractionButtonData { -// component_type: Constants["ComponentTypes"]["BUTTON"]; -// custom_id: string; -// } - -// export interface ComponentInteractionSelectMenuData { -// component_type: Constants["ComponentTypes"]["SELECT_MENU"]; -// custom_id: string; -// values: string[]; -// } - -// export class ComponentInteraction extends Interaction { -// channel: T; -// data: ComponentInteractionButtonData | ComponentInteractionSelectMenuData; -// guildID?: string; -// member?: Member; -// message: Message; -// type: Constants["InteractionTypes"]["MESSAGE_COMPONENT"]; -// user?: User; -// acknowledge(): Promise; -// createFollowup(content: string | InteractionContent, file?: FileContent | FileContent[]): Promise; -// createMessage(content: string | InteractionContent, file?: FileContent | FileContent[]): Promise; -// defer(flags?: number): Promise; -// deferUpdate(): Promise; -// deleteMessage(messageID: string): Promise; -// deleteOriginalMessage(): Promise; -// editMessage( -// messageID: string, -// content: string | InteractionContentEdit, -// file?: FileContent | FileContent[], -// ): Promise; -// editOriginalMessage(content: string | InteractionContentEdit, file?: FileContent | FileContent[]): Promise; -// editParent(content: InteractionContentEdit, file?: FileContent | FileContent[]): Promise; -// getOriginalMessage(): Promise; -// } -// export class AutocompleteInteraction extends Interaction { -// channel: T; -// data: { -// id: string; -// name: string; -// type: Constants["ApplicationCommandTypes"]["CHAT_INPUT"]; -// target_id?: string; -// options: InteractionDataOptions[]; -// }; -// guildID?: string; -// member?: Member; -// type: Constants["InteractionTypes"]["APPLICATION_COMMAND_AUTOCOMPLETE"]; -// user?: User; -// acknowledge(choices: ApplicationCommandOptionChoice[]): Promise; -// result(choices: ApplicationCommandOptionChoice[]): Promise; -// } -// export class UnknownInteraction extends Interaction { -// channel?: T; -// data?: unknown; -// guildID?: string; -// member?: Member; -// message?: Message; -// type: number; -// user?: User; -// acknowledge(data: InteractionResponse): Promise; -// createFollowup(content: string | InteractionContent, file?: FileContent | FileContent[]): Promise; -// createMessage(content: string | InteractionContent, file?: FileContent | FileContent[]): Promise; -// defer(flags?: number): Promise; -// deferUpdate(): Promise; -// deleteMessage(messageID: string): Promise; -// deleteOriginalMessage(): Promise; -// editMessage( -// messageID: string, -// content: string | InteractionContentEdit, -// file?: FileContent | FileContent[], -// ): Promise; -// editOriginalMessage(content: string | InteractionContentEdit, file?: FileContent | FileContent[]): Promise; -// editParent(content: InteractionContentEdit, file?: FileContent | FileContent[]): Promise; -// getOriginalMessage(): Promise; -// pong(): Promise; -// result(choices: ApplicationCommandOptionChoice[]): Promise; -// } - -// // If CT (count) is "withMetadata", it will not have count properties -// export class Invite< -// CT extends "withMetadata" | "withCount" | "withoutCount" = "withMetadata", -// CH extends InviteChannel = InviteChannel, -// > extends Base { -// channel: CH; -// code: string; -// // @ts-ignore: Property is only not null when invite metadata is supplied -// createdAt: CT extends "withMetadata" ? number : null; -// guild: CT extends "withMetadata" ? Guild // Invite with Metadata always has guild prop -// : CH extends Extract // Invite without Metadata -// ? never // If the channel is GroupChannel, there is no guild -// : CH extends Exclude // Invite without Metadata and not GroupChanel -// ? Guild // If the invite channel is not partial -// : Guild | undefined; // If the invite channel is partial -// inviter?: User; -// maxAge: CT extends "withMetadata" ? number : null; -// maxUses: CT extends "withMetadata" ? number : null; -// memberCount: CT extends "withMetadata" | "withoutCount" ? null : number; -// presenceCount: CT extends "withMetadata" | "withoutCount" ? null : number; -// stageInstance: CH extends StageChannel ? InviteStageInstance : null; -// temporary: CT extends "withMetadata" ? boolean : null; -// uses: CT extends "withMetadata" ? number : null; -// constructor(data: BaseData, client: Client); -// delete(reason?: string): Promise; -// } - -// export class Member extends Base implements Presence { -// accentColor?: number | null; -// activities?: Activity[]; -// avatar: string | null; -// avatarURL: string; -// banner?: string | null; -// bannerURL: string | null; -// bot: boolean; -// clientStatus?: ClientStatus; -// communicationDisabledUntil: number | null; -// createdAt: number; -// defaultAvatar: string; -// defaultAvatarURL: string; -// discriminator: string; -// game: Activity | null; -// guild: Guild; -// id: string; -// joinedAt: number | null; -// mention: string; -// nick: string | null; -// pending?: boolean; -// permissions: Permission; -// premiumSince?: number | null; -// roles: string[]; -// staticAvatarURL: string; -// status?: Status; -// user: User; -// username: string; -// voiceState: VoiceState; -// constructor(data: BaseData, guild?: Guild, client?: Client); -// addRole(roleID: string, reason?: string): Promise; -// ban(deleteMessageDays?: number, reason?: string): Promise; -// edit(options: MemberOptions, reason?: string): Promise; -// kick(reason?: string): Promise; -// removeRole(roleID: string, reason?: string): Promise; -// unban(reason?: string): Promise; -// } - -// export class Message extends Base { -// activity?: MessageActivity; -// application?: MessageApplication; -// applicationID?: string; -// attachments: Attachment[]; -// author: User; -// channel: T; -// channelMentions: string[]; -// command?: Command; -// components?: ActionRow[]; -// content: string; -// createdAt: number; -// editedTimestamp?: number; -// embeds: Embed[]; -// flags: number; -// guildID: T extends GuildTextableWithThread ? string : undefined; -// id: string; -// interaction: MessageInteraction | null; -// jumpLink: string; -// member: T extends GuildTextableWithThread ? Member : null; -// mentionEveryone: boolean; -// mentions: User[]; -// messageReference: MessageReference | null; -// pinned: boolean; -// prefix?: string; -// reactions: { [s: string]: { count: number; me: boolean } }; -// referencedMessage?: Message | null; -// roleMentions: string[]; -// stickerItems?: StickerItems[]; -// timestamp: number; -// tts: boolean; -// type: number; -// webhookID: T extends GuildTextableWithThread ? string | undefined : undefined; -// constructor(data: BaseData, client: Client); -// addReaction(reaction: string): Promise; -// createThreadWithMessage(options: CreateThreadOptions): Promise; -// crosspost(): Promise : never>; -// delete(reason?: string): Promise; -// deleteWebhook(token: string): Promise; -// edit(content: MessageContent): Promise>; -// editWebhook(token: string, options: MessageWebhookContent): Promise>; -// getReaction(reaction: string, options?: GetMessageReactionOptions): Promise; -// pin(): Promise; -// removeReaction(reaction: string, userID?: string): Promise; -// removeReactionEmoji(reaction: string): Promise; -// removeReactions(): Promise; -// unpin(): Promise; -// } - -// // News channel rate limit is always 0 -// export class NewsChannel extends TextChannel implements GuildPinnable { -// rateLimitPerUser: 0; -// type: Constants["ChannelTypes"]["GUILD_NEWS"]; -// createInvite(options?: CreateInviteOptions, reason?: string): Promise>; -// createMessage(content: MessageContent, file?: FileContent | FileContent[]): Promise>; -// createThreadWithMessage(messageID: string, options: CreateThreadOptions): Promise; -// crosspostMessage(messageID: string): Promise>; -// editMessage(messageID: string, content: MessageContentEdit): Promise>; -// follow(webhookChannelID: string): Promise; -// getInvites(): Promise<(Invite<"withMetadata", this>)[]>; -// getMessage(messageID: string): Promise>; -// getMessages(options?: GetMessagesOptions): Promise[]>; -// getPins(): Promise[]>; -// } - -// export class NewsThreadChannel extends ThreadChannel { -// type: Constants["ChannelTypes"]["GUILD_NEWS_THREAD"]; -// } - -// export class Permission extends Base { -// allow: bigint; -// deny: bigint; -// json: Record; -// constructor(allow: number | string | bigint, deny?: number | string | bigint); -// has(permission: keyof Constants["Permissions"] | bigint): boolean; -// } - -// export class PermissionOverwrite extends Permission { -// id: string; -// type: PermissionType; -// constructor(data: Overwrite); -// } - -// export class Piper extends EventEmitter { -// converterCommand: ConverterCommand; -// dataPacketCount: number; -// encoding: boolean; -// libopus: boolean; -// opus: OpusScript | null; -// opusFactory: () => OpusScript; -// volumeLevel: number; -// constructor(converterCommand: string, opusFactory: OpusScript); -// addDataPacket(packet: unknown): void; -// encode(source: string | Stream, options: VoiceResourceOptions): boolean; -// getDataPacket(): Buffer; -// reset(): void; -// resetPackets(): void; -// setVolume(volume: number): void; -// stop(e: Error, source: Duplex): void; -// } - -// export class PrivateChannel extends Channel implements Textable, Pinnable { -// lastMessageID: string; -// messages: Collection>; -// recipient: User; -// type: PrivateChannelTypes; -// addMessageReaction(messageID: string, reaction: string): Promise; -// createMessage(content: MessageContent, file?: FileContent | FileContent[]): Promise>; -// deleteMessage(messageID: string, reason?: string): Promise; -// editMessage(messageID: string, content: MessageContentEdit): Promise>; -// getMessage(messageID: string): Promise>; -// getMessageReaction(messageID: string, reaction: string, options?: GetMessageReactionOptions): Promise; -// getMessages(options?: GetMessagesOptions): Promise[]>; -// getPins(): Promise[]>; -// leave(): Promise; -// pinMessage(messageID: string): Promise; -// removeMessageReaction(messageID: string, reaction: string): Promise; -// ring(recipient: string[]): void; -// sendTyping(): Promise; -// syncCall(): void; -// unpinMessage(messageID: string): Promise; -// unsendMessage(messageID: string): Promise; -// } - -// export class PrivateThreadChannel extends ThreadChannel { -// threadMetadata: PrivateThreadMetadata; -// type: Constants["ChannelTypes"]["GUILD_PRIVATE_THREAD"]; -// } - -// export class PublicThreadChannel extends ThreadChannel { -// type: GuildPublicThreadChannelTypes; -// edit( -// options: Pick, -// reason?: string, -// ): Promise; -// } - -// export class Relationship extends Base implements Omit { -// activities: Activity[] | null; -// clientStatus?: ClientStatus; -// id: string; -// status: Status; -// type: number; -// user: User; -// constructor(data: BaseData, client: Client); -// } - -// export class ErisRequestHandler implements SimpleJSON { -// globalBlock: boolean; -// latencyRef: LatencyRef; -// options: RequestHandlerOptions; -// ratelimits: { [route: string]: SequentialBucket }; -// readyQueue: (() => void)[]; -// userAgent: string; -// constructor(client: Client, options?: RequestHandlerOptions); -// globalUnblock(): void; -// request( -// method: RequestMethod, -// url: string, -// auth?: boolean, -// body?: { [s: string]: unknown }, -// file?: FileContent, -// _route?: string, -// short?: boolean, -// ): Promise; -// routefy(url: string, method: RequestMethod): string; -// toString(): string; -// toJSON(props?: string[]): JSONCache; -// } - -// export class Role extends Base { -// color: number; -// createdAt: number; -// guild: Guild; -// hoist: boolean; -// icon: string | null; -// iconURL: string | null; -// id: string; -// json: Partial, boolean>>; -// managed: boolean; -// mention: string; -// mentionable: boolean; -// name: string; -// permissions: Permission; -// position: number; -// tags?: RoleTags; -// unicodeEmoji: string | null; -// constructor(data: BaseData, guild: Guild); -// delete(reason?: string): Promise; -// edit(options: RoleOptions, reason?: string): Promise; -// editPosition(position: number): Promise; -// } - -// class SequentialBucket { -// latencyRef: LatencyRef; -// limit: number; -// processing: boolean; -// remaining: number; -// reset: number; -// constructor(limit: number, latencyRef?: LatencyRef); -// check(override?: boolean): void; -// queue(func: (cb: () => void) => void, short?: boolean): void; -// } - -// export class Shard extends EventEmitter implements SimpleJSON { -// client: Client; -// connectAttempts: number; -// connecting: boolean; -// connectTimeout: number | null; -// discordServerTrace?: string[]; -// getAllUsersCount: { [guildID: string]: boolean }; -// getAllUsersLength: number; -// getAllUsersQueue: string; -// globalBucket: Bucket; -// guildCreateTimeout: number | null; -// guildSyncQueue: string[]; -// guildSyncQueueLength: number; -// heartbeatInterval: number | null; -// id: number; -// lastHeartbeatAck: boolean; -// lastHeartbeatReceived: number | null; -// lastHeartbeatSent: number | null; -// latency: number; -// preReady: boolean; -// presence: ClientPresence; -// presenceUpdateBucket: Bucket; -// ready: boolean; -// reconnectInterval: number; -// requestMembersPromise: { [s: string]: RequestMembersPromise }; -// seq: number; -// sessionID: string | null; -// status: "connecting" | "disconnected" | "handshaking" | "identifying" | "ready" | "resuming"; -// unsyncedGuilds: number; -// ws: WebSocket | BrowserWebSocket | null; -// constructor(id: number, client: Client); -// checkReady(): void; -// connect(): void; -// createGuild(_guild: Guild): Guild; -// disconnect(options?: { reconnect?: boolean | "auto" }, error?: Error): void; -// editAFK(afk: boolean): void; -// editStatus( -// status: SelfStatus, -// activities?: ActivityPartial[] | ActivityPartial, -// ): void; -// editStatus(activities?: ActivityPartial[] | ActivityPartial): void; -// // @ts-ignore: Method override -// emit(event: string, ...args: any[]): void; -// emit(event: K, ...args: ShardEvents[K]): boolean; -// emit(event: string, ...args: any[]): boolean; -// getGuildMembers(guildID: string, timeout: number): void; -// hardReset(): void; -// heartbeat(normal?: boolean): void; -// identify(): void; -// initializeWS(): void; -// off(event: K, listener: (...args: ShardEvents[K]) => void): this; -// off(event: string, listener: (...args: any[]) => void): this; -// once(event: K, listener: (...args: ShardEvents[K]) => void): this; -// once(event: string, listener: (...args: any[]) => void): this; -// onPacket(packet: RawPacket): void; -// requestGuildMembers(guildID: string, options?: RequestGuildMembersOptions): Promise; -// requestGuildSync(guildID: string): void; -// reset(): void; -// restartGuildCreateTimeout(): void; -// resume(): void; -// sendStatusUpdate(): void; -// sendWS(op: number, _data: Record, priority?: boolean): void; -// syncGuild(guildID: string): void; -// wsEvent(packet: Required): void; -// on(event: K, listener: (...args: ShardEvents[K]) => void): this; -// on(event: string, listener: (...args: any[]) => void): this; -// toJSON(props?: string[]): JSONCache; -// } - -// export class ShardManager extends Collection implements SimpleJSON { -// buckets: Map; -// connectQueue: Shard[]; -// connectTimeout: NodeJS.Timer | null; -// constructor(client: Client, options: ShardManagerOptions); -// connect(shard: Shard): void; -// spawn(id: number): void; -// tryConnect(): void; -// toString(): string; -// toJSON(props?: string[]): JSONCache; -// } - -// export class SharedStream extends EventEmitter { -// bitrate: number; -// channels: number; -// current?: VoiceStreamCurrent; -// ended: boolean; -// frameDuration: number; -// piper: Piper; -// playing: boolean; -// samplingRate: number; -// speaking: boolean; -// voiceConnections: Collection; -// volume: number; -// add(connection: VoiceConnection): void; -// emit(event: K, ...args: StreamEvents[K]): boolean; -// emit(event: string, ...args: any[]): boolean; -// off(event: K, listener: (...args: StreamEvents[K]) => void): this; -// off(event: string, listener: (...args: any[]) => void): this; -// once(event: K, listener: (...args: StreamEvents[K]) => void): this; -// once(event: string, listener: (...args: any[]) => void): this; -// play(resource: ReadableStream | string, options?: VoiceResourceOptions): void; -// remove(connection: VoiceConnection): void; -// setSpeaking(value: boolean): void; -// setVolume(volume: number): void; -// stopPlaying(): void; -// on(event: K, listener: (...args: StreamEvents[K]) => void): this; -// on(event: string, listener: (...args: any[]) => void): this; -// } - -// export class StageChannel extends VoiceChannel { -// topic?: string; -// type: Constants["ChannelTypes"]["GUILD_STAGE_VOICE"]; -// createInstance(options: StageInstanceOptions): Promise; -// deleteInstance(): Promise; -// editInstance(options: StageInstanceOptions): Promise; -// getInstance(): Promise; -// } - -// export class StageInstance extends Base { -// channel: StageChannel | Uncached; -// client: Client; -// discoverableDisabled: boolean; -// guild: Guild | Uncached; -// privacyLevel: StageInstancePrivacyLevel; -// topic: string; -// constructor(data: BaseData, client: Client); -// delete(): Promise; -// edit(options: StageInstanceOptions): Promise; -// update(data: BaseData): void; -// } - -// export class StoreChannel extends GuildChannel { -// type: Constants["ChannelTypes"]["GUILD_STORE"]; -// edit(options: Omit, reason?: string): Promise; -// } - -// export class TextChannel extends GuildChannel implements GuildTextable, Invitable, GuildPinnable { -// defaultAutoArchiveDuration: AutoArchiveDuration; -// lastMessageID: string; -// lastPinTimestamp: number | null; -// messages: Collection>; -// rateLimitPerUser: number; -// topic?: string | null; -// type: GuildTextChannelTypes; -// constructor(data: BaseData, client: Client, messageLimit: number); -// addMessageReaction(messageID: string, reaction: string): Promise; -// createInvite(options?: CreateInviteOptions, reason?: string): Promise>; -// createMessage(content: MessageContent, file?: FileContent | FileContent[]): Promise>; -// createThreadWithMessage(messageID: string, options: CreateThreadOptions): Promise; -// createThreadWithoutMessage(options: CreateThreadWithoutMessageOptions): Promise; -// createWebhook(options: { name: string; avatar?: string | null }, reason?: string): Promise; -// deleteMessage(messageID: string, reason?: string): Promise; -// deleteMessages(messageIDs: string[], reason?: string): Promise; -// edit(options: Omit, reason?: string): Promise; -// editMessage(messageID: string, content: MessageContentEdit): Promise>; -// getArchivedThreads( -// type: "private", -// options?: GetArchivedThreadsOptions, -// ): Promise>; -// getArchivedThreads( -// type: "public", -// options?: GetArchivedThreadsOptions, -// ): Promise>; -// getInvites(): Promise<(Invite<"withMetadata", this>)[]>; -// getJoinedPrivateArchivedThreads( -// options: GetArchivedThreadsOptions, -// ): Promise>; -// getMessage(messageID: string): Promise>; -// getMessageReaction(messageID: string, reaction: string, options?: GetMessageReactionOptions): Promise; -// getMessages(options?: GetMessagesOptions): Promise[]>; -// getPins(): Promise[]>; -// getWebhooks(): Promise; -// pinMessage(messageID: string): Promise; -// purge(options: PurgeChannelOptions): Promise; -// removeMessageReaction(messageID: string, reaction: string, userID?: string): Promise; -// removeMessageReactionEmoji(messageID: string, reaction: string): Promise; -// removeMessageReactions(messageID: string): Promise; -// sendTyping(): Promise; -// unpinMessage(messageID: string): Promise; -// unsendMessage(messageID: string): Promise; -// } - -// export class ThreadChannel extends GuildChannel implements ThreadTextable { -// lastMessageID: string; -// lastPinTimestamp?: number; -// member?: ThreadMember; -// memberCount: number; -// members: Collection; -// messageCount: number; -// messages: Collection>; -// ownerID: string; -// rateLimitPerUser: number; -// threadMetadata: ThreadMetadata; -// type: GuildThreadChannelTypes; -// constructor(data: BaseData, client: Client, messageLimit?: number); -// addMessageReaction(messageID: string, reaction: string): Promise; -// createMessage(content: MessageContent, file?: FileContent | FileContent[]): Promise>; -// deleteMessage(messageID: string, reason?: string): Promise; -// deleteMessages(messageIDs: string[], reason?: string): Promise; -// edit( -// options: Pick< -// EditChannelOptions, -// "archived" | "autoArchiveDuration" | "invitable" | "locked" | "name" | "rateLimitPerUser" -// >, -// reason?: string, -// ): Promise; -// editMessage(messageID: string, content: MessageContentEdit): Promise>; -// getMembers(): Promise; -// getMessage(messageID: string): Promise>; -// getMessageReaction(messageID: string, reaction: string, options?: GetMessageReactionOptions): Promise; -// getMessages(options?: GetMessagesOptions): Promise[]>; -// getPins(): Promise[]>; -// join(userID?: string): Promise; -// leave(userID?: string): Promise; -// pinMessage(messageID: string): Promise; -// purge(options: PurgeChannelOptions): Promise; -// removeMessageReaction(messageID: string, reaction: string, userID?: string): Promise; -// removeMessageReactionEmoji(messageID: string, reaction: string): Promise; -// removeMessageReactions(messageID: string): Promise; -// sendTyping(): Promise; -// unpinMessage(messageID: string): Promise; -// unsendMessage(messageID: string): Promise; -// } - -// export class ThreadMember extends Base { -// flags: number; -// guildMember?: Member; -// joinTimestamp: number; -// threadID: string; -// constructor(data: BaseData, client: Client); -// leave(): Promise; -// update(data: BaseData): void; -// } - -// export class UnavailableGuild extends Base { -// createdAt: number; -// id: string; -// shard: Shard; -// unavailable: boolean; -// constructor(data: BaseData, client: Client); -// } - -// export class User extends Base { -// accentColor?: number | null; -// avatar: string | null; -// avatarURL: string; -// banner?: string | null; -// bannerURL: string | null; -// bot: boolean; -// createdAt: number; -// defaultAvatar: string; -// defaultAvatarURL: string; -// discriminator: string; -// id: string; -// mention: string; -// publicFlags?: number; -// staticAvatarURL: string; -// system: boolean; -// username: string; -// constructor(data: BaseData, client: Client); -// addRelationship(block?: boolean): Promise; -// deleteNote(): Promise; -// dynamicAvatarURL(format?: ImageFormat, size?: number): string; -// dynamicBannerURL(format?: ImageFormat, size?: number): string | null; -// editNote(note: string): Promise; -// getDMChannel(): Promise; -// getProfile(): Promise; -// removeRelationship(): Promise; -// } - -// export class VoiceChannel extends GuildChannel implements Invitable { -// bitrate: number; -// rtcRegion: string | null; -// type: TextVoiceChannelTypes; -// userLimit: number; -// videoQualityMode: VideoQualityMode; -// voiceMembers: Collection; -// createInvite(options?: CreateInviteOptions, reason?: string): Promise>; -// getInvites(): Promise<(Invite<"withMetadata", VoiceChannel>)[]>; -// join(options?: JoinVoiceChannelOptions): Promise; -// leave(): void; -// } - -// export class VoiceConnection extends EventEmitter implements SimpleJSON { -// bitrate: number; -// channelID: string | null; -// channels: number; -// connecting: boolean; -// connectionTimeout: number | null; -// current?: VoiceStreamCurrent | null; -// ended?: boolean; -// endpoint: URL; -// frameDuration: number; -// frameSize: number; -// heartbeatInterval: number | null; -// id: string; -// mode?: string; -// modes?: string; -// /** Optional dependencies OpusScript (opusscript) or OpusEncoder (@discordjs/opus) */ -// opus: { [userID: string]: unknown }; -// opusOnly: boolean; -// paused: boolean; -// pcmSize: number; -// piper: Piper; -// playing: boolean; -// ready: boolean; -// receiveStreamOpus?: VoiceDataStream | null; -// receiveStreamPCM?: VoiceDataStream | null; -// reconnecting: boolean; -// samplingRate: number; -// secret: Buffer; -// sendBuffer: Buffer; -// sendNonce: Buffer; -// sequence: number; -// shard: Shard | Record; -// shared: boolean; -// speaking: boolean; -// ssrc?: number; -// ssrcUserMap: { [s: number]: string }; -// timestamp: number; -// udpIP?: string; -// udpPort?: number; -// udpSocket: DgramSocket | null; -// volume: number; -// ws: BrowserWebSocket | WebSocket | null; -// constructor(id: string, options?: { shard?: Shard; shared?: boolean; opusOnly?: boolean }); -// connect(data: VoiceConnectData): NodeJS.Timer | void; -// disconnect(error?: Error, reconnecting?: boolean): void; -// emit(event: K, ...args: VoiceEvents[K]): boolean; -// emit(event: string, ...args: any[]): boolean; -// heartbeat(): void; -// off(event: K, listener: (...args: VoiceEvents[K]) => void): this; -// off(event: string, listener: (...args: any[]) => void): this; -// once(event: K, listener: (...args: VoiceEvents[K]) => void): this; -// once(event: string, listener: (...args: any[]) => void): this; -// pause(): void; -// play(resource: ReadableStream | string, options?: VoiceResourceOptions): void; -// receive(type: "opus" | "pcm"): VoiceDataStream; -// registerReceiveEventHandler(): void; -// resume(): void; -// sendAudioFrame(frame: Buffer): void; -// sendUDPPacket(packet: Buffer): void; -// sendWS(op: number, data: Record): void; -// setSpeaking(value: boolean): void; -// setVolume(volume: number): void; -// stopPlaying(): void; -// switchChannel(channelID: string): void; -// updateVoiceState(selfMute: boolean, selfDeaf: boolean): void; -// on(event: K, listener: (...args: VoiceEvents[K]) => void): this; -// on(event: string, listener: (...args: any[]) => void): this; -// toJSON(props?: string[]): JSONCache; -// } - -// export class VoiceConnectionManager extends Collection -// implements SimpleJSON { -// constructor(vcObject: new () => T); -// join(guildID: string, channelID: string, options: VoiceResourceOptions): Promise; -// leave(guildID: string): void; -// switch(guildID: string, channelID: string): void; -// voiceServerUpdate(data: VoiceServerUpdateData): void; -// toJSON(props?: string[]): JSONCache; -// } - -// export class VoiceDataStream extends EventEmitter { -// type: "opus" | "pcm"; -// constructor(type: string); -// on(event: "data", listener: (data: Buffer, userID: string, timestamp: number, sequence: number) => void): this; -// } - -// export class VoiceState extends Base { -// channelID: string | null; -// createdAt: number; -// deaf: boolean; -// id: string; -// mute: boolean; -// requestToSpeakTimestamp: number | null; -// selfDeaf: boolean; -// selfMute: boolean; -// selfStream: boolean; -// selfVideo: boolean; -// sessionID: string | null; -// suppress: boolean; -// constructor(data: BaseData); -// } diff --git a/packages/client/src/utils/BrowserWebSocket.ts b/packages/client/src/utils/BrowserWebSocket.ts index f83460ffb..9cd1f18a1 100644 --- a/packages/client/src/utils/BrowserWebSocket.ts +++ b/packages/client/src/utils/BrowserWebSocket.ts @@ -1,6 +1,6 @@ /* eslint-disable @typescript-eslint/explicit-function-return-type */ /* eslint-disable @typescript-eslint/no-var-requires */ -import { EventEmitter } from "node:events" +import { EventEmitter } from 'node:events' class BrowserWebSocketError extends Error { static CONNECTING: 0 = 0 @@ -49,7 +49,7 @@ class BrowserWebSocket extends EventEmitter { } static set CONNECTING(state: number) { - BrowserWebSocket.CONNECTING = state; + BrowserWebSocket.CONNECTING = state } static get OPEN() { @@ -57,7 +57,7 @@ class BrowserWebSocket extends EventEmitter { } static set OPEN(state: number) { - BrowserWebSocket.OPEN = state; + BrowserWebSocket.OPEN = state } static get CLOSING() { @@ -65,7 +65,7 @@ class BrowserWebSocket extends EventEmitter { } static set CLOSING(state: number) { - BrowserWebSocket.CLOSING = state; + BrowserWebSocket.CLOSING = state } static get CLOSED() { @@ -73,7 +73,7 @@ class BrowserWebSocket extends EventEmitter { } static set CLOSED(state: number) { - BrowserWebSocket.CLOSED = state; + BrowserWebSocket.CLOSED = state } close(code?: number, reason?: string) { diff --git a/packages/client/tests/index.spec.ts b/packages/client/tests/index.spec.ts index 4af6a08d5..4cc609818 100644 --- a/packages/client/tests/index.spec.ts +++ b/packages/client/tests/index.spec.ts @@ -2,6 +2,6 @@ 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/README.md b/packages/gateway/README.md index d608547e2..894f142af 100644 --- a/packages/gateway/README.md +++ b/packages/gateway/README.md @@ -53,7 +53,7 @@ This WS service is meant for ADVANCED DEVELOPERS ONLY! ```ts createGatewayManager({ // TODO: (docs) Fill this out -}); +}) ``` ## API/Docs diff --git a/packages/gateway/src/Shard.ts b/packages/gateway/src/Shard.ts index 01da47bc8..607117bb0 100644 --- a/packages/gateway/src/Shard.ts +++ b/packages/gateway/src/Shard.ts @@ -16,7 +16,7 @@ import type { RequestMemberRequest } from './manager.js' import type { BotStatusUpdate, ShardEvents, ShardGatewayConfig, ShardHeart, ShardSocketRequest, StatusUpdate, UpdateVoiceState } from './types.js' import { ShardSocketCloseCodes, ShardState } from './types.js' -export class Shard { +export class DiscordenoShard { /** The id of the shard */ id: number /** The connection config details that this shard will used to connect to discord. */ @@ -105,7 +105,7 @@ export class Shard { } /** Connect the shard with the gateway and start heartbeating. This will not identify the shard to the gateway. */ - async connect(): Promise { + async connect(): Promise { // 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)) { @@ -750,4 +750,4 @@ export interface ShardCreateOptions { events: ShardEvents } -export default Shard +export default DiscordenoShard diff --git a/packages/gateway/src/types.ts b/packages/gateway/src/types.ts index f64f3c739..a5440069b 100644 --- a/packages/gateway/src/types.ts +++ b/packages/gateway/src/types.ts @@ -173,7 +173,7 @@ export interface StatusUpdate { // /** Unix time (in milliseconds) of when the client went idle, or null if the client is not idle */ // since: number | null; /** The user's activities */ - activities?: Camelize>> + activities?: Camelize>> /** The user's new status */ status: keyof typeof PresenceStatus // /** Whether or not the client is afk */ diff --git a/packages/rest/src/index.ts b/packages/rest/src/index.ts index 20430ac42..8d4eb8e0d 100644 --- a/packages/rest/src/index.ts +++ b/packages/rest/src/index.ts @@ -3,4 +3,4 @@ export * from './typings/routes.js' export * from './invalidBucket.js' export * from './manager.js' export * from './queue.js' -export * from './types.js' \ No newline at end of file +export * from './types.js' diff --git a/packages/rest/src/invalidBucket.ts b/packages/rest/src/invalidBucket.ts index cc58ef660..12c65a755 100644 --- a/packages/rest/src/invalidBucket.ts +++ b/packages/rest/src/invalidBucket.ts @@ -7,9 +7,7 @@ import { delay, logger } from '@discordeno/utils' * @param options The options used to configure this bucket. * @returns RefillingBucket */ -export function createInvalidRequestBucket ( - options: InvalidRequestBucketOptions -): InvalidRequestBucket { +export function createInvalidRequestBucket(options: InvalidRequestBucketOptions): InvalidRequestBucket { const bucket: InvalidRequestBucket = { current: options.current ?? 0, max: options.max ?? 10000, @@ -87,7 +85,7 @@ export function createInvalidRequestBucket ( bucket.timeoutId = undefined }, bucket.interval) } - } + }, } return bucket diff --git a/packages/rest/src/manager.ts b/packages/rest/src/manager.ts index 1eb0b2e9b..2247a0f3e 100644 --- a/packages/rest/src/manager.ts +++ b/packages/rest/src/manager.ts @@ -14,7 +14,7 @@ import { isGetMessagesLimit, logger, processReactionString, - urlToBase64 + urlToBase64, } from '@discordeno/utils' import { createInvalidRequestBucket } from './invalidBucket.js' @@ -22,9 +22,11 @@ import { Queue } from './queue.js' import type { BigString, - Camelize, DiscordApplication, + Camelize, + DiscordApplication, DiscordApplicationCommand, - DiscordApplicationCommandPermissions, DiscordAuditLog, + DiscordApplicationCommandPermissions, + DiscordAuditLog, DiscordAutoModerationRule, DiscordBan, DiscordChannel, @@ -43,7 +45,8 @@ import type { DiscordListArchivedThreads, DiscordMember, DiscordMemberWithUser, - DiscordMessage, DiscordPrunedCount, + DiscordMessage, + DiscordPrunedCount, DiscordRole, DiscordScheduledEvent, DiscordStageInstance, @@ -55,8 +58,11 @@ import type { DiscordVanityUrl, DiscordVoiceRegion, DiscordWebhook, - DiscordWelcomeScreen, GetMessagesOptions, GetScheduledEventUsers, MfaLevels, - ModifyGuildTemplate + DiscordWelcomeScreen, + GetMessagesOptions, + GetScheduledEventUsers, + MfaLevels, + ModifyGuildTemplate, } from '@discordeno/types' import type { CreateRestManagerOptions, RestManager, SendRequestOptions } from './types.js' @@ -873,7 +879,7 @@ export function createRestManager(options: CreateRestManagerOptions): RestManage rest.invalidBucket.handleCompletedRequest(response.status, response.headers.get('X-RateLimit-Scope') === 'shared') const resetAfter = response.headers.get('x-ratelimit-reset-after') - logger.warn(`Request to ${url} was rate limited. Reset after ${resetAfter} seconds.`,); + logger.warn(`Request to ${url} was rate limited. Reset after ${resetAfter} seconds.`) if (resetAfter) await delay(Number(resetAfter) * 1000) // process the response to prevent mem leak await response.json() diff --git a/packages/rest/src/types.ts b/packages/rest/src/types.ts index a9f6b75bf..48d118d04 100644 --- a/packages/rest/src/types.ts +++ b/packages/rest/src/types.ts @@ -1,4 +1,99 @@ -import type { ApplicationCommandPermissions, AtLeastOne, BeginGuildPrune, BigString, Camelize, CreateApplicationCommand, CreateAutoModerationRuleOptions, CreateChannelInvite, CreateForumPostWithMessage, CreateGuild, CreateGuildBan, CreateGuildChannel, CreateGuildEmoji, CreateGuildFromTemplate, CreateGuildRole, CreateGuildStickerOptions, CreateMessageOptions, CreateScheduledEvent, CreateStageInstance, CreateTemplate, DeleteWebhookMessageOptions, DiscordActiveThreads, DiscordApplication, DiscordApplicationCommand, DiscordApplicationCommandPermissions, DiscordArchivedThreads, DiscordAuditLog, DiscordAutoModerationRule, DiscordBan, DiscordChannel, DiscordEmoji, DiscordFollowedChannel, DiscordGetGatewayBot, DiscordGuild, DiscordGuildPreview, DiscordGuildWidget, DiscordGuildWidgetSettings, DiscordIntegration, DiscordInvite, DiscordInviteMetadata, DiscordMember, DiscordMemberWithUser, DiscordMessage, DiscordModifyGuildWelcomeScreen, DiscordPrunedCount, DiscordRole, DiscordScheduledEvent, DiscordStageInstance, DiscordSticker, DiscordStickerPack, DiscordTemplate, DiscordThreadMember, DiscordUser, DiscordVanityUrl, DiscordVoiceRegion, DiscordWebhook, DiscordWelcomeScreen, EditAutoModerationRuleOptions, EditBotMemberOptions, EditChannelPermissionOverridesOptions, EditGuildRole, EditGuildStickerOptions, EditMessage, EditOwnVoiceState, EditScheduledEvent, EditStageInstanceOptions, EditUserVoiceState, ExecuteWebhook, GetBans, GetGuildAuditLog, GetGuildPruneCountQuery, GetInvite, GetMessagesOptions, GetReactions, GetScheduledEvents, GetScheduledEventUsers, GetWebhookMessageOptions, InteractionCallbackData, InteractionResponse, ListArchivedThreads, ListGuildMembers, MfaLevels, ModifyChannel, ModifyGuild, ModifyGuildChannelPositions, ModifyGuildEmoji, ModifyGuildMember, ModifyGuildTemplate, ModifyRolePositions, ModifyWebhook, SearchMembers, StartThreadWithMessage, StartThreadWithoutMessage, WithReason } from "@discordeno/types" +import type { + ApplicationCommandPermissions, + AtLeastOne, + BeginGuildPrune, + BigString, + Camelize, + CreateApplicationCommand, + CreateAutoModerationRuleOptions, + CreateChannelInvite, + CreateForumPostWithMessage, + CreateGuild, + CreateGuildBan, + CreateGuildChannel, + CreateGuildEmoji, + CreateGuildFromTemplate, + CreateGuildRole, + CreateGuildStickerOptions, + CreateMessageOptions, + CreateScheduledEvent, + CreateStageInstance, + CreateTemplate, + DeleteWebhookMessageOptions, + DiscordActiveThreads, + DiscordApplication, + DiscordApplicationCommand, + DiscordApplicationCommandPermissions, + DiscordArchivedThreads, + DiscordAuditLog, + DiscordAutoModerationRule, + DiscordBan, + DiscordChannel, + DiscordEmoji, + DiscordFollowedChannel, + DiscordGetGatewayBot, + DiscordGuild, + DiscordGuildPreview, + DiscordGuildWidget, + DiscordGuildWidgetSettings, + DiscordIntegration, + DiscordInvite, + DiscordInviteMetadata, + DiscordMember, + DiscordMemberWithUser, + DiscordMessage, + DiscordModifyGuildWelcomeScreen, + DiscordPrunedCount, + DiscordRole, + DiscordScheduledEvent, + DiscordStageInstance, + DiscordSticker, + DiscordStickerPack, + DiscordTemplate, + DiscordThreadMember, + DiscordUser, + DiscordVanityUrl, + DiscordVoiceRegion, + DiscordWebhook, + DiscordWelcomeScreen, + EditAutoModerationRuleOptions, + EditBotMemberOptions, + EditChannelPermissionOverridesOptions, + EditGuildRole, + EditGuildStickerOptions, + EditMessage, + EditOwnVoiceState, + EditScheduledEvent, + EditStageInstanceOptions, + EditUserVoiceState, + ExecuteWebhook, + GetBans, + GetGuildAuditLog, + GetGuildPruneCountQuery, + GetInvite, + GetMessagesOptions, + GetReactions, + GetScheduledEvents, + GetScheduledEventUsers, + GetWebhookMessageOptions, + InteractionCallbackData, + InteractionResponse, + ListArchivedThreads, + ListGuildMembers, + MfaLevels, + ModifyChannel, + ModifyGuild, + ModifyGuildChannelPositions, + ModifyGuildEmoji, + ModifyGuildMember, + ModifyGuildTemplate, + ModifyRolePositions, + ModifyWebhook, + SearchMembers, + StartThreadWithMessage, + StartThreadWithoutMessage, + WithReason, +} from '@discordeno/types' import type { InvalidRequestBucket } from './invalidBucket.js' import type { Queue } from './queue.js' import type { RestRoutes } from './typings/routes.js' diff --git a/packages/rest/tests/e2e/automod.spec.ts b/packages/rest/tests/e2e/automod.spec.ts index 94c33d24f..6a6aa772d 100644 --- a/packages/rest/tests/e2e/automod.spec.ts +++ b/packages/rest/tests/e2e/automod.spec.ts @@ -1,9 +1,5 @@ import type { Camelize, DiscordChannel, DiscordGuild } from '@discordeno/types' -import { - AutoModerationActionType, - AutoModerationEventTypes, - AutoModerationTriggerTypes -} from '@discordeno/types' +import { AutoModerationActionType, AutoModerationEventTypes, AutoModerationTriggerTypes } from '@discordeno/types' import { expect } from 'chai' import { e2ecache, rest } from './utils.js' @@ -18,7 +14,7 @@ before(async () => { after(async () => { if (rest.invalidBucket.timeoutId) clearTimeout(rest.invalidBucket.timeoutId) if (e2ecache.guild.id && !e2ecache.deletedGuild) { - e2ecache.deletedGuild = true; + e2ecache.deletedGuild = true await rest.deleteGuild(e2ecache.guild.id) } }) @@ -30,13 +26,13 @@ describe('[automod] Run automod tests', async () => { eventType: AutoModerationEventTypes.MessageSend, triggerType: AutoModerationTriggerTypes.Keyword, triggerMetadata: { - keywordFilter: ['iblamewolf'] + keywordFilter: ['iblamewolf'], }, actions: [ { - type: AutoModerationActionType.BlockMessage - } - ] + type: AutoModerationActionType.BlockMessage, + }, + ], }) expect(rule.id).to.be.exist @@ -45,20 +41,12 @@ describe('[automod] Run automod tests', async () => { expect(fetchedRule.id).to.be.exist 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.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(fetchedRule.actions[0].type).to.equal(AutoModerationActionType.BlockMessage) await rest.deleteAutomodRule(e2ecache.guild.id, rule.id) }) @@ -69,16 +57,16 @@ describe('[automod] Run automod tests', async () => { eventType: AutoModerationEventTypes.MessageSend, triggerType: AutoModerationTriggerTypes.Keyword, triggerMetadata: { - keywordFilter: ['iblamewolf'] + keywordFilter: ['iblamewolf'], }, actions: [ { type: AutoModerationActionType.Timeout, metadata: { - durationSeconds: 10 - } - } - ] + durationSeconds: 10, + }, + }, + ], }) expect(rule.id).to.be.exist @@ -87,20 +75,12 @@ describe('[automod] Run automod tests', async () => { expect(fetchedRule.id).to.be.exist 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.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].type).to.equal(AutoModerationActionType.Timeout) expect(fetchedRule.actions[0].metadata?.durationSeconds).to.equal(10) await rest.deleteAutomodRule(e2ecache.guild.id, rule.id) @@ -112,19 +92,19 @@ describe('[automod] Run automod tests', async () => { eventType: AutoModerationEventTypes.MessageSend, triggerType: AutoModerationTriggerTypes.Keyword, triggerMetadata: { - keywordFilter: ['iblamewolf'] + keywordFilter: ['iblamewolf'], }, actions: [ { - type: AutoModerationActionType.BlockMessage + type: AutoModerationActionType.BlockMessage, }, { type: AutoModerationActionType.Timeout, metadata: { - durationSeconds: 10 - } - } - ] + durationSeconds: 10, + }, + }, + ], }) expect(rule.id).to.be.exist @@ -137,7 +117,7 @@ describe('[automod] Run automod tests', async () => { beforeEach(async () => { channel = await rest.createChannel(e2ecache.guild.id, { - name: 'test' + name: 'test', }) }) @@ -151,16 +131,16 @@ describe('[automod] Run automod tests', async () => { eventType: AutoModerationEventTypes.MessageSend, triggerType: AutoModerationTriggerTypes.Keyword, triggerMetadata: { - keywordFilter: ['iblamewolf'] + keywordFilter: ['iblamewolf'], }, actions: [ { type: AutoModerationActionType.SendAlertMessage, metadata: { - channelId: channel.id - } - } - ] + channelId: channel.id, + }, + }, + ], }) expect(rule.id).to.be.exist @@ -169,20 +149,12 @@ describe('[automod] Run automod tests', async () => { expect(fetchedRule.id).to.be.exist 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.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].type).to.equal(AutoModerationActionType.SendAlertMessage) expect(fetchedRule.actions[0].metadata?.channelId).to.equal(channel.id) await rest.deleteAutomodRule(e2ecache.guild.id, rule.id) @@ -194,22 +166,22 @@ describe('[automod] Run automod tests', async () => { eventType: AutoModerationEventTypes.MessageSend, triggerType: AutoModerationTriggerTypes.Keyword, triggerMetadata: { - keywordFilter: ['iblamewolf'] + keywordFilter: ['iblamewolf'], }, actions: [ { type: AutoModerationActionType.SendAlertMessage, metadata: { - channelId: channel.id - } + channelId: channel.id, + }, }, { type: AutoModerationActionType.Timeout, metadata: { - durationSeconds: 10 - } - } - ] + durationSeconds: 10, + }, + }, + ], }) expect(rule.id).to.be.exist @@ -223,25 +195,25 @@ describe('[automod] Run automod tests', async () => { eventType: AutoModerationEventTypes.MessageSend, triggerType: AutoModerationTriggerTypes.Keyword, triggerMetadata: { - keywordFilter: ['iblamewolf'] + keywordFilter: ['iblamewolf'], }, actions: [ { - type: AutoModerationActionType.BlockMessage + type: AutoModerationActionType.BlockMessage, }, { type: AutoModerationActionType.SendAlertMessage, metadata: { - channelId: channel.id - } + channelId: channel.id, + }, }, { type: AutoModerationActionType.Timeout, metadata: { - durationSeconds: 10 - } - } - ] + durationSeconds: 10, + }, + }, + ], }) expect(rule.id).to.be.exist @@ -250,30 +222,18 @@ describe('[automod] Run automod tests', async () => { const fetchedRule = await rest.getAutomodRule(e2ecache.guild.id, rule.id) expect(fetchedRule.id).to.be.exist 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.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(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(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) await rest.deleteAutomodRule(e2ecache.guild.id, rule.id) }) diff --git a/packages/rest/tests/e2e/member.spec.ts b/packages/rest/tests/e2e/member.spec.ts index c3e614c33..907183176 100644 --- a/packages/rest/tests/e2e/member.spec.ts +++ b/packages/rest/tests/e2e/member.spec.ts @@ -22,7 +22,7 @@ before(async () => { after(async () => { if (rest.invalidBucket.timeoutId) clearTimeout(rest.invalidBucket.timeoutId) if (e2ecache.guild.id && !e2ecache.deletedGuild) { - e2ecache.deletedGuild = true; + e2ecache.deletedGuild = true await rest.deleteGuild(e2ecache.guild.id) } }) @@ -37,9 +37,9 @@ describe('[member] Member tests', async () => { it('Gets a member list and checks if the bot is in the member list', async () => { const members = await rest.getMembers(e2ecache.communityGuildId, { - limit: 10 + 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 @@ -64,7 +64,7 @@ describe('[member] Member tests', async () => { // ban member from guild with a reason it('ban member from guild with a reason', async () => { await rest.banMember(e2ecache.communityGuildId, ianID, { - reason: 'Blame Wolf' + reason: 'Blame Wolf', }) expect(await rest.getBan(e2ecache.communityGuildId, ianID)).to.exist }) @@ -72,7 +72,7 @@ describe('[member] Member tests', async () => { // ban member from guild and delete messages it('ban member from guild and delete messages', async () => { await rest.banMember(e2ecache.communityGuildId, ltsID, { - deleteMessageSeconds: 604800 + deleteMessageSeconds: 604800, }) expect(await rest.getBan(e2ecache.communityGuildId, ltsID)).to.exist }) @@ -85,13 +85,9 @@ describe('[member] Member tests', async () => { // unban member from guild it('unban member from guild', async () => { - await Promise.all([ - rest.unbanMember(e2ecache.communityGuildId, wolfID), - rest.unbanMember(e2ecache.communityGuildId, ianID) - ]) + await Promise.all([rest.unbanMember(e2ecache.communityGuildId, wolfID), rest.unbanMember(e2ecache.communityGuildId, ianID)]) - await expect(rest.getBan(e2ecache.communityGuildId, wolfID)).to.eventually - .rejected + await expect(rest.getBan(e2ecache.communityGuildId, wolfID)).to.eventually.rejected }) }) @@ -99,13 +95,13 @@ describe('[member] Member tests', async () => { it("Edit a bot's nickname", async () => { const nick = 'lts20050703' const member = await rest.editBotMember(e2ecache.communityGuildId, { - nick + nick, }) expect(member.nick).to.equal(nick) // Change nickname back const member2 = await rest.editBotMember(e2ecache.communityGuildId, { - nick: null + nick: null, }) expect(member2.nick).to.null }) @@ -119,7 +115,7 @@ describe('[member] Member tests', async () => { expect(channel?.id).to.exist const message = await rest.sendMessage(channel.id, { - content: 'https://i.imgur.com/doG55NR.png' + content: 'https://i.imgur.com/doG55NR.png', }) expect(message?.content).to.exist }) diff --git a/packages/rest/tests/e2e/message.spec.ts b/packages/rest/tests/e2e/message.spec.ts index aeba32b8d..172938205 100644 --- a/packages/rest/tests/e2e/message.spec.ts +++ b/packages/rest/tests/e2e/message.spec.ts @@ -13,7 +13,7 @@ before(async () => { after(async () => { if (rest.invalidBucket.timeoutId) clearTimeout(rest.invalidBucket.timeoutId) if (e2ecache.guild.id && !e2ecache.deletedGuild) { - e2ecache.deletedGuild = true; + e2ecache.deletedGuild = true await rest.deleteGuild(e2ecache.guild.id) } }) @@ -26,51 +26,73 @@ describe('[rest] Message related tests', () => { }) 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) + const image = await fetch('https://cdn.discordapp.com/avatars/270010330782892032/d031ea881688526d1ae235fd2843e53c.jpg?size=2048') + .then(async (res) => await res.blob()) + .catch(() => undefined) expect(image).to.not.be.undefined - if (!image) throw new Error("Was not able to fetch the image.") + if (!image) throw new Error('Was not able to fetch the image.') - const message = await rest.sendMessage('1041029705790402611', { file: { blob: image, name: "gamer" }}) + const message = await rest.sendMessage('1041029705790402611', { file: { blob: image, name: 'gamer' } }) expect(message.attachments.length).to.be.greaterThan(0) const [attachment] = message.attachments - expect(attachment.filename).to.be.equal("gamer") + expect(attachment.filename).to.be.equal('gamer') }) }) - describe('Rate limit manager testing', () => { it('Send 10 messages to 1 channel', async () => { - await Promise.all([0, 1, 2, 3, 4, 5, 6, 7, 8, 9].map(async (i) => { - await rest.sendMessage('1041029705790402611', { content: `10 messages to 1 channel testing rate limit manager ${i}` }) - })) + await Promise.all( + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].map(async (i) => { + await rest.sendMessage('1041029705790402611', { content: `10 messages to 1 channel testing rate limit manager ${i}` }) + }), + ) }) // TODO: Make this dynamic when we can create channels const spamChannelIds = [ - '1041029705790402611', '1041029706838966393', - '1041029707459731586', '1041029708004995199', - '1041029708453789766', '1041029709049385010', - '1041029709632377003', '1041029710227976313', - '1041029710764834856', '1041029711414956202', - '1041029712153149524', '1041029712933306459', - '1041029713566646313', '1041029714254508042', - '1041029714921406555', '1041029716334870629', - '1041029717127614636', '1041029717689647114', - '1041029718603997214', '1041029719925215302', - '1041029721179308082', '1041029721988812860', - '1041029722466943037', '1041029723217743964', - '1041029723872034826', '1041029724492804156', - '1041029725117743144', '1041029725818212474', - '1041029726531227741', '1041029727231684638' + '1041029705790402611', + '1041029706838966393', + '1041029707459731586', + '1041029708004995199', + '1041029708453789766', + '1041029709049385010', + '1041029709632377003', + '1041029710227976313', + '1041029710764834856', + '1041029711414956202', + '1041029712153149524', + '1041029712933306459', + '1041029713566646313', + '1041029714254508042', + '1041029714921406555', + '1041029716334870629', + '1041029717127614636', + '1041029717689647114', + '1041029718603997214', + '1041029719925215302', + '1041029721179308082', + '1041029721988812860', + '1041029722466943037', + '1041029723217743964', + '1041029723872034826', + '1041029724492804156', + '1041029725117743144', + '1041029725818212474', + '1041029726531227741', + '1041029727231684638', ] it('Send 10 messages to 10 channels', async () => { - await Promise.all(spamChannelIds.map(async (channelId) => { - await Promise.all([...Array(10).keys()].map(async (_, index) => { - await rest.sendMessage(channelId, { content: `testing rate limit manager ${index}` }) - })) - })) + await Promise.all( + spamChannelIds.map(async (channelId) => { + await Promise.all( + [...Array(10).keys()].map(async (_, index) => { + await rest.sendMessage(channelId, { content: `testing rate limit manager ${index}` }) + }), + ) + }), + ) }) }) }) diff --git a/packages/rest/tests/e2e/role.spec.ts b/packages/rest/tests/e2e/role.spec.ts index 250f48406..ab87049e5 100644 --- a/packages/rest/tests/e2e/role.spec.ts +++ b/packages/rest/tests/e2e/role.spec.ts @@ -90,7 +90,7 @@ describe('[role] Role tests', async () => { it('Edit the roles hoist', async () => { expect(role.hoist).to.equal(false) const edited = await rest.editRole(e2ecache.guild.id, role.id, { - hoist: true + hoist: true, }) expect(edited.hoist).to.equal(true) }) @@ -100,7 +100,7 @@ describe('[role] Role tests', async () => { await rest.editRole(e2ecache.guild.id, role.id, { hoist: true }) const edited = await rest.editRole(e2ecache.guild.id, role.id, { - hoist: false + hoist: false, }) expect(edited.hoist).to.equal(false) }) @@ -108,7 +108,7 @@ describe('[role] Role tests', async () => { // Edit the roles mentionable it('Edit the roles mentionable', async () => { const edited = await rest.editRole(e2ecache.guild.id, role.id, { - mentionable: true + mentionable: true, }) expect(edited.mentionable).to.equal(true) }) @@ -116,10 +116,10 @@ describe('[role] Role tests', async () => { // Make mentionable false it('Make mentionable false', async () => { await rest.editRole(e2ecache.guild.id, role.id, { - mentionable: true + mentionable: true, }) const edited = await rest.editRole(e2ecache.guild.id, role.id, { - mentionable: false + mentionable: false, }) expect(edited.mentionable).to.equal(false) }) diff --git a/packages/rest/tests/e2e/utils.ts b/packages/rest/tests/e2e/utils.ts index 3d9d843c6..3e18c3e55 100644 --- a/packages/rest/tests/e2e/utils.ts +++ b/packages/rest/tests/e2e/utils.ts @@ -14,5 +14,5 @@ rest.deleteQueueDelay = 10000 export const e2ecache = { guild: await rest.createGuild({ name: 'ddenotester' }), deletedGuild: false, - communityGuildId: E2E_TEST_GUILD_ID + communityGuildId: E2E_TEST_GUILD_ID, } diff --git a/packages/rest/tests/unit/manager.spec.ts b/packages/rest/tests/unit/manager.spec.ts index eda7a9ca2..55bd39b30 100644 --- a/packages/rest/tests/unit/manager.spec.ts +++ b/packages/rest/tests/unit/manager.spec.ts @@ -1,7 +1,7 @@ import { expect } from 'chai' import { afterEach, beforeEach, describe, it } from 'mocha' import sinon from 'sinon' -import type { RestManager } from '../../src/manager.js' +import type { RestManager } from '../../src/types.js' import { createRestManager } from '../../src/manager.js' import { fakeToken as token } from '../constants.js' diff --git a/packages/types/README.md b/packages/types/README.md index 961c5a7de..3c7dfe717 100644 --- a/packages/types/README.md +++ b/packages/types/README.md @@ -103,28 +103,24 @@ Have your cache setup in any way you like. Redis, PGSQL or any cache layer you w Here is a minimal example to get started with: ```typescript -import { - createBot, - Intents, - startBot, -} from "https://deno.land/x/discordeno@13.0.0/mod.ts"; +import { createBot, Intents, startBot } from 'https://deno.land/x/discordeno@13.0.0/mod.ts' const bot = createBot({ token: process.env.DISCORD_TOKEN, intents: Intents.Guilds | Intents.GuildMessages, events: { ready() { - console.log("Successfully connected to gateway"); + console.log('Successfully connected to gateway') }, }, -}); +}) // Another way to do events bot.events.messageCreate = function (b, message) { // Process the message here with your command handler. -}; +} -await startBot(bot); +await startBot(bot) ``` ### Tools diff --git a/packages/types/src/discord.ts b/packages/types/src/discord.ts index 045df04fc..d39b00513 100644 --- a/packages/types/src/discord.ts +++ b/packages/types/src/discord.ts @@ -77,50 +77,6 @@ export interface DiscordUser { banner?: string } -// /** https://discord.com/developers/docs/resources/user#connection-object */ -// export interface DiscordConnection { -// /** id of the connection account */ -// id: string -// /** The username of the connection account */ -// name: string -// /** The service of the connection (twitch, youtube) */ -// type: DiscordConnectionServices -// /** Whether the connection is revoked */ -// revoked?: boolean -// /** Whether the connection is verified */ -// verified: boolean -// /** Whether friend sync is enabled for this connection */ -// friend_sync: boolean -// /** Whether activities related to this connection will be shown in presence updates */ -// show_activity: boolean -// /** Visibility of this connection */ -// visibility: VisibilityTypes - -// /** An array of partial server integrations */ -// integrations?: DiscordIntegration[] -// /** Whether this connection has a corresponding third party OAuth2 token. */ -// two_way_link: boolean -// } - -// /** https://discord.com/developers/docs/resources/user#connection-object-services */ -// export type DiscordConnectionServices = -// | 'battlenet' -// | 'ebay' -// | 'epicgames' -// | 'facebook' -// | 'github' -// | 'leagueoflegends' -// | 'playstation' -// | 'reddit' -// | 'riotgames' -// | 'spotify' -// | 'skype' -// | 'steam' -// | 'twitch' -// | 'twitter' -// | 'xbox' -// | 'youtube' - /** https://discord.com/developers/docs/resources/guild#integration-object-integration-structure */ export interface DiscordIntegration { /** Integration Id */ @@ -613,7 +569,6 @@ export interface DiscordGuild { presences?: Array> /** Banner hash */ banner: string | null - // TODO: Can be optimized to a number but is it worth it? /** The preferred locale of a Community guild; used in server discovery and notices from Discord; defaults to "en-US" */ preferred_locale: string /** The id of the channel where admins and moderators of Community guilds receive notices from Discord */ @@ -851,11 +806,6 @@ export interface DiscordThreadMetadata { create_timestamp?: string | null } -// export interface DiscordThreadMemberBase { -// /** Any user-thread settings, currently only used for notifications */ -// flags: number -// } - export interface DiscordThreadMember { /** Any user-thread settings, currently only used for notifications */ flags: number @@ -867,13 +817,6 @@ export interface DiscordThreadMember { join_timestamp: string } -// export interface DiscordThreadMemberGuildCreate { -// /** Any user-thread settings, currently only used for notifications */ -// flags: number -// /** The time the current user last joined the thread */ -// join_timestamp: string -// } - /** https://discord.com/developers/docs/topics/gateway-events#activity-object */ export interface DiscordActivity { /** The activity's name */ @@ -1376,27 +1319,6 @@ export interface DiscordInteractionDataOption { focused?: boolean } -// export interface DiscordInteractionDataResolved { -// /** The Ids and Message objects */ -// messages?: Record -// /** The Ids and User objects */ -// users?: Record -// /** The Ids and partial Member objects */ -// members?: Record< -// string, -// Omit -// > -// /** The Ids and Role objects */ -// roles?: Record -// /** The Ids and partial Channel objects */ -// channels?: Record< -// string, -// Pick -// > -// /** The Ids and attachments objects */ -// attachments?: Record -// } - export interface DiscordListActiveThreads { /** The active threads */ threads: DiscordChannel[] @@ -1483,7 +1405,6 @@ export enum AutoModerationTriggerTypes { } export interface DiscordAutoModerationRuleTriggerMetadata { - // TODO: discord is considering renaming this before release /** The keywords needed to match. Only present when TriggerType.Keyword */ keyword_filter?: string[] /** The pre-defined lists of words to match from. Only present when TriggerType.KeywordPreset */ @@ -2010,39 +1931,6 @@ export interface DiscordGuildPreview { stickers: DiscordSticker[] } -// export interface DiscordDiscoveryCategory { -// /** Numeric id of the category */ -// id: number -// /** The name of this category, in multiple languages */ -// name: DiscordDiscoveryName -// /** Whether this category can be set as a guild's primary category */ -// is_primary: boolean -// } - -// export interface DiscordDiscoveryName { -// /** The name in English */ -// default: string -// /** The name in other languages */ -// localizations?: Record -// } - -// export interface DiscordDiscoveryMetadata { -// /** The guild Id */ -// guild_id: string -// /** The id of the primary discovery category set for this guild */ -// primary_category_id: number -// /** Up to 10 discovery search keywords set for this guild */ -// keywords: string[] | null -// /** Whether guild info is shown when custom emojis from this guild are clicked */ -// emoji_discoverability_enabled: boolean -// /** When the server's partner application was accepted or denied, for applications via Server Settings */ -// partner_actioned_timestamp: string | null -// /** When the server applied for partnership, if it has a pending application */ -// partner_application_timestamp: string | null -// /** Ids of up to 5 discovery subcategories set for this guild */ -// category_ids: number[] -// } - /** https://discord.com/developers/docs/resources/channel#followed-channel-object */ export interface DiscordFollowedChannel { /** Source message id */ @@ -2081,48 +1969,6 @@ export interface DiscordGuildMembersChunk { nonce?: string } -// export interface DiscordComponent { -// /** component type */ -// type: MessageComponentTypes -// /** a developer-defined identifier for the component, max 100 characters */ -// custom_id?: string -// /** whether the component is disabled, default false */ -// disabled?: boolean -// /** For different styles/colors of the buttons */ -// style?: ButtonStyles | TextStyles -// /** text that appears on the button (max 80 characters) */ -// label?: string -// /** the dev-define value of the option, max 100 characters for select or 4000 for input. */ -// value?: string -// /** Emoji object that includes fields of name, id, and animated supporting unicode and custom emojis. */ -// emoji?: { -// /** Emoji id */ -// id?: string -// /** Emoji name */ -// name?: string -// /** Whether this emoji is animated */ -// animated?: boolean -// } -// /** 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 -// /** The choices! Maximum of 25 items. */ -// options?: DiscordSelectOption[] -// /** A custom placeholder text if nothing is selected. Maximum 150 characters. */ -// placeholder?: string -// /** The minimum number of items that must be selected. Default 1. Between 1-25. */ -// min_values?: number -// /** The maximum number of items that can be selected. Default 1. Between 1-25. */ -// max_values?: number -// /** The minimum input length for a text input. Between 0-4000. */ -// min_length?: number -// /** The maximum input length for a text input. Between 1-4000. */ -// max_length?: number -// /** a list of child components */ -// components?: DiscordComponent[] -// /** whether this component is required to be filled, default true */ -// required?: boolean -// } - /** https://discord.com/developers/docs/topics/gateway#channel-pins-update */ export interface DiscordChannelPinsUpdate { /** The id of the guild */ @@ -2355,13 +2201,6 @@ export interface DiscordGuildStickersUpdate { stickers: DiscordSticker[] } -// export interface DiscordAddGuildDiscoverySubcategory { -// /** The guild Id of the subcategory was added to */ -// guild_id: string -// /** The Id of the subcategory added */ -// category_id: number -// } - /** https://discord.com/developers/docs/topics/gateway#guild-member-update */ export interface DiscordGuildMemberUpdate { /** The id of the guild */ @@ -2391,12 +2230,6 @@ export interface DiscordGuildMemberUpdate { /** https://discord.com/developers/docs/topics/gateway#message-reaction-remove-all */ export interface DiscordMessageReactionRemoveAll extends Pick {} -// // TODO: add docs link -// export interface DiscordValidateDiscoverySearchTerm { -// /** Whether the provided term is valid */ -// valid: boolean -// } - /** https://discord.com/developers/docs/topics/gateway#guild-role-update */ export interface DiscordGuildRoleUpdate { /** The id of the guild */ @@ -2480,23 +2313,6 @@ export interface DiscordInstallParams { permissions: string } -// export interface DiscordInteractionResponse { -// type: InteractionResponseTypes -// data?: DiscordInteractionCallbackData -// } - -// export interface DiscordInteractionCallbackData { -// tts?: boolean -// title?: string -// flags?: number -// content?: string -// choices?: DiscordApplicationCommandOptionChoice[] -// custom_id?: string -// embeds?: DiscordEmbed[] -// allowed_mentions?: DiscordAllowedMentions -// components?: DiscordComponent[] -// } - export interface DiscordForumTag { /** The id of the tag */ id: string @@ -2517,42 +2333,6 @@ export interface DiscordDefaultReactionEmoji { emoji_name: string | null } -// export interface DiscordCreateAutomoderationRule { -// /** The name of the rule. */ -// name: string -// /** The type of event to trigger the rule on. */ -// event_type: AutoModerationEventTypes -// /** The type of trigger to use for the rule. */ -// trigger_type: AutoModerationTriggerTypes -// /** The metadata to use for the trigger. */ -// trigger_metadata: DiscordAutoModerationRuleTriggerMetadata -// /** The actions that will trigger for this rule */ -// actions: DiscordAutoModerationAction[] -// /** Whether the rule should be enabled, true by default. */ -// enabled?: boolean -// /** The role ids that should not be effected by the rule */ -// exempt_roles?: string[] -// /** The channel ids that should not be effected by the rule. */ -// exempt_channels?: string[] -// } - -// export interface DiscordModifyAutomoderationRule { -// /** The name of the rule. */ -// name: string -// /** The type of event to trigger the rule on. */ -// event_type: AutoModerationEventTypes -// /** The metadata to use for the trigger. */ -// trigger_metadata: DiscordAutoModerationRuleTriggerMetadata -// /** The actions that will trigger for this rule */ -// actions: DiscordAutoModerationAction[] -// /** Whether the rule should be enabled, true by default. */ -// enabled?: boolean -// /** The role ids that should not be effected by the rule */ -// exempt_roles?: string[] -// /** The channel ids that should not be effected by the rule. */ -// exempt_channels?: string[] -// } - export interface DiscordModifyChannel { /** 1-100 character channel name */ name?: string @@ -2679,26 +2459,6 @@ export interface DiscordCreateGuildChannel { default_sort_order?: SortOrderTypes | null } -// export interface DiscordBulkDeleteMessages { -// messages: string[] -// } - -// /** https://discord.com/developers/docs/resources/channel#edit-message-json-params */ -// export interface DiscordEditMessage { -// /** The new message contents (up to 2000 characters) */ -// content?: string | null -// /** Embedded `rich` content (up to 6000 characters) */ -// embeds?: DiscordEmbed[] | null -// /** Edit the flags of the message (only `SUPPRESS_EMBEDS` can currently be set/unset) */ -// flags?: 4 | null -// /** Allowed mentions for the message */ -// allowed_mentions?: DiscordAllowedMentions -// /** When specified (adding new attachments), attachments which are not provided in this list will be removed. */ -// attachments?: DiscordAttachment[] -// /** The components you would like to have sent in this message */ -// components?: DiscordMessageComponents -// } - export interface DiscordCreateMessage { /** The message contents (up to 2000 characters) */ content?: string @@ -2707,9 +2467,9 @@ export interface DiscordCreateMessage { /** true if this is a TTS message */ tts?: boolean /** Embedded `rich` content (up to 6000 characters) */ - // embeds?: DiscordEmbed[] + embeds?: DiscordEmbed[] /** Allowed mentions for the message */ - // allowed_mentions?: DiscordAllowedMentions + allowed_mentions?: DiscordAllowedMentions /** Include to make your message a reply */ message_reference?: { /** id of the originating message */ @@ -2725,166 +2485,11 @@ export interface DiscordCreateMessage { fail_if_not_exists: boolean } /** The components you would like to have sent in this message */ - // components?: DiscordMessageComponents + components?: DiscordMessageComponents /** IDs of up to 3 stickers in the server to send in the message */ stickerIds?: [string] | [string, string] | [string, string, string] } -// export interface DiscordCreateScheduledEvent { -// /** the channel id of the scheduled event. */ -// channel_id?: string -// /** location of the event. Required for events with `entityType: ScheduledEventEntityType.External` */ -// location?: string -// /** the name of the scheduled event */ -// name: string -// /** the description of the scheduled event */ -// description: string -// /** the time the scheduled event will start */ -// scheduled_start_time: string -// /** the time the scheduled event will end if it does end. Required for events with `entityType: ScheduledEventEntityType.External` */ -// scheduled_end_time?: string -// /** the privacy level of the scheduled event */ -// privacy_level?: ScheduledEventPrivacyLevel -// /** the type of hosting entity associated with a scheduled event */ -// entity_type: ScheduledEventEntityType -// } - -// export interface DiscordEditScheduledEvent { -// /** the channel id of the scheduled event. null if switching to external event. */ -// channel_id: string | null -// /** location of the event */ -// location?: string -// /** the name of the scheduled event */ -// name: string -// /** the description of the scheduled event */ -// description?: string -// /** the time the scheduled event will start */ -// scheduled_start_time: string -// /** the time the scheduled event will end if it does end. */ -// scheduled_end_time?: string -// /** the privacy level of the scheduled event */ -// privacy_level: ScheduledEventPrivacyLevel -// /** the type of hosting entity associated with a scheduled event */ -// entity_type: ScheduledEventEntityType -// /** the status of the scheduled event */ -// status: ScheduledEventStatus -// } - -// export interface DiscordCreateChannelInvite { -// /** Duration of invite in seconds before expiry, or 0 for never. Between 0 and 604800 (7 days). Default: 86400 (24 hours) */ -// max_age?: number -// /** Max number of users or 0 for unlimited. Between 0 and 100. Default: 0 */ -// max_uses?: number -// /** Whether this invite only grants temporary membership. Default: false */ -// temporary?: boolean -// /** If true, don't try to reuse similar invite (useful for creating many unique one time use invites). Default: false */ -// unique?: boolean -// /** The type of target for this voice channel invite */ -// target_type?: 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 */ -// target_user_id?: string -// /** The id of the embedded application to open for this invite, required if `target_type` is 2, the application must have the `EMBEDDED` flag */ -// target_application_id?: string -// } - -// /** https://discord.com/developers/docs/resources/guild#update-current-user-voice-state */ -// export interface DiscordEditOwnVoiceState { -// /** The id of the channel the user is currently in */ -// channel_id: string -// /** Toggles the user's suppress state */ -// suppress?: boolean -// /** Sets the user's request to speak */ -// request_to_speak_timestamp?: number | null -// } - -// /** https://discord.com/developers/docs/resources/guild#update-user-voice-state */ -// export interface DiscordEditUserVoiceState { -// /** The id of the channel the user is currently in */ -// channel_id: string -// /** Toggles the user's suppress state */ -// suppress?: boolean -// /** The user id to target */ -// user_id: string -// } - -// export interface DiscordEditGuildWidgetSettings { -// /** Whether or not the widget is enabled. */ -// enabled: boolean -// /** The channel id if any for this widget. */ -// channel_id?: string | null -// } - -// /** https://discord.com/developers/docs/resources/guild#create-guild */ -// export interface DiscordCreateGuild { -// /** Name of the guild (1-100 characters) */ -// name: string -// /** Base64 128x128 image for the guild icon */ -// icon?: string -// /** Verification level */ -// verification_level?: VerificationLevels -// /** Default message notification level */ -// default_message_notifications?: DefaultMessageNotificationLevels -// /** Explicit content filter level */ -// explicit_content_filter?: ExplicitContentFilterLevels -// /** New guild roles (first role is the everyone role) */ -// roles?: DiscordRole[] -// /** New guild's channels */ -// channels?: Array> -// /** Id for afk channel */ -// afk_channel_id?: string -// /** Afk timeout in seconds */ -// afk_timeout?: number -// /** The id of the channel where guild notices such as welcome messages and boost events are posted */ -// system_channel_id?: string -// /** System channel flags */ -// system_channel_flags?: SystemChannelFlags -// } - -// /** https://discord.com/developers/docs/resources/guild#modify-guild */ -// export interface DiscordModifyGuild { -// /** Guild name */ -// name?: string -// /** Verification level */ -// verification_level?: VerificationLevels | null -// /** Default message notification filter level */ -// default_message_notifications?: DefaultMessageNotificationLevels | null -// /** Explicit content filter level */ -// explicit_content_filter?: ExplicitContentFilterLevels | null -// /** Id for afk channel */ -// afk_channel_id?: string | null -// /** Afk timeout in seconds */ -// afk_timeout?: 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 -// /** User id to transfer guild ownership to (must be owner) */ -// owner_id?: string -// /** Base64 16:9 png/jpeg image for the guild splash (when the server has `INVITE_SPLASH` feature) */ -// splash?: string | null -// /** Base64 16:9 png/jpeg image for the guild discovery spash (when the server has the `DISCOVERABLE` feature) */ -// discovery_splash?: string | null -// /** Base64 16:9 png/jpeg image for the guild banner (when the server has BANNER feature) */ -// banner?: 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 flags */ -// system_channel_flags?: SystemChannelFlags -// /** The id of the channel where Community guilds display rules and/or guidelines */ -// rules_channel_id?: string | null -// /** The id of the channel where admins and moderators of Community guilds receive notices from Discord */ -// public_updates_channel_id?: string | null -// /** The preferred locale of a Community guild used in server discovery and notices from Discord; defaults to "en-US" */ -// preferred_locale?: string | null -// /** Enabled guild features */ -// features?: GuildFeatures[] -// /** Whether the guild's boost progress bar should be enabled */ -// premium_progress_bar_enabled?: boolean -// } - -// export interface DiscordEditGuildMFALevel { -// /** The level to set for the guilds mfa level. */ -// level: MfaLevels -// } - /** https://discord.com/developers/docs/resources/guild#modify-guild-welcome-screen */ export interface DiscordModifyGuildWelcomeScreen { /** Whether the welcome screen is enabled */ @@ -2895,31 +2500,6 @@ export interface DiscordModifyGuildWelcomeScreen { description?: string | null } -// export interface DiscordStartThreadWithMessage { -// /** 1-100 character thread name */ -// name: string -// /** Duration in minutes to automatically archive the thread after recent activity */ -// auto_archive_duration: 60 | 1440 | 4320 | 10080 -// /** Amount of seconds a user has to wait before sending another message (0-21600) */ -// rate_limit_per_user?: number | null -// } - -// export interface DiscordStartThreadWithoutMessage { -// /** 1-100 character thread name */ -// name: string -// /** Duration in minutes to automatically archive the thread after recent activity */ -// auto_archive_duration: 60 | 1440 | 4320 | 10080 -// /** Amount of seconds a user has to wait before sending another message (0-21600) */ -// rate_limit_per_user?: number | null -// /** the type of thread to create */ -// 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 -// } - export interface DiscordFollowAnnouncementChannel { /** The id of the channel to send announcements to. */ webhook_channel_id: string @@ -2946,113 +2526,6 @@ export interface DiscordModifyGuildChannelPositions { parent_id?: string | null } -// /** https://discord.com/developers/docs/resources/guild#create-guild-ban */ -// export interface DiscordCreateGuildBan { -// /** Number of seconds to delete messages for, between 0 and 604800 (7 days) */ -// delete_message_seconds?: number -// } - -// export interface DiscordEditBotMemberOptions { -// nick?: string | null -// } - -// /** https://discord.com/developers/docs/resources/guild#modify-guild-member */ -// export interface DiscordModifyGuildMember { -// /** Value to set users nickname to. Requires the `MANAGE_NICKNAMES` permission */ -// nick?: string | null -// /** Array of role ids the member is assigned. Requires the `MANAGE_ROLES` permission */ -// roles?: string[] | 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 -// /** 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 -// /** Id of channel to move user to (if they are connected to voice). Requires the `MOVE_MEMBERS` permission */ -// channel_id?: string | 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 */ -// communication_disabled_until?: number | null -// } - -// export interface DiscordGetDMChannel { -// /** The user id */ -// recipient_id: string -// } - -// /** https://discord.com/developers/docs/resources/guild#begin-guild-prune */ -// export interface DiscordBeginGuildPrune { -// /** Number of days to prune (1 or more), default: 7 */ -// days?: number -// /** Whether 'pruned' is returned, discouraged for large guilds, default: true */ -// compute_prune_count?: boolean -// /** Role(s) ro include, default: none */ -// include_roles?: string[] -// } - -// export interface DiscordCreateGuildRole { -// /** Name of the role, max 100 characters, default: "new role" */ -// name?: string -// /** Bitwise value of the enabled/disabled permissions, default: everyone permissions in guild */ -// permissions?: string -// /** RGB color value, default: 0 */ -// color?: number -// /** Whether the role should be displayed separately in the sidebar, default: false */ -// hoist?: boolean -// /** Whether the role should be mentionable, default: false */ -// mentionable?: boolean -// /** The role's unicode emoji (if the guild has the `ROLE_ICONS` feature) */ -// unicode_emoji?: string -// /** the role's icon image (if the guild has the `ROLE_ICONS` feature) */ -// icon?: string -// } - -// export interface DiscordEditGuildRole { -// /** Name of the role, max 100 characters, default: "new role" */ -// name?: string -// /** Bitwise value of the enabled/disabled permissions, default: everyone permissions in guild */ -// permissions?: string -// /** RGB color value, default: 0 */ -// color?: number -// /** Whether the role should be displayed separately in the sidebar, default: false */ -// hoist?: boolean -// /** Whether the role should be mentionable, default: false */ -// mentionable?: boolean -// /** The role's unicode emoji (if the guild has the `ROLE_ICONS` feature) */ -// unicode_emoji?: string -// /** the role's icon image (if the guild has the `ROLE_ICONS` feature) */ -// icon?: string -// } - -// export interface DiscordModifyRolePositions { -// /** The role id */ -// id: string -// /** The sorting position for the role. */ -// position?: number | null -// } - -// export interface DiscordCreateGuildStickerOptions { -// /** Name of the sticker (2-30 characters) */ -// name: string -// /** Description of the sticker (empty or 2-100 characters) */ -// description: string -// /** Autocomplete/suggestion tags for the sticker (max 200 characters) */ -// tags: string -// } - -// export interface DiscordEditGuildStickerOptions { -// /** Name of the sticker (2-30 characters) */ -// name?: string -// /** Description of the sticker (empty or 2-100 characters) */ -// description?: string | null -// /** Autocomplete/suggestion tags for the sticker (max 200 characters) */ -// tags?: string -// } - -// export interface DiscordCreateTemplate { -// /** Name which the template should have */ -// name: string -// /** Description of the template */ -// description?: string -// } - export interface DiscordCreateWebhook { /** Name of the webhook (1-80 characters) */ name: string @@ -3060,39 +2533,6 @@ export interface DiscordCreateWebhook { avatar?: string | null } -// export interface DiscordModifyWebhook { -// /** The default name of the webhook */ -// name?: string -// /** Image for the default webhook avatar */ -// avatar?: string | null -// /** The new channel id this webhook should be moved to */ -// channel_id?: string -// } - -// /** https://discord.com/developers/docs/resources/webhook#execute-webhook */ -// export interface DiscordExecuteWebhook { -// /** 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 -// /** Send a message to the specified thread within a webhook's channel. The thread will automatically be unarchived. */ -// thread_id?: string -// /** Name of the thread to create (target channel has to be type of forum channel) */ -// thread_name?: string -// /** The message contents (up to 2000 characters) */ -// content?: string -// /** Override the default username of the webhook */ -// username?: string -// /** Override the default avatar of the webhook */ -// avatar_url?: string -// /** True if this is a TTS message */ -// tts?: boolean -// /** Embedded `rich` content */ -// embeds?: DiscordEmbed[] -// /** Allowed mentions for the message */ -// allowed_mentions?: DiscordAllowedMentions -// /** the components to include with the message */ -// components?: DiscordMessageComponents -// } - /** https://discord.com/developers/docs/resources/channel#start-thread-in-forum-channel */ export interface DiscordCreateForumPostWithMessage { /** 1-100 character channel name */ @@ -3126,14 +2566,6 @@ export interface DiscordCreateForumPostWithMessage { applied_tags?: string[] } -// /** https://discord.com/developers/docs/resources/guild-template#modify-guild-template */ -// export interface DiscordModifyGuildTemplate { -// /** name of the template (1-100 characters) */ -// name?: string -// /** description for the template (0-120 characters) */ -// description?: string -// } - export type DiscordArchivedThreads = DiscordActiveThreads & { hasMore: boolean } @@ -3150,4 +2582,4 @@ export interface DiscordVanityUrl { export interface DiscordPrunedCount { pruned: number -} \ No newline at end of file +} diff --git a/packages/types/src/discordeno.ts b/packages/types/src/discordeno.ts index 64a1b343c..c6050f32b 100644 --- a/packages/types/src/discordeno.ts +++ b/packages/types/src/discordeno.ts @@ -69,19 +69,6 @@ export interface CreateMessageOptions { /** IDs of up to 3 stickers in the server to send in the message */ stickerIds?: [BigString] | [BigString, BigString] | [BigString, BigString, BigString] } -// import type { -// AllowedMentionsTypes, -// ApplicationCommandTypes, -// AuditLogEvents, -// BigString, -// ButtonStyles, -// InteractionResponseTypes, -// Localization, -// MessageComponentTypes, -// OverwriteTypes, -// PermissionStrings, -// TextStyles -// } from './shared.js' export type MessageComponents = ActionRow[] @@ -296,17 +283,6 @@ export interface OverwriteReadable { deny?: PermissionStrings[] } -// export interface GetGatewayBot { -// url: string -// shards: number -// sessionStartLimit: { -// total: number -// remaining: number -// resetAfter: number -// maxConcurrency: number -// } -// } - /** 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 */ @@ -815,7 +791,6 @@ export interface EditAutoModerationRuleOptions extends WithReason { triggerMetadata: { /** The keywords needed to match. Only present when TriggerType.Keyword */ keywordFilter?: string[] - // TODO: This may need a special type or enum /** The pre-defined lists of words to match from. Only present when TriggerType.KeywordPreset */ presets?: DiscordAutoModerationRuleTriggerMetadataPresets[] /** The substrings which will exempt from triggering the preset trigger type. Only present when TriggerType.KeywordPreset */ diff --git a/packages/types/src/shared.ts b/packages/types/src/shared.ts index f79a286e2..fed53662b 100644 --- a/packages/types/src/shared.ts +++ b/packages/types/src/shared.ts @@ -7,14 +7,6 @@ export enum PresenceStatus { offline, } -// /* https://discord.com/developers/docs/resources/channel#message-object-message-flags */ -// export enum ApplicationCommandFlags { -// /** Do not include any embeds when serialising this message */ -// SuppressEmbeds = 1 << 2, -// /** Only visible to the user who invoked the interaction */ -// Ephemeral = 1 << 6, -// } - /** https://discord.com/developers/docs/resources/user#user-object-premium-types */ export enum PremiumTypes { None, @@ -57,14 +49,6 @@ export enum IntegrationExpireBehaviors { Kick, } -// /** https://discord.com/developers/docs/resources/user#connection-object-visibility-types */ -// export enum VisibilityTypes { -// /** Invisible to everyone except the user themselves */ -// None, -// /** Visible to everyone */ -// Everyone, -// } - /** https://discord.com/developers/docs/topics/teams#data-models-membership-state-enum */ export enum TeamMembershipStates { Invited = 1, @@ -189,18 +173,6 @@ export enum VerificationLevels { VeryHigh, } -// /** https://discord.com/developers/docs/topics/permissions#role-object-role-structure */ -// export interface BaseRole { -// /** Role name */ -// name: string -// /** Integer representation of hexadecimal color code */ -// color: number -// /** Position of this role */ -// position: number -// /** role unicode emoji */ -// unicodeEmoji?: string -// } - /** https://discord.com/developers/docs/resources/guild#guild-object-guild-features */ export enum GuildFeatures { /** Guild has access to set an invite splash background */ @@ -525,8 +497,6 @@ export enum AuditLogEvents { } export enum ScheduledEventPrivacyLevel { - /** the scheduled event is public and available in discovery. DISCORD DEVS DISABLED THIS! WILL ERROR IF USED! */ - // Public = 1, /** the scheduled event is only accessible to guild members */ GuildOnly = 2, } @@ -565,19 +535,6 @@ export enum ApplicationCommandPermissionTypes { Channel, } -// /** https://discord.com/developers/docs/topics/gateway#activity-object-activity-flags */ -// export enum ActivityFlags { -// Instance = 1 << 0, -// Join = 1 << 1, -// Spectate = 1 << 2, -// JoinRequest = 1 << 3, -// Sync = 1 << 4, -// Play = 1 << 5, -// PartyPrivacyFriends = 1 << 6, -// PartyPrivacyVoiceChannel = 1 << 7, -// Embedded = 1 << 8, -// } - /** https://discord.com/developers/docs/topics/permissions#permissions-bitwise-permission-flags */ export enum BitwisePermissionFlags { /** Allows creation of instant invites */ @@ -666,314 +623,6 @@ export enum BitwisePermissionFlags { export type PermissionStrings = keyof typeof BitwisePermissionFlags -// /** https://discord.com/developers/docs/topics/opcodes-and-status-codes#voice */ -// export enum VoiceOpcodes { -// /** Begin a voice websocket connection. */ -// Identify, -// /** Select the voice protocol. */ -// SelectProtocol, -// /** Complete the websocket handshake. */ -// Ready, -// /** Keep the websocket connection alive. */ -// Heartbeat, -// /** Describe the session. */ -// SessionDescription, -// /** Indicate which users are speaking. */ -// Speaking, -// /** Sent to acknowledge a received client heartbeat. */ -// HeartbeatACK, -// /** Resume a connection. */ -// Resume, -// /** Time to wait between sending heartbeats in milliseconds. */ -// Hello, -// /** Acknowledge a successful session resume. */ -// Resumed, -// /** A client has disconnected from the voice channel */ -// ClientDisconnect = 13, -// } - -// /** https://discord.com/developers/docs/topics/opcodes-and-status-codes#voice */ -// export enum VoiceCloseEventCodes { -// /** You sent an invalid [opcode](https://discord.com/developers/docs/topics/opcodes-and-status-codes#voice-voice-opcodes). */ -// UnknownOpcode = 4001, -// /** You sent a invalid payload in your [identifying](https://discord.com/developers/docs/topics/gateway#identify) to the Gateway. */ -// FailedToDecodePayload, -// /** You sent a payload before [identifying](https://discord.com/developers/docs/topics/gateway#identify) with the Gateway. */ -// NotAuthenticated, -// /** The token you sent in your [identify](https://discord.com/developers/docs/topics/gateway#identify) payload is incorrect. */ -// AuthenticationFailed, -// /** You sent more than one [identify](https://discord.com/developers/docs/topics/gateway#identify) payload. Stahp. */ -// AlreadyAuthenticated, -// /** Your session is no longer valid. */ -// SessionNoLongerValid, -// /** Your session has timed out. */ -// SessionTimedOut = 4009, -// /** We can't find the server you're trying to connect to. */ -// ServerNotFound = 4011, -// /** We didn't recognize the [protocol](https://discord.com/developers/docs/topics/voice-connections#establishing-a-voice-udp-connection-example-select-protocol-payload) you sent. */ -// UnknownProtocol, -// /** Channel was deleted, you were kicked, voice server changed, or the main gateway session was dropped. Should not reconnect. */ -// Disconnect = 4014, -// /** The server crashed. Our bad! Try [resuming](https://discord.com/developers/docs/topics/voice-connections#resuming-voice-connection). */ -// VoiceServerCrashed, -// /** We didn't recognize your [encryption](https://discord.com/developers/docs/topics/voice-connections#encrypting-and-sending-voice). */ -// UnknownEncryptionMode, -// } - -// /** https://discord.com/developers/docs/topics/opcodes-and-status-codes#rpc */ -// export enum RpcErrorCodes { -// /** An unknown error occurred. */ -// UnknownError = 1000, -// /** You sent an invalid payload. */ -// InvalidPayload = 4000, -// /** Invalid command name specified. */ -// InvalidCommand = 4002, -// /** Invalid guild ID specified. */ -// InvalidGuild, -// /** Invalid event name specified. */ -// InvalidEvent, -// /** Invalid channel ID specified. */ -// InvalidChannel, -// /** You lack permissions to access the given resource. */ -// InvalidPermissions, -// /** An invalid OAuth2 application ID was used to authorize or authenticate with. */ -// InvalidClientId, -// /** An invalid OAuth2 application origin was used to authorize or authenticate with. */ -// InvalidOrigin, -// /** An invalid OAuth2 token was used to authorize or authenticate with. */ -// InvalidToken, -// /** The specified user ID was invalid. */ -// InvalidUser, -// /** A standard OAuth2 error occurred; check the data object for the OAuth2 error details. */ -// OAuth2Error = 5000, -// /** An asynchronous `SELECT_TEXT_CHANNEL`/`SELECT_VOICE_CHANNEL` command timed out. */ -// SelectChannelTimedOut, -// /** An asynchronous `GET_GUILD` command timed out. */ -// GetGuildTimedOut, -// /** You tried to join a user to a voice channel but the user was already in one. */ -// SelectVoiceForceRequired, -// /** You tried to capture more than one shortcut key at once. */ -// CaptureShortcutAlreadyListening, -// } - -// /** https://discord.com/developers/docs/topics/opcodes-and-status-codes#rpc */ -// export enum RpcCloseEventCodes { -// /** You connected to the RPC server with an invalid client ID. */ -// InvalidClientId = 4000, -// /** You connected to the RPC server with an invalid origin. */ -// InvalidOrigin, -// /** You are being rate limited. */ -// RateLimited, -// /** The OAuth2 token associated with a connection was revoked, get a new one! */ -// TokenRevoked, -// /** The RPC Server version specified in the connection string was not valid. */ -// InvalidVersion, -// /** The encoding specified in the connection string was not valid. */ -// InvalidEncoding, -// } - -// /** https://discord.com/developers/docs/topics/opcodes-and-status-codes#json */ -// export enum JsonErrorCodes { -// /** General error (such as a malformed request body, amongst other things) */ -// GeneralError, -// UnknownAccount = 10001, -// UnknownApplication, -// UnknownChannel, -// UnknownGuild, -// UnknownIntegration, -// UnknownInvite, -// UnknownMember, -// UnknownMessage, -// UnknownPermissionOverwrite, -// UnknownProvider, -// UnknownRole, -// UnknownToken, -// UnknownUser, -// UnknownEmoji, -// UnknownWebhook, -// UnknownWebhookService, -// UnknownSession = 10020, -// UnknownBan = 10026, -// UnknownSKU, -// UnknownStoreListing, -// UnknownEntitlement, -// UnknownBuild, -// UnknownLobby, -// UnknownBranch, -// UnknownStoreDirectoryLayout, -// UnknownRedistributable = 10036, -// UnknownGiftCode = 10038, -// UnknownStream = 10049, -// UnknownPremiumServerSubscribeCooldown, -// UnknownGuildTemplate = 10057, -// UnknownDiscoveryCategory = 10059, -// UnknownSticker, -// UnknownInteraction = 10062, -// UnknownApplicationCommand = 10063, -// UnknownVoiceState = 10065, -// UnknownApplicationCommandPermissions, -// UnknownStageInstance, -// UnknownGuildMemberVerificationForm, -// UnknownGuildWelcomeScreen, -// UnknownGuildScheduledEvent, -// UnknownGuildScheduledEventUser, -// UnknownTag = 10087, -// BotsCannotUseThisEndpoint = 20001, -// OnlyBotsCanUseThisEndpoint, -// ExplicitContentCannotBeSentToTheDesiredRecipient = 20009, -// YouAreNotAuthorizedToPerformThisActionOnThisApplication = 20012, -// ThisActionCannotBePerformedDueToSlowmodeRateLimit = 20016, -// OnlyTheOwnerOfThisAccountCanPerformThisAction = 20018, -// ThisMessageCannotBeEditedDueToAnnouncementRateLimits = 20022, -// UnderMinimumAge = 20024, -// TheChannelYouAreWritingHasHitTheWriteRateLimit = 20028, -// TheWriteActionYouArePerformingOnTheServerHasHitTheWriteRateLimit, -// YourStageTopicOrServerNameOrServerDescriptionOrChannelNamesContainsWordsThatAreNotAllowedForPublicStages = 20031, -// GuildPremiumSubscriptionLevelTooLow = 20035, -// MaximumNumberOfGuildsReached = 30001, -// MaximumNumberOfFriendsReached, -// MaximumNumberOfPinsReachedForTheChannel, -// MaximumNumberOfRecipientsReached, -// MaximumNumberOfGuildRolesReached, -// MaximumNumberOfWebhooksReached = 30007, -// MaximumNumberOfEmojisReached, -// MaximumNumberOfReactionsReached = 30010, -// MaximumNumberOfGuildChannelsReached = 30013, -// MaximumNumberOfAttachmentsInAMessageReached = 30015, -// MaximumNumberOfInvitesReached, -// MaximumNumberOfAnimatedEmojisReached = 30018, -// MaximumNumberOfServerMembersReached, -// MaximumNumberOfServerCategoriesHasBeenReached = 30030, -// GuildAlreadyHasTemplate, -// MaximumNumbersOfApplicationCommandsReached, -// MaxNumberOfThreadParticipantsHasBeenReached, -// MaxNumberOfDailyApplicationCommandCreatesHasBeenReached, -// MaximumNumberOfBansForNonGuildMembersHaveBeenExceeded, -// MaximumNumberOfBansFetchesHasBeenReached = 30037, -// MaximumNumberOfUncompletedGuildScheduledEventsReached = 30038, -// MaximumNumberOfStickersReached = 30039, -// MaximumNumberOfPruneRequestsHasBeenReachedTryAgainLater, -// MaximumNumberOfGuildWidgetSettingsUpdatesHasBeenReachedTryAgainLater = 30042, -// MaximumNumberOfEditsToMessagesOlderThan1HourReachedTryAgainLater = 30046, -// MaximumNumberOfPinnedThreadsInAForumChannelHasBeenReached, -// MaxiumNumberOfTagsInAForumChannelHasBeenReached, -// BitrateIsTooHighForChannelOfThisType = 30052, -// UnauthorizedProvideAValidTokenAndTryAgain = 40001, -// YouNeedToVerifyYourAccountInOrderToPerformThisAction, -// YouAreOpeningDirectMessagesTooFast, -// SendMessagesHasBeenTemporarilyDisabled, -// RequestEntityTooLargeTrySendingSomethingSmallerInSize, -// ThisFeatureHasBeenTemporarilyDisabledServerSide, -// ThisUserBannedFromThisGuild, -// ConnectionHasBeenRevoked = 40012, -// TargetUserIsNotConnectedToVoice = 40032, -// ThisMessageHasAlreadyBeenCrossposted, -// AnApplicationCommandWithThatNameAlreadyExists = 40041, -// ApplicationInteractionFailedToSend = 40043, -// InteractionHasAlreadyBeenAcknowledged = 40060, -// MissingAccess = 50001, -// InvalidAccountType, -// CannotExecuteActionOnADMChannel, -// GuildWidgetDisabled, -// CannotEditMessageAuthoredByAnotherUser, -// CannotSendAnEmptyMessage, -// CannotSendMessagesToThisUser, -// CannotSendMessagesInANonTextChannel, -// ChannelVerificationLevelIsTooHighForYouToGainAccess, -// OAuth2ApplicationDoesNotHaveABot, -// OAuth2ApplicationLimitReached, -// InvalidOAuth2State, -// YouLackPermissionsToPerformThatAction, -// InvalidAuthenticationTokenProvided, -// NoteWasTooLong, -// ProvidedTooFewOrTooManyMessagesToDeleteMustProvideAtLeast2AndFewerThan100MessagesToDelete, -// InvalidMFALevel, -// AMessageCanOnlyBePinnedInTheChannelItWasSentIn = 50019, -// InviteCodeWasEitherInvalidOrTaken, -// CannotExecuteActionOnASystemMessage, -// CannotExecuteActionOnThisChannelType = 50024, -// InvalidOAuth2AccessTokenProvided, -// MissingRequiredOAuth2Scope, -// InvalidWebhookTokenProvided, -// InvalidRole, -// InvalidRecipients = 50033, -// AMessageProvidedWasTooOldToBulkDelete, -// /** Invalid form body (returned for both `application/json` and `multipart/form-data` bodies), or invalid `Content-Type` provided */ -// InvalidFormBodyOrContentTypeProvided, -// AnInviteWasAcceptedToAGuildTheApplicationsBotIsNotIn, -// InvalidActivityAction = 50039, -// InvalidApiVersionProvided = 50041, -// FileUploadedExceedsTheMaximumSize = 50045, -// InvalidFileUploaded, -// CannotSelfRedeemThisGift = 50054, -// InvalidGuild, -// InvalidMessageType = 50068, -// PaymentSourceRequiredToRedeemGift = 50070, -// CannotDeleteAChannelRequiredForCommunityGuilds = 50074, -// CannotEditStickersWithinAMessage = 50080, -// InvalidStickerSent, -// TriedToPerformAnOperationOnAnArchivedThreadSuchAsEditingAMessageOrAddingAUserToTheThread = 50083, -// InvalidThreadNotificationSettings, -// BeforeValueIsEarlierThanTheThreadCreationDate, -// CommunityServerChannelsMustBeTextChannels, -// ThisServerIsNotAvailableInYourLocation = 50095, -// ThisServerNeedsMonetizationEnabledInOrderToPerformThisAction = 50097, -// ThisServerNeedsMoreBoostsToPerformThisAction = 50101, -// TheRequestBodyContainsInvalidJSON = 50109, -// OwnershipCannotBeTransferredToABotUser = 50132, -// FailedToResizeAssetBelowTheMaximumSize = 50138, -// UploadedFileNotFound = 50146, -// TwoFactorIsRequiredForThisOperation = 60003, -// NoUsersWithDiscordTagExist = 80004, -// ReactionWasBlocked = 90001, -// ApplicationNotYetAvailable = 110001, -// ApiResourceIsCurrentlyOverloadedTryAgainALittleLater = 130000, -// TheStageIsAlreadyOpen = 150006, -// CannotReplyWithoutPermissionToReadMessageHistory = 160002, -// AThreadHasAlreadyBeenCreatedForThisMessage = 160004, -// ThreadIsLocked = 160005, -// MaximumNumberOfActiveThreadsReached = 160006, -// MaximumNumberOfActiveAnnouncementThreadsReached = 160007, -// InvalidJsonForUploadedLottieFile = 170001, -// UploadedLottiesCannotContainRasterizedImagesSuchAsPngOrJpeg, -// StickerMaximumFramerateExceeded, -// StickerFrameCountExceedsMaximumOf1000Frames, -// LottieAnimationMaximumDimensionsExceeded, -// StickerFrameRateIsEitherTooSmallOrTooLarge, -// StickerAnimationDurationExceedsMaximumOf5Seconds, -// CannotUpdateAFinishedEvent = 180000, -// FailedToCreateStageNeededForStageEvent = 180002, -// MessageWasBlockedByAutomaticModeration = 200000, -// TitleWasBlockedByAutomaticModeration, -// WebhooksCanOnlyCreateThreadsInForumChannels = 220003, -// } - -// /** https://discord.com/developers/docs/topics/opcodes-and-status-codes#http */ -// export enum HTTPResponseCodes { -// /** The request completed successfully. */ -// Ok = 200, -// /** The entity was created successfully. */ -// Created, -// /** The request completed successfully but returned no content. */ -// NoContent = 204, -// /** The entity was not modified (no action was taken). */ -// NotModified = 304, -// /** The request was improperly formatted, or the server couldn't understand it. */ -// BadRequest = 400, -// /** The `Authorization` header was missing or invalid. */ -// Unauthorized, -// /** The `Authorization` token you passed did not have permission to the resource. */ -// Forbidden = 403, -// /** The resource at the location specified doesn't exist. */ -// NotFound, -// /** The HTTP method used is not valid for the location specified. */ -// MethodNotAllowed, -// /** You are being rate limited, see [Rate Limits](https://discord.com/developers/docs/topics/rate-limits). */ -// TooManyRequests = 429, -// /** There was not a gateway available to process your request. Wait a bit and retry. */ -// GatewayUnavailable = 502, -// } - /** https://discord.com/developers/docs/topics/opcodes-and-status-codes#opcodes-and-status-codes */ export enum GatewayCloseEventCodes { /** A normal closure of the gateway. You may attempt to reconnect. */ @@ -1008,12 +657,6 @@ export enum GatewayCloseEventCodes { DisallowedIntents, } -// /** https://discord.com/developers/docs/resources/invite#invite-object-invite-target-types */ -// export enum InviteTargetTypes { -// Stream = 1, -// EmbeddedApplication, -// } - /** https://discord.com/developers/docs/topics/opcodes-and-status-codes#gateway-gateway-opcodes */ export enum GatewayOpcodes { /** An event was dispatched. */ @@ -1227,8 +870,6 @@ export enum GatewayIntents { AutoModerationExecution = 1 << 21, } -// ALIASES JUST FOR BETTER UX IN THIS CASE - /** https://discord.com/developers/docs/topics/gateway#list-of-intents */ export const Intents = GatewayIntents @@ -1266,129 +907,6 @@ export type ImageFormat = 'jpg' | 'jpeg' | 'png' | 'webp' | 'gif' | 'json' /** https://discord.com/developers/docs/reference#image-formatting */ export type ImageSize = 16 | 32 | 64 | 128 | 256 | 512 | 1024 | 2048 | 4096 -// export enum Errors { -// // Bot Role errors -// BOTS_HIGHEST_ROLE_TOO_LOW = 'BOTS_HIGHEST_ROLE_TOO_LOW', -// // Channel Errors -// CHANNEL_NOT_FOUND = 'CHANNEL_NOT_FOUND', -// CHANNEL_NOT_IN_GUILD = 'CHANNEL_NOT_IN_GUILD', -// CHANNEL_NOT_TEXT_BASED = 'CHANNEL_NOT_TEXT_BASED', -// CHANNEL_NOT_STAGE_VOICE = 'CHANNEL_NOT_STAGE_VOICE', -// MESSAGE_MAX_LENGTH = 'MESSAGE_MAX_LENGTH', -// RULES_CHANNEL_CANNOT_BE_DELETED = 'RULES_CHANNEL_CANNOT_BE_DELETED', -// UPDATES_CHANNEL_CANNOT_BE_DELETED = 'UPDATES_CHANNEL_CANNOT_BE_DELETED', -// INVALID_TOPIC_LENGTH = 'INVALID_TOPIC_LENGTH', -// // Guild Errors -// GUILD_NOT_DISCOVERABLE = 'GUILD_NOT_DISCOVERABLE', -// GUILD_WIDGET_NOT_ENABLED = 'GUILD_WIDGET_NOT_ENABLED', -// GUILD_NOT_FOUND = 'GUILD_NOT_FOUND', -// MEMBER_NOT_FOUND = 'MEMBER_NOT_FOUND', -// MEMBER_NOT_IN_VOICE_CHANNEL = 'MEMBER_NOT_IN_VOICE_CHANNEL', -// MEMBER_SEARCH_LIMIT_TOO_HIGH = 'MEMBER_SEARCH_LIMIT_TOO_HIGH', -// MEMBER_SEARCH_LIMIT_TOO_LOW = 'MEMBER_SEARCH_LIMIT_TOO_LOW', -// PRUNE_MAX_DAYS = 'PRUNE_MAX_DAYS', -// ROLE_NOT_FOUND = 'ROLE_NOT_FOUND', -// // Thread errors -// INVALID_THREAD_PARENT_CHANNEL_TYPE = 'INVALID_THREAD_PARENT_CHANNEL_TYPE', -// GUILD_NEWS_CHANNEL_ONLY_SUPPORT_PUBLIC_THREADS = 'GUILD_NEWS_CHANNEL_ONLY_SUPPORT_PUBLIC_THREADS', -// NOT_A_THREAD_CHANNEL = 'NOT_A_THREAD_CHANNEL', -// MISSING_MANAGE_THREADS_AND_NOT_MEMBER = 'MISSING_MANAGE_THREADS_AND_NOT_MEMBER', -// CANNOT_GET_MEMBERS_OF_AN_UNJOINED_PRIVATE_THREAD = 'CANNOT_GET_MEMBERS_OF_AN_UNJOINED_PRIVATE_THREAD', -// HAVE_TO_BE_THE_CREATOR_OF_THE_THREAD_OR_HAVE_MANAGE_THREADS_TO_REMOVE_MEMBERS = 'HAVE_TO_BE_THE_CREATOR_OF_THE_THREAD_OR_HAVE_MANAGE_THREADS_TO_REMOVE_MEMBERS', -// // Message Get Errors -// INVALID_GET_MESSAGES_LIMIT = 'INVALID_GET_MESSAGES_LIMIT', -// // Message Delete Errors -// DELETE_MESSAGES_MIN = 'DELETE_MESSAGES_MIN', -// PRUNE_MIN_DAYS = 'PRUNE_MIN_DAYS', -// // Interaction Errors -// INVALID_SLASH_DESCRIPTION = 'INVALID_SLASH_DESCRIPTION', -// INVALID_SLASH_NAME = 'INVALID_SLASH_NAME', -// INVALID_SLASH_OPTIONS = 'INVALID_SLASH_OPTIONS', -// INVALID_SLASH_OPTIONS_CHOICES = 'INVALID_SLASH_OPTIONS_CHOICES', -// TOO_MANY_SLASH_OPTIONS = 'TOO_MANY_SLASH_OPTIONS', -// INVALID_SLASH_OPTION_CHOICE_NAME = 'INVALID_SLASH_OPTION_CHOICE_NAME', -// INVALID_SLASH_OPTIONS_CHOICE_VALUE_TYPE = 'INVALID_SLASH_OPTIONS_CHOICE_VALUE_TYPE', -// TOO_MANY_SLASH_OPTION_CHOICES = 'TOO_MANY_SLASH_OPTION_CHOICES', -// ONLY_STRING_OR_INTEGER_OPTIONS_CAN_HAVE_CHOICES = 'ONLY_STRING_OR_INTEGER_OPTIONS_CAN_HAVE_CHOICES', -// INVALID_SLASH_OPTION_NAME = 'INVALID_SLASH_OPTION_NAME', -// INVALID_SLASH_OPTION_DESCRIPTION = 'INVALID_SLASH_OPTION_DESCRIPTION', -// INVALID_CONTEXT_MENU_COMMAND_NAME = 'INVALID_CONTEXT_MENU_COMMAND_NAME', -// INVALID_CONTEXT_MENU_COMMAND_DESCRIPTION = 'INVALID_CONTEXT_MENU_COMMAND_DESCRIPTION', -// // Webhook Errors -// INVALID_WEBHOOK_NAME = 'INVALID_WEBHOOK_NAME', -// INVALID_WEBHOOK_OPTIONS = 'INVALID_WEBHOOK_OPTIONS', -// // Permission Errors -// MISSING_ADD_REACTIONS = 'MISSING_ADD_REACTIONS', -// MISSING_ADMINISTRATOR = 'MISSING_ADMINISTRATOR', -// MISSING_ATTACH_FILES = 'MISSING_ATTACH_FILES', -// MISSING_BAN_MEMBERS = 'MISSING_BAN_MEMBERS', -// MISSING_CHANGE_NICKNAME = 'MISSING_CHANGE_NICKNAME', -// MISSING_CONNECT = 'MISSING_CONNECT', -// MISSING_CREATE_INSTANT_INVITE = 'MISSING_CREATE_INSTANT_INVITE', -// MISSING_DEAFEN_MEMBERS = 'MISSING_DEAFEN_MEMBERS', -// MISSING_EMBED_LINKS = 'MISSING_EMBED_LINKS', -// MISSING_INTENT_GUILD_MEMBERS = 'MISSING_INTENT_GUILD_MEMBERS', -// MISSING_KICK_MEMBERS = 'MISSING_KICK_MEMBERS', -// MISSING_MANAGE_CHANNELS = 'MISSING_MANAGE_CHANNELS', -// MISSING_MANAGE_EMOJIS = 'MISSING_MANAGE_EMOJIS', -// MISSING_MANAGE_GUILD = 'MISSING_MANAGE_GUILD', -// MISSING_MANAGE_MESSAGES = 'MISSING_MANAGE_MESSAGES', -// MISSING_MANAGE_NICKNAMES = 'MISSING_MANAGE_NICKNAMES', -// MISSING_MANAGE_ROLES = 'MISSING_MANAGE_ROLES', -// MISSING_MANAGE_WEBHOOKS = 'MISSING_MANAGE_WEBHOOKS', -// MISSING_MENTION_EVERYONE = 'MISSING_MENTION_EVERYONE', -// MISSING_MOVE_MEMBERS = 'MISSING_MOVE_MEMBERS', -// MISSING_MUTE_MEMBERS = 'MISSING_MUTE_MEMBERS', -// MISSING_PRIORITY_SPEAKER = 'MISSING_PRIORITY_SPEAKER', -// MISSING_READ_MESSAGE_HISTORY = 'MISSING_READ_MESSAGE_HISTORY', -// MISSING_SEND_MESSAGES = 'MISSING_SEND_MESSAGES', -// MISSING_SEND_TTS_MESSAGES = 'MISSING_SEND_TTS_MESSAGES', -// MISSING_SPEAK = 'MISSING_SPEAK', -// MISSING_STREAM = 'MISSING_STREAM', -// MISSING_USE_VAD = 'MISSING_USE_VAD', -// MISSING_USE_EXTERNAL_EMOJIS = 'MISSING_USE_EXTERNAL_EMOJIS', -// MISSING_VIEW_AUDIT_LOG = 'MISSING_VIEW_AUDIT_LOG', -// MISSING_VIEW_CHANNEL = 'MISSING_VIEW_CHANNEL', -// MISSING_VIEW_GUILD_INSIGHTS = 'MISSING_VIEW_GUILD_INSIGHTS', -// // User Errors -// NICKNAMES_MAX_LENGTH = 'NICKNAMES_MAX_LENGTH', -// USERNAME_INVALID_CHARACTER = 'USERNAME_INVALID_CHARACTER', -// USERNAME_INVALID_USERNAME = 'USERNAME_INVALID_USERNAME', -// USERNAME_MAX_LENGTH = 'USERNAME_MAX_LENGTH', -// USERNAME_MIN_LENGTH = 'USERNAME_MIN_LENGTH', -// NONCE_TOO_LONG = 'NONCE_TOO_LONG', -// INVITE_MAX_AGE_INVALID = 'INVITE_MAX_AGE_INVALID', -// INVITE_MAX_USES_INVALID = 'INVITE_MAX_USES_INVALID', -// // API Errors -// RATE_LIMIT_RETRY_MAXED = 'RATE_LIMIT_RETRY_MAXED', -// REQUEST_CLIENT_ERROR = 'REQUEST_CLIENT_ERROR', -// REQUEST_SERVER_ERROR = 'REQUEST_SERVER_ERROR', -// REQUEST_UNKNOWN_ERROR = 'REQUEST_UNKNOWN_ERROR', -// // Component Errors -// TOO_MANY_COMPONENTS = 'TOO_MANY_COMPONENTS', -// TOO_MANY_ACTION_ROWS = 'TOO_MANY_ACTION_ROWS', -// LINK_BUTTON_CANNOT_HAVE_CUSTOM_ID = 'LINK_BUTTON_CANNOT_HAVE_CUSTOM_ID', -// COMPONENT_LABEL_TOO_BIG = 'COMPONENT_LABEL_TOO_BIG', -// COMPONENT_CUSTOM_ID_TOO_BIG = 'COMPONENT_CUSTOM_ID_TOO_BIG', -// BUTTON_REQUIRES_CUSTOM_ID = 'BUTTON_REQUIRES_CUSTOM_ID', -// COMPONENT_SELECT_MUST_BE_ALONE = 'COMPONENT_SELECT_MUST_BE_ALONE', -// COMPONENT_PLACEHOLDER_TOO_BIG = 'COMPONENT_PLACEHOLDER_TOO_BIG', -// COMPONENT_SELECT_MIN_VALUE_TOO_LOW = 'COMPONENT_SELECT_MIN_VALUE_TOO_LOW', -// COMPONENT_SELECT_MIN_VALUE_TOO_MANY = 'COMPONENT_SELECT_MIN_VALUE_TOO_MANY', -// COMPONENT_SELECT_MAX_VALUE_TOO_LOW = 'COMPONENT_SELECT_MAX_VALUE_TOO_LOW', -// COMPONENT_SELECT_MAX_VALUE_TOO_MANY = 'COMPONENT_SELECT_MAX_VALUE_TOO_MANY', -// COMPONENT_SELECT_OPTIONS_TOO_LOW = 'COMPONENT_SELECT_OPTIONS_TOO_LOW', -// COMPONENT_SELECT_OPTIONS_TOO_MANY = 'COMPONENT_SELECT_OPTIONS_TOO_MANY', -// SELECT_OPTION_LABEL_TOO_BIG = 'SELECT_OPTION_LABEL_TOO_BIG', -// SELECT_OPTION_VALUE_TOO_BIG = 'SELECT_OPTION_VALUE_TOO_BIG', -// SELECT_OPTION_TOO_MANY_DEFAULTS = 'SELECT_OPTION_TOO_MANY_DEFAULTS', -// COMPONENT_SELECT_MIN_HIGHER_THAN_MAX = 'COMPONENT_SELECT_MIN_HIGHER_THAN_MAX', -// CANNOT_ADD_USER_TO_ARCHIVED_THREADS = 'CANNOT_ADD_USER_TO_ARCHIVED_THREADS', -// CANNOT_LEAVE_ARCHIVED_THREAD = 'CANNOT_LEAVE_ARCHIVED_THREAD', -// CANNOT_REMOVE_FROM_ARCHIVED_THREAD = 'CANNOT_REMOVE_FROM_ARCHIVED_THREAD', -// YOU_CAN_NOT_DM_THE_BOT_ITSELF = 'YOU_CAN_NOT_DM_THE_BOT_ITSELF', -// } - export enum Locales { Danish = 'da', German = 'de', @@ -1424,15 +942,9 @@ export enum Locales { export type Localization = Partial> -// UTILS - -export type AtLeastOne }> = Partial & -U[keyof U] - -// export type MakeRequired = T & { [P in K]-?: T[P] } - +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 Capitalize ? "_" : ""}${Lowercase}${SnakeCase}` : S +export type SnakeCase = S extends `${infer T}${infer U}` ? `${T extends Capitalize ? '_' : ''}${Lowercase}${SnakeCase}` : S export type Camelize = T extends any[] ? T extends Array> @@ -1442,7 +954,7 @@ export type Camelize = T extends any[] ? { [K in keyof T as CamelCase]: Camelize } : T - export type Snakelize = T extends any[] +export type Snakelize = T extends any[] ? T extends Array> ? Array> : T @@ -1450,91 +962,4 @@ export type Camelize = T extends any[] ? { [K in keyof T as SnakeCase]: Snakelize } : T -// /** Non object primitives */ -// export type Primitive = -// | string -// | number -// | symbol -// | bigint -// | boolean -// | undefined -// | null -// // | object <- don't make object a primitive - -// /** -// * alternative to 'object' or '{}' -// * @example: -// * export const o: ObjectLiteral = [] as object; // error -// * export const o: object = []; // no error -// */ -// export type ObjectLiteral = { -// [K in PropertyKey]: T; -// } - -// /** Array with no utilty methods, aka Object.create(null) */ -// export interface ArrayWithNoPrototype { -// [index: number]: T | ArrayWithNoPrototype -// } - -// /** -// * Allows any type but T -// * it is recursive -// * @example -// * export type RequestData = Record>; -// */ -// export type AnythingBut = Exclude< -// | Primitive -// | { -// [K in PropertyKey]: AnythingBut; -// } -// | ArrayWithNoPrototype< -// | Primitive -// | { -// [K in PropertyKey]: AnythingBut; -// } -// >, -// T -// > - -// /** -// * object identity type -// */ -// export type Id = T extends infer U -// ? { -// [K in keyof U]: U[K]; -// } -// : never - -// export type KeysWithUndefined = { -// [K in keyof T]-?: undefined extends T[K] ? K : null extends T[K] ? K : never; -// }[keyof T] - -// type OptionalizeAux = Id< -// { -// [K in KeysWithUndefined]?: Optionalize; -// } & { -// [K in Exclude>]: T[K] extends ObjectLiteral -// ? Optionalize -// : T[K]; -// } -// > - -// /** -// * Makes all of properties in T optional when they're null | undefined -// * it is recursive -// */ -// export type Optionalize = T extends object -// ? T extends unknown[] -// ? number extends T['length'] -// ? T[number] extends object -// ? Array> -// : T -// : Partial -// : OptionalizeAux -// : T - export type PickPartial = { [P in keyof T]?: T[P] | undefined } & { [P in K]: T[P] } - -// export type OmitFirstFnArg = F extends (x: any, ...args: infer P) => infer R -// ? (...args: P) => R -// : never diff --git a/packages/utils/README.md b/packages/utils/README.md index 961c5a7de..3c7dfe717 100644 --- a/packages/utils/README.md +++ b/packages/utils/README.md @@ -103,28 +103,24 @@ Have your cache setup in any way you like. Redis, PGSQL or any cache layer you w Here is a minimal example to get started with: ```typescript -import { - createBot, - Intents, - startBot, -} from "https://deno.land/x/discordeno@13.0.0/mod.ts"; +import { createBot, Intents, startBot } from 'https://deno.land/x/discordeno@13.0.0/mod.ts' const bot = createBot({ token: process.env.DISCORD_TOKEN, intents: Intents.Guilds | Intents.GuildMessages, events: { ready() { - console.log("Successfully connected to gateway"); + console.log('Successfully connected to gateway') }, }, -}); +}) // Another way to do events bot.events.messageCreate = function (b, message) { // Process the message here with your command handler. -}; +} -await startBot(bot); +await startBot(bot) ``` ### Tools diff --git a/packages/utils/src/casing.ts b/packages/utils/src/casing.ts index 8ae88efb3..7164e2eb7 100644 --- a/packages/utils/src/casing.ts +++ b/packages/utils/src/casing.ts @@ -1,4 +1,4 @@ -import type { Camelize, Snakelize } from '@discordeno/types'; +import type { Camelize, Snakelize } from '@discordeno/types' export const camelize = (object: T): Camelize => { if (Array.isArray(object)) { @@ -16,7 +16,6 @@ export const camelize = (object: T): Camelize => { return object as Camelize } - export const snakelize = (object: T): Snakelize => { if (Array.isArray(object)) { return object.map((element) => snakelize(element)) as Snakelize @@ -25,7 +24,7 @@ export const snakelize = (object: T): Snakelize => { if (typeof object === 'object' && object !== null) { const obj = {} as Snakelize ;(Object.keys(object) as Array).forEach((key) => { - // @ts-expect-error js hack + // @ts-expect-error js hack ;(obj[typeof key === 'string' ? camelToSnakeCase(key) : key] as Snakelize<(T & object)[keyof T]>) = snakelize(object[key]) }) @@ -52,16 +51,16 @@ export function snakeToCamelCase(str: string): string { } 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()}`; + if (str[i] >= 'A' && str[i] <= 'Z') { + 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 bacd80395..17a100856 100644 --- a/packages/utils/src/colors.ts +++ b/packages/utils/src/colors.ts @@ -5,22 +5,22 @@ // on npm. // https://deno.land/std@0.153.0/fmt/colors.ts?source -const noColor = false; +const noColor = false -interface Code { - open: string; - close: string; - regexp: RegExp; +export interface Code { + open: string + close: string + regexp: RegExp } /** RGB 8-bits per channel. Each in range `0->255` or `0x00->0xff` */ -interface Rgb { - r: number; - g: number; - b: number; +export interface Rgb { + r: number + g: number + b: number } -let enabled = !noColor; +let enabled = !noColor /** * Set changing text color to enabled or disabled @@ -28,15 +28,15 @@ let enabled = !noColor; */ export function setColorEnabled(value: boolean) { if (noColor) { - return; + return } - enabled = value; + enabled = value } /** Get whether text color change is enabled or disabled. */ export function getColorEnabled(): boolean { - return enabled; + return enabled } /** @@ -46,10 +46,10 @@ export function getColorEnabled(): boolean { */ function code(open: number[], close: number): Code { return { - open: `\x1b[${open.join(";")}m`, + open: `\x1b[${open.join(';')}m`, close: `\x1b[${close}m`, - regexp: new RegExp(`\\x1b\\[${close}m`, "g"), - }; + regexp: new RegExp(`\\x1b\\[${close}m`, 'g'), + } } /** @@ -58,9 +58,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 } /** @@ -68,7 +66,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)) } /** @@ -76,7 +74,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)) } /** @@ -84,7 +82,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)) } /** @@ -92,7 +90,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)) } /** @@ -100,7 +98,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)) } /** @@ -108,7 +106,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)) } /** @@ -116,7 +114,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)) } /** @@ -124,7 +122,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)) } /** @@ -132,7 +130,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)) } /** @@ -140,7 +138,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)) } /** @@ -148,7 +146,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)) } /** @@ -156,7 +154,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)) } /** @@ -164,7 +162,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)) } /** @@ -172,7 +170,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)) } /** @@ -180,7 +178,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)) } /** @@ -188,7 +186,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)) } /** @@ -196,7 +194,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) } /** @@ -204,7 +202,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)) } /** @@ -212,7 +210,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)) } /** @@ -220,7 +218,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)) } /** @@ -228,7 +226,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)) } /** @@ -236,7 +234,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)) } /** @@ -244,7 +242,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)) } /** @@ -252,7 +250,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)) } /** @@ -260,7 +258,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)) } /** @@ -268,7 +266,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)) } /** @@ -276,7 +274,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)) } /** @@ -284,7 +282,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)) } /** @@ -292,7 +290,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)) } /** @@ -300,7 +298,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)) } /** @@ -308,7 +306,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)) } /** @@ -316,7 +314,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)) } /** @@ -324,7 +322,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)) } /** @@ -332,7 +330,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)) } /** @@ -340,7 +338,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)) } /** @@ -348,7 +346,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)) } /** @@ -356,7 +354,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)) } /** @@ -364,7 +362,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)) } /** @@ -372,7 +370,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)) } /** @@ -380,7 +378,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)) } /** @@ -388,7 +386,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 */ @@ -400,7 +398,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)) } /** @@ -410,7 +408,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)) } /** @@ -420,7 +418,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)) } /** @@ -439,28 +437,10 @@ export function bgRgb8(str: string, color: number): string { * @param color code */ 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, - ), - ); + 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, - 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)) } /** @@ -479,43 +459,25 @@ export function rgb24(str: string, color: number | Rgb): string { * @param color code */ 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, - ), - ); + 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, - 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 const ANSI_PATTERN = new RegExp( [ - "[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)", - "(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))", - ].join("|"), - "g", -); + '[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)', + '(?:(?:\\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, ""); -} \ No newline at end of file + return string.replace(ANSI_PATTERN, '') +} diff --git a/packages/utils/src/files.ts b/packages/utils/src/files.ts index ae9076ad1..6c6ffe5a9 100644 --- a/packages/utils/src/files.ts +++ b/packages/utils/src/files.ts @@ -1,5 +1,5 @@ -import type { FileContent } from "@discordeno/types" -import { decode } from "./base64.js" +import type { FileContent } from '@discordeno/types' +import { decode } from './base64.js' export function findFiles(file: unknown): FileContent[] { if (!file) { diff --git a/packages/utils/src/hash.ts b/packages/utils/src/hash.ts index 2b8421eaf..68df5ee7f 100644 --- a/packages/utils/src/hash.ts +++ b/packages/utils/src/hash.ts @@ -1,4 +1,4 @@ -export function iconHashToBigInt (hash: string): bigint { +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` @@ -11,7 +11,7 @@ export function iconHashToBigInt (hash: string): bigint { return BigInt(`0x${hash}`) } -export function iconBigintToHash (icon: bigint): string { +export function iconBigintToHash(icon: bigint): string { // Convert the bigint back to a hash const hash = icon.toString(16) // Hashes starting with a are animated and with b are not so need to handle that diff --git a/packages/utils/src/images.ts b/packages/utils/src/images.ts index 830fb083c..6ecc7854c 100644 --- a/packages/utils/src/images.ts +++ b/packages/utils/src/images.ts @@ -81,16 +81,14 @@ export function guildIconUrl( options?: { size?: ImageSize format?: ImageFormat - } + }, ): string | undefined { return imageHash ? formatImageUrl( - `https://cdn.discordapp.com/icons/${guildId}/${typeof imageHash === 'string' - ? imageHash - : iconBigintToHash(imageHash)}`, - options?.size ?? 128, - options?.format - ) + `https://cdn.discordapp.com/icons/${guildId}/${typeof imageHash === 'string' ? imageHash : iconBigintToHash(imageHash)}`, + options?.size ?? 128, + options?.format, + ) : undefined } @@ -108,16 +106,14 @@ export function guildSplashUrl( options?: { size?: ImageSize format?: ImageFormat - } + }, ): string | undefined { return imageHash ? formatImageUrl( - `https://cdn.discordapp.com/splashes/${guildId}/${typeof imageHash === 'string' - ? imageHash - : iconBigintToHash(imageHash)}`, - options?.size ?? 128, - options?.format - ) + `https://cdn.discordapp.com/splashes/${guildId}/${typeof imageHash === 'string' ? imageHash : iconBigintToHash(imageHash)}`, + options?.size ?? 128, + options?.format, + ) : undefined } @@ -128,10 +124,7 @@ export function guildSplashUrl( * @param options - The parameters for the building of the URL. * @returns The link to the resource. */ -export function getWidgetImageUrl ( - guildId: BigString, - options?: GetGuildWidgetImageQuery -): string { +export function getWidgetImageUrl(guildId: BigString, options?: GetGuildWidgetImageQuery): string { let url = `https://cdn.discordapp.com/guilds/${guildId}/widget.png` if (options?.style) { diff --git a/packages/utils/src/token.ts b/packages/utils/src/token.ts index 4cc0c51f7..ccc2c9a5a 100644 --- a/packages/utils/src/token.ts +++ b/packages/utils/src/token.ts @@ -1,15 +1,10 @@ import { Buffer } from 'node:buffer' /** Removes the Bot before the token. */ -export function removeTokenPrefix ( - token?: string, - type: 'GATEWAY' | 'REST' = 'REST' -): string { +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.`) } // If the token does not have a prefix just return token if (!token.startsWith('Bot ')) return token @@ -18,6 +13,6 @@ export function removeTokenPrefix ( } /** 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 { +export function getBotIdFromToken(token: string): bigint { return BigInt(Buffer.from(token.split('.')[0], 'base64').toString()) } diff --git a/packages/utils/src/utils.ts b/packages/utils/src/utils.ts index e02849adc..05288b892 100644 --- a/packages/utils/src/utils.ts +++ b/packages/utils/src/utils.ts @@ -12,10 +12,7 @@ export async function delay(ms: number): Promise { // 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 { +export function hasProperty(obj: T, prop: Y): obj is T & Record { // eslint-disable-next-line no-prototype-builtins return obj.hasOwnProperty(prop) } diff --git a/script/generateHandlerData.ts b/script/generateHandlerData.ts index 1df7c8227..db424f20a 100644 --- a/script/generateHandlerData.ts +++ b/script/generateHandlerData.ts @@ -1,38 +1,40 @@ const handlers: { - [index: string]: any; -} = {}; + [index: string]: any +} = {} -const topDirs = ["./handlers"]; +const topDirs = ['./handlers'] const readDir = async (dirname: string, onContent: (content: string) => void) => { - const files: Deno.DirEntry[] = []; + const files: Deno.DirEntry[] = [] for (const dirEntry of Deno.readDirSync(dirname)) { - files.push(dirEntry); + files.push(dirEntry) } await Promise.all( files.map(async (file) => { if (file.isFile) { - const content = await Deno.readTextFile(dirname + "/" + file.name); - onContent(content); - return; + const content = await Deno.readTextFile(dirname + '/' + file.name) + onContent(content) + return } - if (file.isDirectory) await readDir(`${dirname}/${file.name}`, onContent); + if (file.isDirectory) await readDir(`${dirname}/${file.name}`, onContent) }), - ); -}; + ) +} -await Promise.all(topDirs.map((topDir) => - readDir(topDir, (content) => { - const handler = content.match(/export function [A-z]+\(/g); - if (handler === null) return; - const transformers = content.match(/bot.transformers.[A-z]+\(/g); - const event = content.match(/bot.events.[A-z]+\(/); +await Promise.all( + topDirs.map((topDir) => + readDir(topDir, (content) => { + const handler = content.match(/export function [A-z]+\(/g) + if (handler === null) return + const transformers = content.match(/bot.transformers.[A-z]+\(/g) + const event = content.match(/bot.events.[A-z]+\(/) - handlers[handler.map((handler) => handler.slice(16, -1))[0]] = { - transformers: transformers === null ? [] : transformers.map((result) => result.slice(4, -1)), - event: event === null ? undefined : event.map((result) => result.slice(4, -1))[0], - }; - }) -)); + handlers[handler.map((handler) => handler.slice(16, -1))[0]] = { + transformers: transformers === null ? [] : transformers.map((result) => result.slice(4, -1)), + event: event === null ? undefined : event.map((result) => result.slice(4, -1))[0], + } + }), + ), +) -console.log(handlers); +console.log(handlers) diff --git a/scripts/finalizeTypedocs.js b/scripts/finalizeTypedocs.js index c1e823e1e..bc4ceaa89 100644 --- a/scripts/finalizeTypedocs.js +++ b/scripts/finalizeTypedocs.js @@ -15,33 +15,25 @@ async function* walk(dir) { } for await (let filepath of walk(typedocOutPath)) { + if (filepath.endsWith('.json')) continue + // if (filepath.includes('/generated/classes')) console.log('file in classes', filepath) + // if (filepath.includes('/generated/modules')) console.log('file in modules', filepath) let file = fs.readFileSync(filepath, 'utf-8') - // Removes the old file in case it had ugly name, will be recreated below - fs.rmSync(filepath); - if (filepath.endsWith('generated/README.md')) { file = [ - "discordeno-monorepo / [Modules](modules.md)", - "", - "# Discordeno", - "", - "Thank you for using Discordeno. These docs are generated automatically. If you see any issues please contact us on [Discord](https://discord.gg/ddeno)" - ].join('\n'); - filepath = filepath.replace("README", "Docs") + 'discordeno-monorepo / [Modules](modules.md)', + '', + '# Discordeno', + '', + 'Thank you for using Discordeno. These docs are generated automatically. If you see any issues please contact us on [Discord](https://discord.gg/ddeno)', + ].join('\n') + // console.log('renaming readme', filepath) + // filepath = filepath.replace("README", "Docs") } - // These files should be simply deleted. - const filesToDelete = [ - // "README", - // "modules" - ]; - let deleted = false; - for (const filename of filesToDelete) { - if (filepath.endsWith(`generated/${filename}.md`)) deleted = true; - } - // Skip the rest if this file should be deleted - if (deleted) continue; + // Removes the old file in case it had ugly name, will be recreated below + fs.rmSync(filepath) // add all the words we need to replace here for invalid jsx errors const words = ['internal'] @@ -50,14 +42,35 @@ for await (let filepath of walk(typedocOutPath)) { } // Converts ugly names to clean names for example discordeno_types.ActionRow becomes ActionRow - const cleanForms = [{ ugly: 'discordeno_types.' }, { ugly: "discordeno_utils."}] + const cleanForms = [ + { ugly: 'discordeno_bot.' }, + { ugly: 'discordeno_client.' }, + { ugly: 'discordeno_gateway.' }, + { ugly: 'discordeno_rest.' }, + { ugly: 'discordeno_types.' }, + { ugly: 'discordeno_utils.' }, + ] for (const form of cleanForms) { - // Clean the file of the ugly forms - file = file.replace(new RegExp(form.ugly, 'gi'), form.clean || '') - const lastIndex = filepath.lastIndexOf("/") - // Clean the file name of the ugly forms - filepath = filepath.replace(new RegExp(form.ugly, 'gi'), form.clean || '') + // Clean the file of the ugly forms + file = file.replace(new RegExp(form.ugly, 'gi'), form.clean || '') + const lastIndex = filepath.lastIndexOf('/') + // Clean the file name of the ugly forms + if (!filepath.endsWith(`${form.ugly}md`)) filepath = filepath.replace(new RegExp(form.ugly, 'gi'), form.clean || '') + } + + file = file.replace(/Promise<([^>]+)>/gi, 'Promise{$1}') + + if (file.includes('Promise<')) console.log('Removing Promise< failed') + + if (filepath.endsWith('/md')) { + filepath = filepath.replace('/md', '/README.md') + } + + // if (filepath.includes('/generated/classes')) console.log('file in classes 2', filepath) + if (filepath.includes('/generated/modules/discordeno_')) { + const mod = filepath.substring(filepath.lastIndexOf('_') + 1) + filepath = filepath.substring(0, filepath.lastIndexOf('/')) + `/${mod[0].toUpperCase()}${mod.substring(1)}` } fs.writeFileSync(filepath, file, function (err, result) { diff --git a/site/docs/amethyst/exampleBot.md b/site/docs/amethyst/exampleBot.md index 8dd89659e..74424ff5f 100644 --- a/site/docs/amethyst/exampleBot.md +++ b/site/docs/amethyst/exampleBot.md @@ -17,54 +17,47 @@ npm i @thereallonewolf/amethystframework - **Step 4**: Add following code in index.ts file, replacing TOKEN with your bot token. ```ts -import { createBot, GatewayIntents, startBot } from "discordeno"; -import { enableCachePlugin, enableCacheSweepers } from "discordeno/cache-plugin"; -import { - AmethystBot, - Category, - Command, - Context, - enableAmethystPlugin, - Event, -} from "@thereallonewolf/amethystframework"; +import { createBot, GatewayIntents, startBot } from 'discordeno' +import { enableCachePlugin, enableCacheSweepers } from 'discordeno/cache-plugin' +import { AmethystBot, Category, Command, Context, enableAmethystPlugin, Event } from '@thereallonewolf/amethystframework' let baseClient = createBot({ - token: "TOKEN", + token: 'TOKEN', intents: GatewayIntents.Guilds | GatewayIntents.GuildMessages | GatewayIntents.MessageContent, -}); +}) //@ts-ignore let client = enableAmethystPlugin(enableCachePlugin(baseClient), { botMentionAsPrefix: true, - prefix: "!", //Can be a function or a string. + prefix: '!', //Can be a function or a string. ignoreBots: false, -}); -enableCacheSweepers(client); +}) +enableCacheSweepers(client) -startBot(client); +startBot(client) @Category({ - name: "general", - description: "My general commands", + name: 'general', + description: 'My general commands', uniqueCommands: true, - default: "", //As all the commands are unique so no need to set the default command. + default: '', //As all the commands are unique so no need to set the default command. }) export class General { @Command({ - name: "ping", - description: "Pong!", - commandType: ["application", "message"], - category: "general", + name: 'ping', + description: 'Pong!', + commandType: ['application', 'message'], + category: 'general', args: [], }) async ping(bot: AmethystBot, ctx: Context) { - ctx.reply({ content: "Pong!" }); + ctx.reply({ content: 'Pong!' }) } - @Event("ready") + @Event('ready') async ready() { - console.log("I am ready!"); - client.amethystUtils.updateSlashCommands(); + console.log('I am ready!') + client.amethystUtils.updateSlashCommands() } } ``` diff --git a/site/docs/big-bot-guide/cache.md b/site/docs/big-bot-guide/cache.md index da148767a..18302f8c0 100644 --- a/site/docs/big-bot-guide/cache.md +++ b/site/docs/big-bot-guide/cache.md @@ -80,15 +80,15 @@ Now we will initiate our cache service. This may be different for you based on y using PGSQL for our cache layer, we will now instantiate it. ```ts -import { postgres } from "../../../deps.ts"; +import { postgres } from '../../../deps.ts' // YOU CUSTOM PGSQL INFO GOES HERE -const DATABASE_USERNAME = ""; -const DATABASE_PASSWORD = ""; -const DATABASE_NAME = ""; -const DATABASE_HOST = ""; -const DATABASE_PORT = 8956; -const DATABASE_MAX = 20; +const DATABASE_USERNAME = '' +const DATABASE_PASSWORD = '' +const DATABASE_NAME = '' +const DATABASE_HOST = '' +const DATABASE_PORT = 8956 +const DATABASE_MAX = 20 export const psql = postgres({ username: DATABASE_USERNAME, @@ -103,14 +103,14 @@ export const psql = postgres({ types: { bigint: postgres.BigInt, }, -}); +}) ``` To use the PGSQL driver we are using in this guide you can insert this into your `deps.ts`. ```ts // @deno-types="https://denopkg.com/porsager/postgres@e2a8595d7aa8c3c838b83b9bca7b890c1707ad2c/types/index.d.ts" -export { default as postgres } from "https://denopkg.com/porsager/postgres@e2a8595d7aa8c3c838b83b9bca7b890c1707ad2c/deno/lib/index.js"; +export { default as postgres } from 'https://denopkg.com/porsager/postgres@e2a8595d7aa8c3c838b83b9bca7b890c1707ad2c/deno/lib/index.js' ``` > Note: Remember you can use any driver you like. For deno users we prefer to use this library for PGSQL because it is diff --git a/site/docs/big-bot-guide/events.md b/site/docs/big-bot-guide/events.md index 2abb18f3f..deceb7a38 100644 --- a/site/docs/big-bot-guide/events.md +++ b/site/docs/big-bot-guide/events.md @@ -24,9 +24,9 @@ reloaded instantly. Create a file path like `src/bot/mod.ts`. ```ts -import { DISCORD_TOKEN } from "../../configs.ts"; -import { Collection, createBot, Intents } from "../../deps.ts"; -import { psql } from "./cache/mod.ts"; +import { DISCORD_TOKEN } from '../../configs.ts' +import { Collection, createBot, Intents } from '../../deps.ts' +import { psql } from './cache/mod.ts' export const bot = createBot({ token: DISCORD_TOKEN, @@ -34,10 +34,10 @@ export const bot = createBot({ intents: Intents.Guilds | Intents.GuildMessages, events: { messageCreate: function (bot, message) { - console.log("message arrived"); + console.log('message arrived') }, }, -}); +}) ``` Alright that was a lot of code. Now let's break it down little by little. @@ -69,56 +69,36 @@ Here we'll have some basic functions to make use of the cache we created in step const cache = { /** Get a single item from the table */ async get(key) { - return await psql`SELECT * FROM ${ - psql( - tables[table], - ) - } WHERE "id" = ${psql.types.bigint(key)}`; + return await psql`SELECT * FROM ${psql(tables[table])} WHERE "id" = ${psql.types.bigint(key)}` }, /** Completely empty this table. */ async clear() { - await psql`TRUNCATE TABLE ${psql(tables[table])}`; + await psql`TRUNCATE TABLE ${psql(tables[table])}` }, /** Delete the data related to this key from table. */ async delete(key) { - await psql`DELETE FROM ${ - psql( - tables[table], - ) - } WHERE "id" = ${psql.types.bigint(key)}`; - return true; + await psql`DELETE FROM ${psql(tables[table])} WHERE "id" = ${psql.types.bigint(key)}` + return true }, /** Check if there is data assigned to this key. */ async has(key) { - return Boolean( - await psql`SELECT 1 FROM ${ - psql( - tables[table], - ) - } WHERE "id" = ${psql.types.bigint(key)}`, - ); + return Boolean(await psql`SELECT 1 FROM ${psql(tables[table])} WHERE "id" = ${psql.types.bigint(key)}`) }, /** Check how many items are stored in this table. */ async size() { - return (await psql`SELECT COUNT("id") FROM ${psql(tables[table])}`) - .count; + return (await psql`SELECT COUNT("id") FROM ${psql(tables[table])}`).count }, /** Store new data to this table. */ async set(key, data) { - await psql`INSERT INTO ${psql(tables[table])} ${ - psql( - data, - ...Object.keys(data), - ) - }`; - return true; + await psql`INSERT INTO ${psql(tables[table])} ${psql(data, ...Object.keys(data))}` + return true }, // THESE TWO ARE USELESS FOR CUSTOM CACHE BUT NEED TO SHUT UP TS ERRORS async forEach(callback) {}, async filter(callback) { - return new Collection(); + return new Collection() }, -}; +} ``` You can insert any code you desire for your cache system here. Since we were using PGSQL, we used sql queries to make @@ -146,47 +126,44 @@ below simply to keep code cleaner and simpler, in expectation that it will grow as you wish. ```ts -import { Bot } from "../../../deps.ts"; -import { customizeBotTransformers } from "./transformers/mod.ts"; +import { Bot } from '../../../deps.ts' +import { customizeBotTransformers } from './transformers/mod.ts' export function customizeBotInternals(bot: Bot) { - bot = customizeBotTransformers(bot); + bot = customizeBotTransformers(bot) // ADD AS MANY MORE CUSTOMIZATIONS HERE AS YOU LIKE TO HANDLERS, HELPERS, UTILS ETC... - return bot; + return bot } ``` We also need to add another file now at `src/bot/internals/transformers/mod.ts` ```ts -import { Bot } from "../../../../deps.ts"; -import { customizeUserTransformer } from "./user.ts"; +import { Bot } from '../../../../deps.ts' +import { customizeUserTransformer } from './user.ts' export function customizeBotTransformers(bot: Bot) { - bot = customizeUserTransformer(bot); + bot = customizeUserTransformer(bot) // ADD ANY MORE CUSTOM TRANSFORMERS HERE - return bot; + return bot } ``` One more file at `src/bot/internals/transformers/user.ts` ```ts -import { Bot, DiscordenoUser, transformUser } from "../../../../deps.ts"; +import { Bot, DiscordenoUser, transformUser } from '../../../../deps.ts' export function customizeUserTransformer(bot: Bot) { bot.transformers.user = function (bot, payload) { // REMOVE USELESS PROPS OUR BOT DOESNT USE - const { system, locale, verified, email, flags, mfaEnabled, premiumType, publicFlags, ...user } = transformUser( - bot, - payload, - ); + const { system, locale, verified, email, flags, mfaEnabled, premiumType, publicFlags, ...user } = transformUser(bot, payload) // RETURN ONLY USEFUL PROPS WE NEED TO USE AND CACHE IF NECESSARY - return user as DiscordenoUser; - }; + return user as DiscordenoUser + } - return bot; + return bot } ``` @@ -210,51 +187,51 @@ Create a file in a path like `src/bot/gatewayEventsListener.ts` Now we should create a http listener, check for authorization in headers, run `bot.events.raw` and `bot.handlers[event]` ```ts -import { DiscordGatewayPayload } from "discordeno"; -import { EVENT_HANDLER_PORT, REST_AUTHORIZATION } from "../../configs.ts"; +import { DiscordGatewayPayload } from 'discordeno' +import { EVENT_HANDLER_PORT, REST_AUTHORIZATION } from '../../configs.ts' -const server = Deno.listen({ port: EVENT_HANDLER_PORT }); +const server = Deno.listen({ port: EVENT_HANDLER_PORT }) // Connections to the server will be yielded up as an async iterable. for await (const conn of server) { // In order to not be blocking, we need to handle each connection individually // in its own async function. - handleRequest(conn); + handleRequest(conn) } async function handleRequest(conn: Deno.Conn) { // This "upgrades" a network connection into an HTTP connection. - const httpConn = Deno.serveHttp(conn); + const httpConn = Deno.serveHttp(conn) // Each request sent over the HTTP connection will be yielded as an async // iterator from the HTTP connection. for await (const requestEvent of httpConn) { - if (!REST_AUTHORIZATION || REST_AUTHORIZATION !== requestEvent.request.headers.get("AUTHORIZATION")) { + if (!REST_AUTHORIZATION || REST_AUTHORIZATION !== requestEvent.request.headers.get('AUTHORIZATION')) { return requestEvent.respondWith( - new Response(JSON.stringify({ error: "Invalid authorization key." }), { + new Response(JSON.stringify({ error: 'Invalid authorization key.' }), { status: 401, }), - ); + ) } const json = (await requestEvent.request.json()) as { - message: DiscordGatewayPayload; - shardId: number; - }; + message: DiscordGatewayPayload + shardId: number + } // Run raw event. - bot.events.raw(bot, json.message, json.shardId); + bot.events.raw(bot, json.message, json.shardId) - if (json.message.t && json.message.t !== "RESUMED") { + if (json.message.t && json.message.t !== 'RESUMED') { // When a guild or something isn't in cache this will fetch it before doing anything else. - if (!["READY", "GUILD_LOADED_DD"].includes(json.message.t)) { - await bot.events.dispatchRequirements(bot, json.message, json.shardId); + if (!['READY', 'GUILD_LOADED_DD'].includes(json.message.t)) { + await bot.events.dispatchRequirements(bot, json.message, json.shardId) } // Run event function provided in bot.events - bot.handlers[json.message.t]?.(bot, json.message, json.shardId); + bot.handlers[json.message.t]?.(bot, json.message, json.shardId) } - new Response(undefined, { status: 200 }); + new Response(undefined, { status: 200 }) } } ``` diff --git a/site/docs/big-bot-guide/gateway.md b/site/docs/big-bot-guide/gateway.md index 7f79dd954..5f76d30ed 100644 --- a/site/docs/big-bot-guide/gateway.md +++ b/site/docs/big-bot-guide/gateway.md @@ -61,14 +61,14 @@ Before, we dive into how, here is a quick summary of why you will want a standal Create a file under some path like `src/gateway/mod.ts`. ```ts -import { DISCORD_TOKEN, REST_AUTHORIZATION, REST_PORT } from "../../configs.ts"; -import { BASE_URL, createRestManager } from "../../deps.ts"; +import { DISCORD_TOKEN, REST_AUTHORIZATION, REST_PORT } from '../../configs.ts' +import { BASE_URL, createRestManager } from '../../deps.ts' const rest = createRestManager({ token: DISCORD_TOKEN, secretKey: REST_AUTHORIZATION, customUrl: `http://localhost:${REST_PORT}`, -}); +}) ``` Throw another rest manager here which will be responsible for calling the main REST process we created in Step 1. This @@ -84,16 +84,16 @@ Now we need to use this rest manager to call the api to get information about ho your bot. ```ts -import { routes } from "../../deps.ts"; +import { routes } from '../../deps.ts' const rest = createRestManager({ token: DISCORD_TOKEN, secretKey: REST_AUTHORIZATION, customUrl: `http://localhost:${REST_PORT}`, -}); +}) // CALL THE REST PROCESS TO GET GATEWAY DATA -const gatewayBot = await rest.runMethod(rest, "GET", routes.GATEWAY_BOT()).then((res) => ({ +const gatewayBot = await rest.runMethod(rest, 'GET', routes.GATEWAY_BOT()).then((res) => ({ url: res.url, shards: res.shards, sessionStartLimit: { @@ -102,7 +102,7 @@ const gatewayBot = await rest.runMethod(rest, "GET", routes.GATEWAY_BOT()).then( resetAfter: res.session_start_limit.reset_after, maxConcurrency: res.session_start_limit.max_concurrency, }, -})); +})) ``` With this info, we can now create our gateway manager. @@ -110,7 +110,7 @@ With this info, we can now create our gateway manager. ### Understanding Gateway Manager ```ts -import { INTENTS, SHARDS_PER_WORKER, TOTAL_WORKERS } from "../../configs.ts"; +import { INTENTS, SHARDS_PER_WORKER, TOTAL_WORKERS } from '../../configs.ts' const gateway = createGatewayManager({ gatewayBot, @@ -124,7 +124,7 @@ const gateway = createGatewayManager({ // debug: console.log, // THIS WILL BE USED LATER IN WORKER SO LEAVE IT HERE handleDiscordPayload: () => {}, -}); +}) ``` #### Basic Keys @@ -171,7 +171,7 @@ change the logic in any method it is as simple as: // TYPINGS WILL BE AUTOMATICALLY PROVIDED gateway.heartbeat = function (gateway, shardId, interval) { // YOUR CUSTOM HANDLING CODE HERE -}; +} ``` ## Workers @@ -188,20 +188,20 @@ to create workers and send message: ```ts gateway.tellWorkerToIdentify = async (_gateway, workerId, shardId, _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) } // TYPE TYPE WorkerMessage IS FROM WORKER FILE, DISCUSSED IN DETAIL BELOW const identify: WorkerMessage = { - type: "IDENTIFY_SHARD", + type: 'IDENTIFY_SHARD', shardId, - }; + } - worker.postMessage(identify); -}; + worker.postMessage(identify) +} ``` You can choose to replace the handler with any desired functionality you like. For example, should should you want to @@ -212,13 +212,13 @@ Now that we've setup our initial gateway manager and added `tellWorkerToIdentify of the work: creating workers, spawning shards etc. ```ts -import { EVENT_HANDLER_SECRET_KEY, EVENT_HANDLER_URL } from "../../configs.ts"; -import { Worker } from "worker_threads"; -import { WorkerCreateData, WorkerGetShardInfo, WorkerMessage, WorkerShardInfo, WorkerShardPayload } from "./worker.js"; +import { EVENT_HANDLER_SECRET_KEY, EVENT_HANDLER_URL } from '../../configs.ts' +import { Worker } from 'worker_threads' +import { WorkerCreateData, WorkerGetShardInfo, WorkerMessage, WorkerShardInfo, WorkerShardPayload } from './worker.js' // A COLLECTION OF WORKERS -const workers = new Collection(); -const nonces = new Collection void>(); +const workers = new Collection() +const nonces = new Collection void>() function createWorker(workerId: number) { const workerData: WorkerCreateData = { @@ -227,51 +227,51 @@ function createWorker(workerId: number) { // TODO: PUT THIS SEPARATELY. CAN USE MULTIPLE URLS IF YOU HAVE MULTIPLE BOT PROCESSES HANDLING DIFFERENT SHARDS' EVENTS handlerUrls: [EVENT_HANDLER_URL], handlerAuthorization: EVENT_HANDLER_SECRET_KEY, - path: "./worker.ts", + path: './worker.ts', totalShards: gateway.manager.totalShards, workerId, - }; + } - const worker = new Worker("./worker.js", { + const worker = new Worker('./worker.js', { workerData, - }); + }) - worker.on("message", async (data: ManagerMessage) => { + worker.on('message', async (data: ManagerMessage) => { switch (data.type) { - case "REQUEST_IDENTIFY": { - await gateway.manager.requestIdentify(data.shardId); + case 'REQUEST_IDENTIFY': { + await gateway.manager.requestIdentify(data.shardId) const allowIdentify: WorkerMessage = { - type: "ALLOW_IDENTIFY", + type: 'ALLOW_IDENTIFY', shardId: data.shardId, - }; + } - worker.postMessage(allowIdentify); + worker.postMessage(allowIdentify) - break; + break } - case "NONCE_REPLY": { - nonces.get(data.nonce)?.(data.data); + case 'NONCE_REPLY': { + nonces.get(data.nonce)?.(data.data) } } - }); + }) - return worker; + return worker } // TYPES WE USE -export type ManagerMessage = ManagerRequestIdentify | ManagerNonceReply; +export type ManagerMessage = ManagerRequestIdentify | ManagerNonceReply export type ManagerRequestIdentify = { - type: "REQUEST_IDENTIFY"; - shardId: number; -}; + type: 'REQUEST_IDENTIFY' + shardId: number +} export type ManagerNonceReply = { - type: "NONCE_REPLY"; - nonce: string; - data: T; -}; + type: 'NONCE_REPLY' + nonce: string + data: T +} ``` ## Spawning Shards @@ -279,7 +279,7 @@ export type ManagerNonceReply = { Once you are ready and the gateway has been created as you desired, we can begin spawning the shards. ```ts -gateway.spawnShards(gateway); +gateway.spawnShards(gateway) ``` This code now handles creating gateway manager, creating workers, spawning shards and sending the info to each workers. @@ -297,25 +297,25 @@ import { REST_PORT, SHARDS_PER_WORKER, TOTAL_WORKERS, -} from "../../configs.ts"; -import { BASE_URL, createRestManager, routes } from "../../deps.ts"; -import { Worker } from "worker_threads"; -import { WorkerCreateData, WorkerGetShardInfo, WorkerMessage, WorkerShardInfo, WorkerShardPayload } from "./worker.ts"; +} from '../../configs.ts' +import { BASE_URL, createRestManager, routes } from '../../deps.ts' +import { Worker } from 'worker_threads' +import { WorkerCreateData, WorkerGetShardInfo, WorkerMessage, WorkerShardInfo, WorkerShardPayload } from './worker.ts' const rest = createRestManager({ token: DISCORD_TOKEN, secretKey: REST_AUTHORIZATION, customUrl: `http://localhost:${REST_PORT}`, -}); +}) const rest = createRestManager({ token: DISCORD_TOKEN, secretKey: REST_AUTHORIZATION, customUrl: `http://localhost:${REST_PORT}`, -}); +}) // CALL THE REST PROCESS TO GET GATEWAY DATA -const gatewayBot = await rest.runMethod(rest, "GET", routes.GATEWAY_BOT()).then((res) => ({ +const gatewayBot = await rest.runMethod(rest, 'GET', routes.GATEWAY_BOT()).then((res) => ({ url: res.url, shards: res.shards, sessionStartLimit: { @@ -324,7 +324,7 @@ const gatewayBot = await rest.runMethod(rest, "GET", routes.GATEWAY_BOT()).then( resetAfter: res.session_start_limit.reset_after, maxConcurrency: res.session_start_limit.max_concurrency, }, -})); +})) const gateway = createGatewayManager({ gatewayBot, @@ -338,25 +338,25 @@ const gateway = createGatewayManager({ // debug: console.log, handleDiscordPayload: () => {}, tellWorkerToIdentify: async (_gateway, workerId, shardId, _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) } // TYPE TYPE WorkerMessage IS FROM WORKER FILE, DISCUSSED IN DETAIL BELOW const identify: WorkerMessage = { - type: "IDENTIFY_SHARD", + type: 'IDENTIFY_SHARD', shardId, - }; + } - worker.postMessage(identify); + worker.postMessage(identify) }, -}); +}) // A COLLECTION OF WORKERS -const workers = new Collection(); -const nonces = new Collection void>(); +const workers = new Collection() +const nonces = new Collection void>() function createWorker(workerId: number) { const workerData: WorkerCreateData = { @@ -364,54 +364,54 @@ function createWorker(workerId: number) { token: DISCORD_TOKEN, handlerUrls: [EVENT_HANDLER_URL], handlerAuthorization: EVENT_HANDLER_SECRET_KEY, - path: "./worker.ts", + path: './worker.ts', totalShards: gateway.manager.totalShards, workerId, - }; + } - const worker = new Worker("./worker.ts", { + const worker = new Worker('./worker.ts', { workerData, - }); + }) - worker.on("message", async (data: ManagerMessage) => { + worker.on('message', async (data: ManagerMessage) => { switch (data.type) { - case "REQUEST_IDENTIFY": { - await gateway.manager.requestIdentify(data.shardId); + case 'REQUEST_IDENTIFY': { + await gateway.manager.requestIdentify(data.shardId) const allowIdentify: WorkerMessage = { - type: "ALLOW_IDENTIFY", + type: 'ALLOW_IDENTIFY', shardId: data.shardId, - }; + } - worker.postMessage(allowIdentify); + worker.postMessage(allowIdentify) - break; + break } - case "NONCE_REPLY": { - nonces.get(data.nonce)?.(data.data); + case 'NONCE_REPLY': { + nonces.get(data.nonce)?.(data.data) } } - }); + }) - return worker; + return worker } // TYPES WE USE -export type ManagerMessage = ManagerRequestIdentify | ManagerNonceReply; +export type ManagerMessage = ManagerRequestIdentify | ManagerNonceReply export type ManagerRequestIdentify = { - type: "REQUEST_IDENTIFY"; - shardId: number; -}; + type: 'REQUEST_IDENTIFY' + shardId: number +} export type ManagerNonceReply = { - type: "NONCE_REPLY"; - nonce: string; - data: T; -}; + type: 'NONCE_REPLY' + nonce: string + data: T +} // SPAWN SHARDS INTO WORKERS -gateway.spawnShards(); +gateway.spawnShards() ``` ## Worker File @@ -424,17 +424,17 @@ Create a file in a path like `src/gateway/worker.ts`. Now we'll have to create a Shard Manager, this is what will handle identifying, receiving events. ```ts -import { createShardManager } from "discordeno"; -import { parentPort, workerData } from "worker_threads"; +import { createShardManager } from 'discordeno' +import { parentPort, workerData } from 'worker_threads' if (!parentPort) { - throw new Error("Parent port is null"); + throw new Error('Parent port is null') } // THE DATA WE GET FROM GATEWAY FILE -const script: WorkerCreateData = workerData; +const script: WorkerCreateData = workerData -const identifyPromises = new Map void>(); +const identifyPromises = new Map void>() const manager = createShardManager({ gatewayConfig: { @@ -446,7 +446,7 @@ const manager = createShardManager({ // WE WILL COVER THESE TWO FUNCTIONS IN LATER PART OF THE GUIDE, FOR NOW, LEAVE IT THIS WAY handleMessage: () => {}, requestIdentify: async () => {}, -}); +}) ``` The above code only creates a shard manager, we now have 3 more things to do: @@ -461,7 +461,7 @@ In order for the shards to receive events and send to bot process, we need to re first, we can do this by using `message` event in `parentPort` like shown below: ```ts -import { Shard } from "discordeno"; +import { Shard } from 'discordeno' function buildShardInfo(shard: Shard): WorkerShardInfo { return { @@ -469,84 +469,84 @@ function buildShardInfo(shard: Shard): WorkerShardInfo { shardId: shard.id, rtt: shard.heart.rtt || -1, state: shard.state, - }; + } } -parentPort.on("message", async (data: WorkerMessage) => { +parentPort.on('message', async (data: WorkerMessage) => { switch (data.type) { // Gateway sends IDENTIFY_SHARD in gateway.tellWorkerToIdentify - case "IDENTIFY_SHARD": { - await manager.identify(data.shardId); + case 'IDENTIFY_SHARD': { + await manager.identify(data.shardId) - break; + break } // Gateway sends ALLOW_IDENTIFY when worker requests to identify - case "ALLOW_IDENTIFY": { - identifyPromises.get(data.shardId)?.(); - identifyPromises.delete(data.shardId); + case 'ALLOW_IDENTIFY': { + identifyPromises.get(data.shardId)?.() + identifyPromises.delete(data.shardId) - break; + break } // Gateway sends SHARD_PAYLOAD for every events it receives from Discord - case "SHARD_PAYLOAD": { - manager.shards.get(data.shardId)?.send(data.data); + case 'SHARD_PAYLOAD': { + manager.shards.get(data.shardId)?.send(data.data) - break; + break } // Send shard info if gateway sends GET_SHARD_INFO - case "GET_SHARD_INFO": { - const infos = manager.shards.map(buildShardInfo); + case 'GET_SHARD_INFO': { + const infos = manager.shards.map(buildShardInfo) - parentPort?.postMessage({ type: "NONCE_REPLY", nonce: data.nonce, data: infos }); + parentPort?.postMessage({ type: 'NONCE_REPLY', nonce: data.nonce, data: infos }) } } -}); +}) ``` Now TypeScript will error because of missing types, add these to your code: ```ts -import { ShardSocketRequest, ShardState } from "discordeno"; +import { ShardSocketRequest, ShardState } from 'discordeno' -export type WorkerMessage = WorkerIdentifyShard | WorkerAllowIdentify | WorkerShardPayload | WorkerGetShardInfo; +export type WorkerMessage = WorkerIdentifyShard | WorkerAllowIdentify | WorkerShardPayload | WorkerGetShardInfo export type WorkerIdentifyShard = { - type: "IDENTIFY_SHARD"; - shardId: number; -}; + type: 'IDENTIFY_SHARD' + shardId: number +} export type WorkerAllowIdentify = { - type: "ALLOW_IDENTIFY"; - shardId: number; -}; + type: 'ALLOW_IDENTIFY' + shardId: number +} export type WorkerShardPayload = { - type: "SHARD_PAYLOAD"; - shardId: number; - data: ShardSocketRequest; -}; + type: 'SHARD_PAYLOAD' + shardId: number + data: ShardSocketRequest +} export type WorkerGetShardInfo = { - type: "GET_SHARD_INFO"; - nonce: string; -}; + type: 'GET_SHARD_INFO' + nonce: string +} export type WorkerCreateData = { - intents: number; - token: string; - handlerUrls: string[]; - handlerAuthorization: string; - path: string; - totalShards: number; - workerId: number; -}; + intents: number + token: string + handlerUrls: string[] + handlerAuthorization: string + path: string + totalShards: number + workerId: number +} export type WorkerShardInfo = { - workerId: number; - shardId: number; - rtt: number; - state: ShardState; -}; + workerId: number + shardId: number + rtt: number + state: ShardState +} ``` ## Handling Discord Payloads @@ -558,15 +558,15 @@ with anything you like. ```ts manager.createShardOptions.handleMessage = async (shard, message) => { - const url = script.handlerUrls[shard.id % script.handlerUrls.length]; - if (!url) return console.error("ERROR: NO URL FOUND TO SEND MESSAGE"); + const url = script.handlerUrls[shard.id % script.handlerUrls.length] + if (!url) return console.error('ERROR: NO URL FOUND TO SEND MESSAGE') await fetch(url, { - method: "POST", + method: 'POST', body: JSON.stringify({ message, shardId: shard.id }), - headers: { "Content-Type": "application/json", Authorization: script.handlerAuthorization }, - }).catch((error) => console.error(error)); -}; + headers: { 'Content-Type': 'application/json', Authorization: script.handlerAuthorization }, + }).catch((error) => console.error(error)) +} ``` You can change this function to use a WS or any form of communication you prefer to use to send this to your event @@ -597,21 +597,21 @@ Now TypeScript will probably throw some errors at your face, so let's fix those hold the queue of events for our gateway. ```ts -import { DiscordGatewayPayload } from "discordeno"; +import { DiscordGatewayPayload } from 'discordeno' const queue: GatewayQueue = { processing: false, events: [], -}; +} export interface QueuedEvent { - message: DiscordGatewayPayload; - shardId: number; + message: DiscordGatewayPayload + shardId: number } export interface GatewayQueue { - processing: boolean; - events: QueuedEvent[]; + processing: boolean + events: QueuedEvent[] } async function handleQueue() { @@ -644,38 +644,33 @@ automatically respond to the ones that can not be deferred. For the interactions defer them and add this event to the queue. ```ts -import { DiscordInteraction, InteractionResponseTypes, InteractionTypes, routes } from "discordeno"; -import { BOT_SERVER_INVITE_CODE } from "../../configs.ts"; +import { DiscordInteraction, InteractionResponseTypes, InteractionTypes, routes } from 'discordeno' +import { BOT_SERVER_INVITE_CODE } from '../../configs.ts' async function handleInteractionQueueing(message: DiscordGatewayPayload, shardId: number) { - if (message.t !== "INTERACTION_CREATE") return; + if (message.t !== 'INTERACTION_CREATE') return - const interaction = message.d as DiscordInteraction; + const interaction = message.d as DiscordInteraction // IF THIS INTERACTION IS NOT DEFERABLE if ([InteractionTypes.ModalSubmit, InteractionTypes.ApplicationCommandAutocomplete].includes(interaction.type)) { - return await rest.runMethod( - rest, - "POST", - routes.INTERACTION_ID_TOKEN(BigInt(interaction.id), interaction.token), - { - type: InteractionResponseTypes.ChannelMessageWithSource, - data: { - content: - `The bot is having a temporary issue, please try again or contact us at https://discord.gg/${BOT_SERVER_INVITE_CODE}`, - }, + return await rest.runMethod(rest, 'POST', routes.INTERACTION_ID_TOKEN(BigInt(interaction.id), interaction.token), { + type: InteractionResponseTypes.ChannelMessageWithSource, + data: { + content: `The bot is having a temporary issue, please try again or contact us at https://discord.gg/${BOT_SERVER_INVITE_CODE}`, }, - ); + }) } - await rest.runMethod(rest, "POST", endpoints.INTERACTION_ID_TOKEN(BigInt(interaction.id), interaction.token), { + await rest.runMethod(rest, 'POST', endpoints.INTERACTION_ID_TOKEN(BigInt(interaction.id), interaction.token), { // MESSAGE COMPONENTS NEED SPECIAL DEFER - type: InteractionTypes.MessageComponent === interaction.type - ? InteractionResponseTypes.DeferredUpdateMessage - : InteractionResponseTypes.DeferredChannelMessageWithSource, - }); + type: + InteractionTypes.MessageComponent === interaction.type + ? InteractionResponseTypes.DeferredUpdateMessage + : InteractionResponseTypes.DeferredChannelMessageWithSource, + }) // ADD EVENT TO QUEUE - queue.events.push({ shardId, message }); + queue.events.push({ shardId, message }) } ``` @@ -687,7 +682,7 @@ const rest = createRestManager({ token: DISCORD_TOKEN, secretKey: REST_AUTHORIZATION, customUrl: REST_URL, -}); +}) ``` So now there is only one thing left the `handleQueue` function. First we get the first item from the queue using @@ -698,34 +693,34 @@ again to run the next item in the queue. ```ts async function handleQueue() { - const event = queue.events.shift(); + const event = queue.events.shift() // QUEUE IS EMPTY if (!event) { - console.log("GATEWAY QUEUE ENDING"); - queue.processing = false; - return; + console.log('GATEWAY QUEUE ENDING') + queue.processing = false + return } await fetch(EVENT_HANDLER_URL, { headers: { Authorization: EVENT_HANDLER_SECRET_KEY, - "Content-Type": "application/json", + 'Content-Type': 'application/json', }, - method: "POST", + method: 'POST', body: JSON.stringify({ shardId: event.shardId, message: event.message, }), }) .then((res) => { - res.text(); - handleQueue(); + res.text() + handleQueue() }) .catch(() => { // EVENT HANDLER STILL NOT ACCEPTING REQUEST. SO ADD BACK TO QUEUE - queue.events.unshift(event); - setTimeout(handleQueue, 1000); - }); + queue.events.unshift(event) + setTimeout(handleQueue, 1000) + }) } ``` @@ -735,20 +730,20 @@ We need to request identify in order to trigger initial handshake with the gatew to do this. ```ts -import { ManagerMessage } from "./mod.ts"; +import { ManagerMessage } from './mod.ts' manager.requestIdentify = async function (shardId: number): Promise { return await new Promise((resolve) => { - identifyPromises.set(shardId, resolve); + identifyPromises.set(shardId, resolve) const identifyRequest: ManagerMessage = { - type: "REQUEST_IDENTIFY", + type: 'REQUEST_IDENTIFY', shardId, - }; + } - parentPort?.postMessage(identifyRequest); - }); -}; + parentPort?.postMessage(identifyRequest) + }) +} ``` That's all, you've now setup your gateway and worker. Here's the full code of `src/gateway/worker.ts`: @@ -765,32 +760,25 @@ import { Shard, ShardSocketRequest, ShardState, -} from "discordeno"; -import { parentPort, workerData } from "worker_threads"; -import { ManagerMessage } from "./mod"; -import { - BOT_SERVER_INVITE_CODE, - DISCORD_TOKEN, - EVENT_HANDLER_SECRET_KEY, - EVENT_HANDLER_URL, - REST_AUTHORIZATION, - REST_URL, -} from "../../configs.ts"; +} from 'discordeno' +import { parentPort, workerData } from 'worker_threads' +import { ManagerMessage } from './mod' +import { BOT_SERVER_INVITE_CODE, DISCORD_TOKEN, EVENT_HANDLER_SECRET_KEY, EVENT_HANDLER_URL, REST_AUTHORIZATION, REST_URL } from '../../configs.ts' if (!parentPort) { - throw new Error("Parent port is null"); + throw new Error('Parent port is null') } // THE DATA WE GET FROM GATEWAY FILE -const script: WorkerCreateData = workerData; +const script: WorkerCreateData = workerData -const identifyPromises = new Map void>(); +const identifyPromises = new Map void>() const rest = createRestManager({ token: DISCORD_TOKEN, secretKey: REST_AUTHORIZATION, customUrl: REST_URL, -}); +}) const manager = createShardManager({ gatewayConfig: { @@ -800,34 +788,34 @@ const manager = createShardManager({ shardIds: [], totalShards: script.totalShards, handleMessage: async (shard, message) => { - const url = script.handlerUrls[shard.id % script.handlerUrls.length]; - if (!url) return console.error("ERROR: NO URL FOUND TO SEND MESSAGE"); + const url = script.handlerUrls[shard.id % script.handlerUrls.length] + if (!url) return console.error('ERROR: NO URL FOUND TO SEND MESSAGE') await fetch(url, { - method: "POST", + method: 'POST', body: JSON.stringify({ message, shardId: shard.id }), - headers: { "Content-Type": "application/json", Authorization: script.handlerAuthorization }, + headers: { 'Content-Type': 'application/json', Authorization: script.handlerAuthorization }, }).catch(() => { // IF FAILED TRY TO QUEUE MAYBE LISTENER IS DOWN - if (message.t === "INTERACTION_CREATE") handleInteractionQueueing(message, shard.id); - else queue.events.push({ shardId: shard.id, message }); + if (message.t === 'INTERACTION_CREATE') handleInteractionQueueing(message, shard.id) + else queue.events.push({ shardId: shard.id, message }) - setTimeout(handleQueue, 1000); - }); + setTimeout(handleQueue, 1000) + }) }, requestIdentify: async function (shardId: number): Promise { return await new Promise((resolve) => { - identifyPromises.set(shardId, resolve); + identifyPromises.set(shardId, resolve) const identifyRequest: ManagerMessage = { - type: "REQUEST_IDENTIFY", + type: 'REQUEST_IDENTIFY', shardId, - }; + } - parentPort?.postMessage(identifyRequest); - }); + parentPort?.postMessage(identifyRequest) + }) }, -}); +}) function buildShardInfo(shard: Shard): WorkerShardInfo { return { @@ -835,149 +823,149 @@ function buildShardInfo(shard: Shard): WorkerShardInfo { shardId: shard.id, rtt: shard.heart.rtt || -1, state: shard.state, - }; + } } -parentPort.on("message", async (data: WorkerMessage) => { +parentPort.on('message', async (data: WorkerMessage) => { switch (data.type) { // Gateway sends IDENTIFY_SHARD in gateway.tellWorkerToIdentify - case "IDENTIFY_SHARD": { - await manager.identify(data.shardId); + case 'IDENTIFY_SHARD': { + await manager.identify(data.shardId) - break; + break } // Gateway sends ALLOW_IDENTIFY when worker requests to identify - case "ALLOW_IDENTIFY": { - identifyPromises.get(data.shardId)?.(); - identifyPromises.delete(data.shardId); + case 'ALLOW_IDENTIFY': { + identifyPromises.get(data.shardId)?.() + identifyPromises.delete(data.shardId) - break; + break } // Gateway sends SHARD_PAYLOAD for every events it receives from Discord - case "SHARD_PAYLOAD": { - manager.shards.get(data.shardId)?.send(data.data); + case 'SHARD_PAYLOAD': { + manager.shards.get(data.shardId)?.send(data.data) - break; + break } // Send shard info if gateway sends GET_SHARD_INFO - case "GET_SHARD_INFO": { - const infos = manager.shards.map(buildShardInfo); + case 'GET_SHARD_INFO': { + const infos = manager.shards.map(buildShardInfo) - parentPort?.postMessage({ type: "NONCE_REPLY", nonce: data.nonce, data: infos }); + parentPort?.postMessage({ type: 'NONCE_REPLY', nonce: data.nonce, data: infos }) } } -}); +}) const queue: GatewayQueue = { processing: false, events: [], -}; +} async function handleQueue() { - const event = queue.events.shift(); + const event = queue.events.shift() // QUEUE IS EMPTY if (!event) { - console.log("GATEWAY QUEUE ENDING"); - queue.processing = false; - return; + console.log('GATEWAY QUEUE ENDING') + queue.processing = false + return } await fetch(EVENT_HANDLER_URL, { headers: { Authorization: EVENT_HANDLER_SECRET_KEY, - "Content-Type": "application/json", + 'Content-Type': 'application/json', }, - method: "POST", + method: 'POST', body: JSON.stringify({ shardId: event.shardId, message: event.message, }), }) .then((res) => { - res.text(); - handleQueue(); + res.text() + handleQueue() }) .catch(() => { // EVENT HANDLER STILL NOT ACCEPTING REQUEST. SO ADD BACK TO QUEUE - queue.events.unshift(event); - setTimeout(handleQueue, 1000); - }); + queue.events.unshift(event) + setTimeout(handleQueue, 1000) + }) } async function handleInteractionQueueing(message: DiscordGatewayPayload, shardId: number) { - if (message.t !== "INTERACTION_CREATE") return; + if (message.t !== 'INTERACTION_CREATE') return - const interaction = message.d as DiscordInteraction; + const interaction = message.d as DiscordInteraction // IF THIS INTERACTION IS NOT DEFERABLE if ([InteractionTypes.ModalSubmit, InteractionTypes.ApplicationCommandAutocomplete].includes(interaction.type)) { - return await rest.runMethod(rest, "POST", routes.INTERACTION_ID_TOKEN(BigInt(interaction.id), interaction.token), { + return await rest.runMethod(rest, 'POST', routes.INTERACTION_ID_TOKEN(BigInt(interaction.id), interaction.token), { type: InteractionResponseTypes.ChannelMessageWithSource, data: { - content: - `The bot is having a temporary issue, please try again or contact us at https://discord.gg/${BOT_SERVER_INVITE_CODE}`, + content: `The bot is having a temporary issue, please try again or contact us at https://discord.gg/${BOT_SERVER_INVITE_CODE}`, }, - }); + }) } - await rest.runMethod(rest, "POST", routes.INTERACTION_ID_TOKEN(BigInt(interaction.id), interaction.token), { + await rest.runMethod(rest, 'POST', routes.INTERACTION_ID_TOKEN(BigInt(interaction.id), interaction.token), { // MESSAGE COMPONENTS NEED SPECIAL DEFER - type: InteractionTypes.MessageComponent === interaction.type - ? InteractionResponseTypes.DeferredUpdateMessage - : InteractionResponseTypes.DeferredChannelMessageWithSource, - }); + type: + InteractionTypes.MessageComponent === interaction.type + ? InteractionResponseTypes.DeferredUpdateMessage + : InteractionResponseTypes.DeferredChannelMessageWithSource, + }) // ADD EVENT TO QUEUE - queue.events.push({ shardId, message }); + queue.events.push({ shardId, message }) } -export type WorkerMessage = WorkerIdentifyShard | WorkerAllowIdentify | WorkerShardPayload | WorkerGetShardInfo; +export type WorkerMessage = WorkerIdentifyShard | WorkerAllowIdentify | WorkerShardPayload | WorkerGetShardInfo export type WorkerIdentifyShard = { - type: "IDENTIFY_SHARD"; - shardId: number; -}; + type: 'IDENTIFY_SHARD' + shardId: number +} export type WorkerAllowIdentify = { - type: "ALLOW_IDENTIFY"; - shardId: number; -}; + type: 'ALLOW_IDENTIFY' + shardId: number +} export type WorkerShardPayload = { - type: "SHARD_PAYLOAD"; - shardId: number; - data: ShardSocketRequest; -}; + type: 'SHARD_PAYLOAD' + shardId: number + data: ShardSocketRequest +} export type WorkerGetShardInfo = { - type: "GET_SHARD_INFO"; - nonce: string; -}; + type: 'GET_SHARD_INFO' + nonce: string +} export type WorkerCreateData = { - intents: number; - token: string; - handlerUrls: string[]; - handlerAuthorization: string; - path: string; - totalShards: number; - workerId: number; -}; + intents: number + token: string + handlerUrls: string[] + handlerAuthorization: string + path: string + totalShards: number + workerId: number +} export type WorkerShardInfo = { - workerId: number; - shardId: number; - rtt: number; - state: ShardState; -}; + workerId: number + shardId: number + rtt: number + state: ShardState +} export interface QueuedEvent { - message: DiscordGatewayPayload; - shardId: number; + message: DiscordGatewayPayload + shardId: number } export interface GatewayQueue { - processing: boolean; - events: QueuedEvent[]; + processing: boolean + events: QueuedEvent[] } ``` diff --git a/site/docs/big-bot-guide/rest.md b/site/docs/big-bot-guide/rest.md index f33b3e137..2195203ed 100644 --- a/site/docs/big-bot-guide/rest.md +++ b/site/docs/big-bot-guide/rest.md @@ -43,14 +43,14 @@ Before going further, you should have already made the following pieces: Now let's open up that rest file and start coding. ```ts -import { DISCORD_TOKEN, REST_AUTHORIZATION, REST_PORT } from "../../configs.ts"; -import { BASE_URL, createRestManager } from "../../deps.ts"; +import { DISCORD_TOKEN, REST_AUTHORIZATION, REST_PORT } from '../../configs.ts' +import { BASE_URL, createRestManager } from '../../deps.ts' const rest = createRestManager({ token: DISCORD_TOKEN, secretKey: REST_AUTHORIZATION, customUrl: `http://localhost:${REST_PORT}`, -}); +}) ``` - `createRestManager` is imported from your deps file which should have exported everything from discordeno. @@ -70,36 +70,31 @@ guides on this out there. I will only cover the rough functionality. ```ts // START LISTENING TO THE URL(localhost) -const server = Deno.listen({ port: REST_PORT }); -console.info( - `HTTP webserver running. Access it at: http://localhost:${REST_PORT}/`, -); +const server = Deno.listen({ port: REST_PORT }) +console.info(`HTTP webserver running. Access it at: http://localhost:${REST_PORT}/`) // Connections to the server will be yielded up as an async iterable. for await (const conn of server) { // In order to not be blocking, we need to handle each connection individually // in its own async function. - handleRequest(conn); + handleRequest(conn) } async function handleRequest(conn: Deno.Conn) { // This "upgrades" a network connection into an HTTP connection. - const httpConn = Deno.serveHttp(conn); + const httpConn = Deno.serveHttp(conn) // Each request sent over the HTTP connection will be yielded as an async // iterator from the HTTP connection. for await (const requestEvent of httpConn) { - if ( - !REST_AUTHORIZATION || - REST_AUTHORIZATION !== requestEvent.request.headers.get("AUTHORIZATION") - ) { + if (!REST_AUTHORIZATION || REST_AUTHORIZATION !== requestEvent.request.headers.get('AUTHORIZATION')) { return requestEvent.respondWith( - new Response(JSON.stringify({ error: "Invalid authorization key." }), { + new Response(JSON.stringify({ error: 'Invalid authorization key.' }), { status: 401, }), - ); + ) } - const json = (await requestEvent.request.json()) as any; + const json = (await requestEvent.request.json()) as any // IMPLEMENT ANY ERROR HANDLING HERE IF YOU WOULD LIKE BY WRAPPING THIS IN A CATCH @@ -109,13 +104,9 @@ async function handleRequest(conn: Deno.Conn) { // USE THE SAME METHOD THAT CAME IN. IF DELETE CAME IN WE SEND DELETE OUT requestEvent.request.method as any, // OVERWRITE THE CUSTOM URL WITH DISCORDS BASE URL - `${BASE_URL}/v${rest.version}${ - requestEvent.request.url.substring( - rest.customUrl.length, - ) - }`, + `${BASE_URL}/v${rest.version}${requestEvent.request.url.substring(rest.customUrl.length)}`, json, - ); + ) // RETURN DISCORDS RESPONSE BACK TO THE PROCESS MAKING THE REQUEST if (result) { @@ -123,13 +114,13 @@ async function handleRequest(conn: Deno.Conn) { new Response(JSON.stringify(result), { status: 200, }), - ); + ) } else { requestEvent.respondWith( new Response(undefined, { status: 204, }), - ); + ) } } } diff --git a/site/docs/frequently-asked-questions.md b/site/docs/frequently-asked-questions.md index 2efadcba2..aeb6ac8ae 100644 --- a/site/docs/frequently-asked-questions.md +++ b/site/docs/frequently-asked-questions.md @@ -10,7 +10,7 @@ TypeScript is supported to the highest standard by Discordeno. TypeScript is inc When I utilised other libraries, I frequently observed incorrect or troublesome typings. This is so that TypeScript won't alert the library developers because most of the Discord API typings aren't utilised by the libraries themselves. -It is quite unlikely that these typings would become wrong or outdated as a result of minor errors like forgetting to update typings because Discordeno utilises them as part of the rest process. Libraries occasionally add a property without also adding it to their typings. Because of this, TypeScript developers cannot use it, only JavaScript developers can. Typings are crucial for TypeScript developers. Typings are treated as a component of the code by Discordeno! A breaking change in typings is a breaking change for the library! +It is quite unlikely that these typings would become wrong or outdated as a result of minor errors like forgetting to update typings because Discordeno utilises them as part of the rest process. Libraries occasionally add a property without also adding it to their typings. Because of this, TypeScript developers cannot use it, only JavaScript developers can. Typings are crucial for TypeScript developers. Typings are treated as a component of the code by Discordeno! A breaking change in typings is a breaking change for the library! ## How Stable Is Discordeno? @@ -33,9 +33,9 @@ In regards to EventEmitter, I believe a functional event API was a much better c ```typescript // EventEmitter Example -EventEmitter.emit("guildCreate", guild); +EventEmitter.emit('guildCreate', guild) // Discordeno Example -bot.events.guildCreate?.(bot, guild); +bot.events.guildCreate?.(bot, guild) ``` There isn't really any difference especially for users when they use it. One bad thing about EventEmitter is that if @@ -48,7 +48,7 @@ listeners. You don't need to worry about binding or not binding events. They are In Discordeno, this is extremely simple; you just simply give it the new event handlers. For example: ```typescript -bot.events.guildCreate = newGuildCreateEventHandler; +bot.events.guildCreate = newGuildCreateEventHandler ``` ## Why Do You Have A Class for Collection If Classes Are Bad? @@ -84,7 +84,7 @@ have even seen some bots have hundreds of thousands of Missing Permission or Mis don't handle it. IMO, this is a crucial part of any good library as much as it is to handle rate limiting. ```typescript -import { Bot, Errors, Message } from "https://deno.land/x/discordeno@16.0.0/mod.ts"; +import { Bot, Errors, Message } from 'https://deno.land/x/discordeno@16.0.0/mod.ts' export function handleCommandError(bot: Bot, message: Message, type: Errors) { switch (type) { @@ -92,10 +92,10 @@ export function handleCommandError(bot: Bot, message: Message, type: Errors) { return bot.helpers.sendMessage(message.channelId, { content: "The bot does not have the necessary permission to manage/edit other user's nicknames. Grant the **MANAGE_NICKNAME** permission to the bot and try again.", - }); + }) case Errors.MISSING_MANAGE_ROLES: // Note: i18n is not part of the library. This is just an example of how you could use i18n for custom error responses. - return bot.helpers.sendMessage(message.channelId, { content: i18n.translate(type) }); + return bot.helpers.sendMessage(message.channelId, { content: i18n.translate(type) }) } } ``` diff --git a/site/docs/general/frequently-asked-questions.md b/site/docs/general/frequently-asked-questions.md index 2efadcba2..aeb6ac8ae 100644 --- a/site/docs/general/frequently-asked-questions.md +++ b/site/docs/general/frequently-asked-questions.md @@ -10,7 +10,7 @@ TypeScript is supported to the highest standard by Discordeno. TypeScript is inc When I utilised other libraries, I frequently observed incorrect or troublesome typings. This is so that TypeScript won't alert the library developers because most of the Discord API typings aren't utilised by the libraries themselves. -It is quite unlikely that these typings would become wrong or outdated as a result of minor errors like forgetting to update typings because Discordeno utilises them as part of the rest process. Libraries occasionally add a property without also adding it to their typings. Because of this, TypeScript developers cannot use it, only JavaScript developers can. Typings are crucial for TypeScript developers. Typings are treated as a component of the code by Discordeno! A breaking change in typings is a breaking change for the library! +It is quite unlikely that these typings would become wrong or outdated as a result of minor errors like forgetting to update typings because Discordeno utilises them as part of the rest process. Libraries occasionally add a property without also adding it to their typings. Because of this, TypeScript developers cannot use it, only JavaScript developers can. Typings are crucial for TypeScript developers. Typings are treated as a component of the code by Discordeno! A breaking change in typings is a breaking change for the library! ## How Stable Is Discordeno? @@ -33,9 +33,9 @@ In regards to EventEmitter, I believe a functional event API was a much better c ```typescript // EventEmitter Example -EventEmitter.emit("guildCreate", guild); +EventEmitter.emit('guildCreate', guild) // Discordeno Example -bot.events.guildCreate?.(bot, guild); +bot.events.guildCreate?.(bot, guild) ``` There isn't really any difference especially for users when they use it. One bad thing about EventEmitter is that if @@ -48,7 +48,7 @@ listeners. You don't need to worry about binding or not binding events. They are In Discordeno, this is extremely simple; you just simply give it the new event handlers. For example: ```typescript -bot.events.guildCreate = newGuildCreateEventHandler; +bot.events.guildCreate = newGuildCreateEventHandler ``` ## Why Do You Have A Class for Collection If Classes Are Bad? @@ -84,7 +84,7 @@ have even seen some bots have hundreds of thousands of Missing Permission or Mis don't handle it. IMO, this is a crucial part of any good library as much as it is to handle rate limiting. ```typescript -import { Bot, Errors, Message } from "https://deno.land/x/discordeno@16.0.0/mod.ts"; +import { Bot, Errors, Message } from 'https://deno.land/x/discordeno@16.0.0/mod.ts' export function handleCommandError(bot: Bot, message: Message, type: Errors) { switch (type) { @@ -92,10 +92,10 @@ export function handleCommandError(bot: Bot, message: Message, type: Errors) { return bot.helpers.sendMessage(message.channelId, { content: "The bot does not have the necessary permission to manage/edit other user's nicknames. Grant the **MANAGE_NICKNAME** permission to the bot and try again.", - }); + }) case Errors.MISSING_MANAGE_ROLES: // Note: i18n is not part of the library. This is just an example of how you could use i18n for custom error responses. - return bot.helpers.sendMessage(message.channelId, { content: i18n.translate(type) }); + return bot.helpers.sendMessage(message.channelId, { content: i18n.translate(type) }) } } ``` diff --git a/site/docs/general/getting-started.md b/site/docs/general/getting-started.md index 57b6b72b9..e02f8558e 100644 --- a/site/docs/general/getting-started.md +++ b/site/docs/general/getting-started.md @@ -36,7 +36,7 @@ in handy! You can install Discordeno by importing: ```ts -import { startBot } from "https://deno.land/x/discordeno@16.0.0/mod.ts"; +import { startBot } from 'https://deno.land/x/discordeno@16.0.0/mod.ts' ``` ## Example Usage @@ -45,24 +45,24 @@ Starting with Discordeno is very simple, you can start from scratch without any of code into a new TypeScript file: ```ts -import { createBot, Intents, startBot } from "https://deno.land/x/discordeno/mod.ts"; +import { createBot, Intents, startBot } from 'https://deno.land/x/discordeno/mod.ts' startBot( createBot({ - token: "BOT TOKEN", + token: 'BOT TOKEN', intents: Intents.Guilds | Intents.GuildMessages, events: { ready() { - console.log("Successfully connected to gateway"); + console.log('Successfully connected to gateway') }, messageCreate(bot, message) { - if (message.content === "!ping") { - bot.helpers.sendMessage(message.channelId, { content: "Pong using Discordeno!" }); + if (message.content === '!ping') { + bot.helpers.sendMessage(message.channelId, { content: 'Pong using Discordeno!' }) } }, }, }), -); +) ``` ## Tutorials diff --git a/site/docs/general/migrating.md b/site/docs/general/migrating.md index c74a33e9c..b99997983 100644 --- a/site/docs/general/migrating.md +++ b/site/docs/general/migrating.md @@ -44,118 +44,104 @@ Current Discord.JS Code: ```js /* Keeping this to shoutout/credit the original author <3 -* @author: nukestye -*/ + * @author: nukestye + */ -const config = require("./config.json"); -const fs = require("fs"); -const log = console.log; +const config = require('./config.json') +const fs = require('fs') +const log = console.log // Setting up the way to get commands -const { CommandoClient } = require("discord.js-commando"); -const path = require("path"); +const { CommandoClient } = require('discord.js-commando') +const path = require('path') // reading events -fs.readdir("./src/events/", (err, files) => { - if (err) return console.error(err); +fs.readdir('./src/events/', (err, files) => { + if (err) return console.error(err) files.forEach((file) => { - const eventFunction = require(`./src/events/${file}`); - if (eventFunction.disabled) return; - const event = eventFunction.event || file.split(".")[0]; - const emitter = - (typeof eventFunction.emitter === "string" ? client[eventFunction.emitter] : eventFunction.emitter) || client; - const { once } = eventFunction; + const eventFunction = require(`./src/events/${file}`) + if (eventFunction.disabled) return + const event = eventFunction.event || file.split('.')[0] + const emitter = (typeof eventFunction.emitter === 'string' ? client[eventFunction.emitter] : eventFunction.emitter) || client + const { once } = eventFunction try { - emitter[ - once ? "once" : "on" - ](event, (...args) => eventFunction.run(...args)); + emitter[once ? 'once' : 'on'](event, (...args) => eventFunction.run(...args)) } catch (error) { - console.error(error.stack); + console.error(error.stack) } - }); -}); + }) +}) -const client = global.client = new CommandoClient({ +const client = (global.client = new CommandoClient({ commandPrefix: `${config.prefix}`, owner: `${config.owner}`, invite: `${config.discord}`, unknownCommandResponse: false, -}); +})) // Registing the commands client.registry .registerDefaultTypes() // The different fields for cmds .registerGroups([ - ["mod", "Moderation Commands"], - ["public", "Public Commands"], + ['mod', 'Moderation Commands'], + ['public', 'Public Commands'], ]) .registerDefaultGroups() // Basic cmds can be disabled like {"cmd: false"} .registerDefaultCommands() // commands in "/src/commands" will be counted - .registerCommandsIn(path.join(__dirname, "/src/commands")); + .registerCommandsIn(path.join(__dirname, '/src/commands')) // list of activities that the bot goes through -const activityArray = [`${config.prefix}help | `]; +const activityArray = [`${config.prefix}help | `] // Bot lanuch code -client.once("ready", () => { - log(`Logged in as ${client.user.tag} in ${client.guilds.size} guild(s)!`); +client.once('ready', () => { + log(`Logged in as ${client.user.tag} in ${client.guilds.size} guild(s)!`) setInterval(() => { - const index = Math.floor(Math.random() * (activityArray.length)); // generates a random number between 1 and the length of the activities array list - client.user.setActivity( - activityArray[index], - { - type: "PLAYING", - }, - ); // sets bot"s activities to one of the phrases in the arraylist. - }, 5000); // updates every 10000ms = 10s -}); + const index = Math.floor(Math.random() * activityArray.length) // generates a random number between 1 and the length of the activities array list + client.user.setActivity(activityArray[index], { + type: 'PLAYING', + }) // sets bot"s activities to one of the phrases in the arraylist. + }, 5000) // updates every 10000ms = 10s +}) // If an error print it out -client.on("error", console.error); +client.on('error', console.error) // Login in using the token in config -client.login(config.env.TOKEN); +client.login(config.env.TOKEN) ``` Discordeno Version: ```ts -import { botCache, Intents } from "./deps.ts"; -import { configs } from "./configs.ts"; -import { importDirectory } from "./src/utils/helpers.ts"; -import { loadLanguages } from "./src/utils/i18next.ts"; +import { botCache, Intents } from './deps.ts' +import { configs } from './configs.ts' +import { importDirectory } from './src/utils/helpers.ts' +import { loadLanguages } from './src/utils/i18next.ts' -console.info( - "Beginning Bot Startup Process. This can take a little bit depending on your system. Loading now...", -); +console.info('Beginning Bot Startup Process. This can take a little bit depending on your system. Loading now...') // Always require these files be processed before anything else -await Promise.all([ - "./src/customizations/structures", -].map( - (path) => importDirectory(Deno.realPathSync(path)), -)); +await Promise.all(['./src/customizations/structures'].map((path) => importDirectory(Deno.realPathSync(path)))) // Forces deno to read all the files which will fill the commands/inhibitors cache etc. await Promise.all( [ - "./src/commands", - "./src/inhibitors", - "./src/events", - "./src/arguments", - "./src/monitors", - "./src/tasks", - "./src/permissionLevels", - "./src/events", - ].map( - (path) => importDirectory(Deno.realPathSync(path)), - ), -); + './src/commands', + './src/inhibitors', + './src/events', + './src/arguments', + './src/monitors', + './src/tasks', + './src/permissionLevels', + './src/events', + ].map((path) => importDirectory(Deno.realPathSync(path))), +) // Loads languages -await loadLanguages(); -await import("./src/database/database.ts"); +await loadLanguages() +await import('./src/database/database.ts') startBot({ token: configs.token, @@ -164,7 +150,7 @@ startBot({ intents: Intents.Guilds | Intents.GuildMessages, // These are all your event handler functions. Imported from the events folder events: botCache.events, -}); +}) ``` Something we haven't converted yet from the `main.js` files is the event listeners. To do that, we will open up the @@ -174,40 +160,34 @@ there is already a `ready.ts` file. We can just use that. In our `ready.ts` file we can add the `ready` event listener. ```ts -import { ActivityTypes, botCache, cache, chooseRandom, editBotStatus, StatusTypes } from "../../deps.ts"; -import { registerTasks } from "./../utils/taskHelper.ts"; +import { ActivityTypes, botCache, cache, chooseRandom, editBotStatus, StatusTypes } from '../../deps.ts' +import { registerTasks } from './../utils/taskHelper.ts' botCache.events.ready = function () { - editBotStatus( - StatusTypes.DoNotDisturb, - "Discordeno Best Lib", - ActivityTypes.Game, - ); + editBotStatus(StatusTypes.DoNotDisturb, 'Discordeno Best Lib', ActivityTypes.Game) - console.log(`Loaded ${botCache.arguments.size} Argument(s)`); - console.log(`Loaded ${botCache.commands.size} Command(s)`); - console.log(`Loaded ${Object.keys(botCache.events).length} Event(s)`); - console.log(`Loaded ${botCache.inhibitors.size} Inhibitor(s)`); - console.log(`Loaded ${botCache.monitors.size} Monitor(s)`); - console.log(`Loaded ${botCache.tasks.size} Task(s)`); + console.log(`Loaded ${botCache.arguments.size} Argument(s)`) + console.log(`Loaded ${botCache.commands.size} Command(s)`) + console.log(`Loaded ${Object.keys(botCache.events).length} Event(s)`) + console.log(`Loaded ${botCache.inhibitors.size} Inhibitor(s)`) + console.log(`Loaded ${botCache.monitors.size} Monitor(s)`) + console.log(`Loaded ${botCache.tasks.size} Task(s)`) - registerTasks(); + registerTasks() - console.log( - `[READY] Bot is online and ready in ${cache.guilds.size} guild(s)!`, - ); + console.log(`[READY] Bot is online and ready in ${cache.guilds.size} guild(s)!`) // list of activities that the bot goes through - const activityArray = [`${configs.prefix}help | `]; + const activityArray = [`${configs.prefix}help | `] setInterval(() => { - const randomActivity = activityArray[Math.floor(Math.random() * activityArray.length)]; + const randomActivity = activityArray[Math.floor(Math.random() * activityArray.length)] editBotStatus(botCache, { activities: [{ name: randomActivity, type: ActivityTypes.Game, createdAt: Date.now() }], - status: "online", - }); - }, 5000); -}; + status: 'online', + }) + }, 5000) +} ``` To understand this code, we are setting a function to be run when the bot is `ready`. Then the bot will edit the bot's @@ -228,86 +208,85 @@ This is the code from the bot: ```ts // Getting the 'Command' features from Commando -const { Command } = require("discord.js-commando"); +const { Command } = require('discord.js-commando') // Code for the command module.exports = class addRoleCommand extends Command { constructor(client) { super(client, { // name of the command, must be in lowercase - name: "addrole", + name: 'addrole', // other ways to call the command, must be in lowercase - aliases: ["role"], + aliases: ['role'], // command group its part of - group: "mod", + group: 'mod', // name within the command group, must be in lowercase - memberName: "addrole", + memberName: 'addrole', // Is the description used for 'help' command - description: "Adds mentioned role to mentioned user.", + description: 'Adds mentioned role to mentioned user.', // Prevents it from being used in dms guildOnly: true, // Permissions, list found here > `discord.js.org/#/docs/main/11.5.1/class/Permissions?scrollTo=s-FLAGS` - clientPermissions: ["ADMINISTRATOR", "MANAGE_ROLES"], - userPermissions: ["MANAGE_ROLES"], + clientPermissions: ['ADMINISTRATOR', 'MANAGE_ROLES'], + userPermissions: ['MANAGE_ROLES'], // Prevents anyone other than owner to use the command ownerOnly: false, - }); + }) } // Run code goes here run(message) { - const user = message.mentions.members.first(); - const roleToAdd = message.mentions.roles.first(); + const user = message.mentions.members.first() + const roleToAdd = message.mentions.roles.first() // checking to see if the user has the role or not - if (!(user.roles.find((r) => r.name === roleToAdd.name))) { - user.addRole(roleToAdd); - message.channel.send(`${user} has been given the role: ${roleToAdd.name}`) - .then((msg) => { - msg.delete(5000); - }); + if (!user.roles.find((r) => r.name === roleToAdd.name)) { + user.addRole(roleToAdd) + message.channel.send(`${user} has been given the role: ${roleToAdd.name}`).then((msg) => { + msg.delete(5000) + }) } else { - message.channel.send(`${user} already has the role: ${roleToAdd.name}`); + message.channel.send(`${user} already has the role: ${roleToAdd.name}`) } // console.error(user, roleToAdd, message.member.roles.find(r => r.name === roleToAdd)); } -}; +} ``` This is how to do it with Discordeno: ```ts -import { createCommand } from "./../../utils/helpers.ts"; +import { createCommand } from './../../utils/helpers.ts' createCommand({ - name: "role", + name: 'role', // Oher ways to call the command - aliases: ["addrole"], + aliases: ['addrole'], // Is the description used for 'help' command - description: "Adds mentioned role to mentioned user.", + description: 'Adds mentioned role to mentioned user.', // Prevents it from being used in dms guildOnly: true, - botServerPermissions: ["ADMINISTRATOR", "MANAGE_ROLES"], - userServerPermissions: ["MANAGE_ROLES"], + botServerPermissions: ['ADMINISTRATOR', 'MANAGE_ROLES'], + userServerPermissions: ['MANAGE_ROLES'], arguments: [ - { name: "member", type: "member" }, - { name: "role", type: "role" }, + { name: 'member', type: 'member' }, + { name: 'role', type: 'role' }, ], execute: (bot, message, args) => { // checking to see if the user has the role or not if (!args.member.roles.includes(args.role.id)) { - bot.helpers.addRole(message.guildId, args.member.id, args.role.id); + bot.helpers.addRole(message.guildId, args.member.id, args.role.id) bot.helpers.sendMessage(message.channelId, { content: `${args.member.mention} has been given the role: ${args.role.name}`, - }); + }) } else { bot.helpers.sendMessage(message.channelId, { content: `${args.member.mention} already has the role: ${args.role.name}`, - }); + }) } }, -}); +}) ``` Awesome, that is a full command converted from Discord.JS to Discordeno. See how easy it is! Let's convert one more @@ -317,25 +296,25 @@ Discord.JS Kick Command Version ```js // Getting the 'Command' features from Commando -const { Command } = require("discord.js-commando"); -const { RichEmbed } = require("discord.js"); -const chalk = require("chalk"); -const log = console.log; +const { Command } = require('discord.js-commando') +const { RichEmbed } = require('discord.js') +const chalk = require('chalk') +const log = console.log // Code for the command module.exports = class kickCommand extends Command { constructor(client) { super(client, { // name of the command, must be in lowercase - name: "kick", + name: 'kick', // other ways to call the command, must be in lowercase - aliases: ["boot", "tempban"], + aliases: ['boot', 'tempban'], // command group its part of - group: "mod", + group: 'mod', // name within the command group, must be in lowercase - memberName: "kick", + memberName: 'kick', // Is the description used for 'help' command - description: "Kick command.", + description: 'Kick command.', // adds cooldowns to the command throttling: { // usages in certain time x @@ -346,57 +325,52 @@ module.exports = class kickCommand extends Command { // Prevents it from being used in dms guildOnly: true, // Permissions, list found here > `discord.js.org/#/docs/main/11.5.1/class/Permissions?scrollTo=s-FLAGS` - clientPermissions: ["ADMINISTRATOR"], - userPermissions: ["KICK_MEMBERS"], + clientPermissions: ['ADMINISTRATOR'], + userPermissions: ['KICK_MEMBERS'], // Prevents anyone other than owner to use the command ownerOnly: false, - }); + }) } // Run code goes here run(message) { - const messageArry = message.content.split(" "); - const args = messageArry.slice(1); + const messageArry = message.content.split(' ') + const args = messageArry.slice(1) - const kUser = message.guild.member( - message.mentions.users.first() || message.guild.get(args[0]), - ); - if (!kUser) return message.channel.send("User cannot be found!"); - const kreason = args.join(" ").slice(22); + const kUser = message.guild.member(message.mentions.users.first() || message.guild.get(args[0])) + if (!kUser) return message.channel.send('User cannot be found!') + const kreason = args.join(' ').slice(22) // setting up the embed for report/log - const kickEmbed = new RichEmbed() - .setDescription(`Report: ${kUser} Kick`) - .addField("Reason >", `${kreason}`) - .addField("Time", message.createdAt); + const kickEmbed = new RichEmbed().setDescription(`Report: ${kUser} Kick`).addField('Reason >', `${kreason}`).addField('Time', message.createdAt) - const reportchannel = message.guild.channels.find("name", "report"); + const reportchannel = message.guild.channels.find('name', 'report') if (!reportchannel) { - return message.channel.send("*`Report channel cannot be found!`*"); + return message.channel.send('*`Report channel cannot be found!`*') } // Delete the message command // eslint-disable-next-line camelcase - message.delete().catch((O_o) => {}); + message.delete().catch((O_o) => {}) // Kick the user with reason - message.guild.member(kUser).kick(kreason); + message.guild.member(kUser).kick(kreason) // sends the kick report into log/report - reportchannel.send(kickEmbed); + reportchannel.send(kickEmbed) // Logs the kick into the terminal - log(chalk.red("KICK", chalk.underline.bgBlue(kUser) + "!")); + log(chalk.red('KICK', chalk.underline.bgBlue(kUser) + '!')) } -}; +} ``` Discordeno Version ```ts -import { createCommand } from "./../../utils/helpers.ts"; +import { createCommand } from './../../utils/helpers.ts' createCommand({ name: `kick`, - aliases: ["boot", "tempban"], - description: "Kick command.", + aliases: ['boot', 'tempban'], + description: 'Kick command.', // adds cooldowns to the command cooldown: { // usages in certain duration of seconds below @@ -406,23 +380,23 @@ createCommand({ }, // Prevents it from being used in dms guildOnly: true, - botServerPermissions: ["ADMINISTRATOR"], - userServerPermissions: ["KICK_MEMBERS"], + botServerPermissions: ['ADMINISTRATOR'], + userServerPermissions: ['KICK_MEMBERS'], arguments: [ { - name: "member", - type: "member", + name: 'member', + type: 'member', missing: function (message) { - message.reply(`User cannot be found.`); + message.reply(`User cannot be found.`) }, // By default this is true but for the purpose of the guide so you can see this exists. required: true, }, { - name: "reason", + name: 'reason', // The leftover string provided by the user that was not used by previous args. - type: "...string", - defaultValue: "No reason provided.", + type: '...string', + defaultValue: 'No reason provided.', // It is silly to lowercase this but for the purpose of the guide you can see that this is also available to you. lowercase: true, }, @@ -431,26 +405,26 @@ createCommand({ // setting up the embed for report/log const embed = new Embed() .setDescription(`Report: ${args.member.mention} Kick`) - .addField("Reason >", args.reason) - .addField("Time", message.timestamp.toString()); + .addField('Reason >', args.reason) + .addField('Time', message.timestamp.toString()) - const reportchannel = message.guild?.channels.find((channel) => channel.name === "report"); + const reportchannel = message.guild?.channels.find((channel) => channel.name === 'report') if (!reportchannel) { - return bot.helpers.sendMessage(message.channelId, { content: "*`Report channel cannot be found!`*" }); + return bot.helpers.sendMessage(message.channelId, { content: '*`Report channel cannot be found!`*' }) } // Delete the message command - bot.helpers.deleteMessage(message.channelId, { content: "Remove kick command trigger." }); + bot.helpers.deleteMessage(message.channelId, { content: 'Remove kick command trigger.' }) // Kick the user with reason - bot.helpers.kickMember(message.guildId, args.member.id, args.reason); + bot.helpers.kickMember(message.guildId, args.member.id, args.reason) // sends the kick report into log/report - bot.helpers.sendMessage(message.channelId, { embeds: [embed] }); + bot.helpers.sendMessage(message.channelId, { embeds: [embed] }) }, -}); +}) interface KickArgs { - member: Member; - reason: string; + member: Member + reason: string } ``` diff --git a/site/docs/generated/README.md b/site/docs/generated/README.md index 6a32797c8..fcffdc04c 100644 --- a/site/docs/generated/README.md +++ b/site/docs/generated/README.md @@ -105,28 +105,24 @@ Have your cache setup in any way you like. Redis, PGSQL or any cache layer you w Here is a minimal example to get started with: ```typescript -import { - createBot, - Intents, - startBot, -} from "https://deno.land/x/discordeno@13.0.0/mod.ts"; +import { createBot, Intents, startBot } from 'https://deno.land/x/discordeno@13.0.0/mod.ts' const bot = createBot({ token: process.env.DISCORD_TOKEN, intents: Intents.Guilds | Intents.GuildMessages, events: { ready() { - console.log("Successfully connected to gateway"); + console.log('Successfully connected to gateway') }, }, -}); +}) // Another way to do events bot.events.messageCreate = function (b, message) { // Process the message here with your command handler. -}; +} -await startBot(bot); +await startBot(bot) ``` ### Tools diff --git a/site/docs/getting-started.md b/site/docs/getting-started.md index 57b6b72b9..e02f8558e 100644 --- a/site/docs/getting-started.md +++ b/site/docs/getting-started.md @@ -36,7 +36,7 @@ in handy! You can install Discordeno by importing: ```ts -import { startBot } from "https://deno.land/x/discordeno@16.0.0/mod.ts"; +import { startBot } from 'https://deno.land/x/discordeno@16.0.0/mod.ts' ``` ## Example Usage @@ -45,24 +45,24 @@ Starting with Discordeno is very simple, you can start from scratch without any of code into a new TypeScript file: ```ts -import { createBot, Intents, startBot } from "https://deno.land/x/discordeno/mod.ts"; +import { createBot, Intents, startBot } from 'https://deno.land/x/discordeno/mod.ts' startBot( createBot({ - token: "BOT TOKEN", + token: 'BOT TOKEN', intents: Intents.Guilds | Intents.GuildMessages, events: { ready() { - console.log("Successfully connected to gateway"); + console.log('Successfully connected to gateway') }, messageCreate(bot, message) { - if (message.content === "!ping") { - bot.helpers.sendMessage(message.channelId, { content: "Pong using Discordeno!" }); + if (message.content === '!ping') { + bot.helpers.sendMessage(message.channelId, { content: 'Pong using Discordeno!' }) } }, }, }), -); +) ``` ## Tutorials diff --git a/site/docs/migrating.md b/site/docs/migrating.md index c74a33e9c..b99997983 100644 --- a/site/docs/migrating.md +++ b/site/docs/migrating.md @@ -44,118 +44,104 @@ Current Discord.JS Code: ```js /* Keeping this to shoutout/credit the original author <3 -* @author: nukestye -*/ + * @author: nukestye + */ -const config = require("./config.json"); -const fs = require("fs"); -const log = console.log; +const config = require('./config.json') +const fs = require('fs') +const log = console.log // Setting up the way to get commands -const { CommandoClient } = require("discord.js-commando"); -const path = require("path"); +const { CommandoClient } = require('discord.js-commando') +const path = require('path') // reading events -fs.readdir("./src/events/", (err, files) => { - if (err) return console.error(err); +fs.readdir('./src/events/', (err, files) => { + if (err) return console.error(err) files.forEach((file) => { - const eventFunction = require(`./src/events/${file}`); - if (eventFunction.disabled) return; - const event = eventFunction.event || file.split(".")[0]; - const emitter = - (typeof eventFunction.emitter === "string" ? client[eventFunction.emitter] : eventFunction.emitter) || client; - const { once } = eventFunction; + const eventFunction = require(`./src/events/${file}`) + if (eventFunction.disabled) return + const event = eventFunction.event || file.split('.')[0] + const emitter = (typeof eventFunction.emitter === 'string' ? client[eventFunction.emitter] : eventFunction.emitter) || client + const { once } = eventFunction try { - emitter[ - once ? "once" : "on" - ](event, (...args) => eventFunction.run(...args)); + emitter[once ? 'once' : 'on'](event, (...args) => eventFunction.run(...args)) } catch (error) { - console.error(error.stack); + console.error(error.stack) } - }); -}); + }) +}) -const client = global.client = new CommandoClient({ +const client = (global.client = new CommandoClient({ commandPrefix: `${config.prefix}`, owner: `${config.owner}`, invite: `${config.discord}`, unknownCommandResponse: false, -}); +})) // Registing the commands client.registry .registerDefaultTypes() // The different fields for cmds .registerGroups([ - ["mod", "Moderation Commands"], - ["public", "Public Commands"], + ['mod', 'Moderation Commands'], + ['public', 'Public Commands'], ]) .registerDefaultGroups() // Basic cmds can be disabled like {"cmd: false"} .registerDefaultCommands() // commands in "/src/commands" will be counted - .registerCommandsIn(path.join(__dirname, "/src/commands")); + .registerCommandsIn(path.join(__dirname, '/src/commands')) // list of activities that the bot goes through -const activityArray = [`${config.prefix}help | `]; +const activityArray = [`${config.prefix}help | `] // Bot lanuch code -client.once("ready", () => { - log(`Logged in as ${client.user.tag} in ${client.guilds.size} guild(s)!`); +client.once('ready', () => { + log(`Logged in as ${client.user.tag} in ${client.guilds.size} guild(s)!`) setInterval(() => { - const index = Math.floor(Math.random() * (activityArray.length)); // generates a random number between 1 and the length of the activities array list - client.user.setActivity( - activityArray[index], - { - type: "PLAYING", - }, - ); // sets bot"s activities to one of the phrases in the arraylist. - }, 5000); // updates every 10000ms = 10s -}); + const index = Math.floor(Math.random() * activityArray.length) // generates a random number between 1 and the length of the activities array list + client.user.setActivity(activityArray[index], { + type: 'PLAYING', + }) // sets bot"s activities to one of the phrases in the arraylist. + }, 5000) // updates every 10000ms = 10s +}) // If an error print it out -client.on("error", console.error); +client.on('error', console.error) // Login in using the token in config -client.login(config.env.TOKEN); +client.login(config.env.TOKEN) ``` Discordeno Version: ```ts -import { botCache, Intents } from "./deps.ts"; -import { configs } from "./configs.ts"; -import { importDirectory } from "./src/utils/helpers.ts"; -import { loadLanguages } from "./src/utils/i18next.ts"; +import { botCache, Intents } from './deps.ts' +import { configs } from './configs.ts' +import { importDirectory } from './src/utils/helpers.ts' +import { loadLanguages } from './src/utils/i18next.ts' -console.info( - "Beginning Bot Startup Process. This can take a little bit depending on your system. Loading now...", -); +console.info('Beginning Bot Startup Process. This can take a little bit depending on your system. Loading now...') // Always require these files be processed before anything else -await Promise.all([ - "./src/customizations/structures", -].map( - (path) => importDirectory(Deno.realPathSync(path)), -)); +await Promise.all(['./src/customizations/structures'].map((path) => importDirectory(Deno.realPathSync(path)))) // Forces deno to read all the files which will fill the commands/inhibitors cache etc. await Promise.all( [ - "./src/commands", - "./src/inhibitors", - "./src/events", - "./src/arguments", - "./src/monitors", - "./src/tasks", - "./src/permissionLevels", - "./src/events", - ].map( - (path) => importDirectory(Deno.realPathSync(path)), - ), -); + './src/commands', + './src/inhibitors', + './src/events', + './src/arguments', + './src/monitors', + './src/tasks', + './src/permissionLevels', + './src/events', + ].map((path) => importDirectory(Deno.realPathSync(path))), +) // Loads languages -await loadLanguages(); -await import("./src/database/database.ts"); +await loadLanguages() +await import('./src/database/database.ts') startBot({ token: configs.token, @@ -164,7 +150,7 @@ startBot({ intents: Intents.Guilds | Intents.GuildMessages, // These are all your event handler functions. Imported from the events folder events: botCache.events, -}); +}) ``` Something we haven't converted yet from the `main.js` files is the event listeners. To do that, we will open up the @@ -174,40 +160,34 @@ there is already a `ready.ts` file. We can just use that. In our `ready.ts` file we can add the `ready` event listener. ```ts -import { ActivityTypes, botCache, cache, chooseRandom, editBotStatus, StatusTypes } from "../../deps.ts"; -import { registerTasks } from "./../utils/taskHelper.ts"; +import { ActivityTypes, botCache, cache, chooseRandom, editBotStatus, StatusTypes } from '../../deps.ts' +import { registerTasks } from './../utils/taskHelper.ts' botCache.events.ready = function () { - editBotStatus( - StatusTypes.DoNotDisturb, - "Discordeno Best Lib", - ActivityTypes.Game, - ); + editBotStatus(StatusTypes.DoNotDisturb, 'Discordeno Best Lib', ActivityTypes.Game) - console.log(`Loaded ${botCache.arguments.size} Argument(s)`); - console.log(`Loaded ${botCache.commands.size} Command(s)`); - console.log(`Loaded ${Object.keys(botCache.events).length} Event(s)`); - console.log(`Loaded ${botCache.inhibitors.size} Inhibitor(s)`); - console.log(`Loaded ${botCache.monitors.size} Monitor(s)`); - console.log(`Loaded ${botCache.tasks.size} Task(s)`); + console.log(`Loaded ${botCache.arguments.size} Argument(s)`) + console.log(`Loaded ${botCache.commands.size} Command(s)`) + console.log(`Loaded ${Object.keys(botCache.events).length} Event(s)`) + console.log(`Loaded ${botCache.inhibitors.size} Inhibitor(s)`) + console.log(`Loaded ${botCache.monitors.size} Monitor(s)`) + console.log(`Loaded ${botCache.tasks.size} Task(s)`) - registerTasks(); + registerTasks() - console.log( - `[READY] Bot is online and ready in ${cache.guilds.size} guild(s)!`, - ); + console.log(`[READY] Bot is online and ready in ${cache.guilds.size} guild(s)!`) // list of activities that the bot goes through - const activityArray = [`${configs.prefix}help | `]; + const activityArray = [`${configs.prefix}help | `] setInterval(() => { - const randomActivity = activityArray[Math.floor(Math.random() * activityArray.length)]; + const randomActivity = activityArray[Math.floor(Math.random() * activityArray.length)] editBotStatus(botCache, { activities: [{ name: randomActivity, type: ActivityTypes.Game, createdAt: Date.now() }], - status: "online", - }); - }, 5000); -}; + status: 'online', + }) + }, 5000) +} ``` To understand this code, we are setting a function to be run when the bot is `ready`. Then the bot will edit the bot's @@ -228,86 +208,85 @@ This is the code from the bot: ```ts // Getting the 'Command' features from Commando -const { Command } = require("discord.js-commando"); +const { Command } = require('discord.js-commando') // Code for the command module.exports = class addRoleCommand extends Command { constructor(client) { super(client, { // name of the command, must be in lowercase - name: "addrole", + name: 'addrole', // other ways to call the command, must be in lowercase - aliases: ["role"], + aliases: ['role'], // command group its part of - group: "mod", + group: 'mod', // name within the command group, must be in lowercase - memberName: "addrole", + memberName: 'addrole', // Is the description used for 'help' command - description: "Adds mentioned role to mentioned user.", + description: 'Adds mentioned role to mentioned user.', // Prevents it from being used in dms guildOnly: true, // Permissions, list found here > `discord.js.org/#/docs/main/11.5.1/class/Permissions?scrollTo=s-FLAGS` - clientPermissions: ["ADMINISTRATOR", "MANAGE_ROLES"], - userPermissions: ["MANAGE_ROLES"], + clientPermissions: ['ADMINISTRATOR', 'MANAGE_ROLES'], + userPermissions: ['MANAGE_ROLES'], // Prevents anyone other than owner to use the command ownerOnly: false, - }); + }) } // Run code goes here run(message) { - const user = message.mentions.members.first(); - const roleToAdd = message.mentions.roles.first(); + const user = message.mentions.members.first() + const roleToAdd = message.mentions.roles.first() // checking to see if the user has the role or not - if (!(user.roles.find((r) => r.name === roleToAdd.name))) { - user.addRole(roleToAdd); - message.channel.send(`${user} has been given the role: ${roleToAdd.name}`) - .then((msg) => { - msg.delete(5000); - }); + if (!user.roles.find((r) => r.name === roleToAdd.name)) { + user.addRole(roleToAdd) + message.channel.send(`${user} has been given the role: ${roleToAdd.name}`).then((msg) => { + msg.delete(5000) + }) } else { - message.channel.send(`${user} already has the role: ${roleToAdd.name}`); + message.channel.send(`${user} already has the role: ${roleToAdd.name}`) } // console.error(user, roleToAdd, message.member.roles.find(r => r.name === roleToAdd)); } -}; +} ``` This is how to do it with Discordeno: ```ts -import { createCommand } from "./../../utils/helpers.ts"; +import { createCommand } from './../../utils/helpers.ts' createCommand({ - name: "role", + name: 'role', // Oher ways to call the command - aliases: ["addrole"], + aliases: ['addrole'], // Is the description used for 'help' command - description: "Adds mentioned role to mentioned user.", + description: 'Adds mentioned role to mentioned user.', // Prevents it from being used in dms guildOnly: true, - botServerPermissions: ["ADMINISTRATOR", "MANAGE_ROLES"], - userServerPermissions: ["MANAGE_ROLES"], + botServerPermissions: ['ADMINISTRATOR', 'MANAGE_ROLES'], + userServerPermissions: ['MANAGE_ROLES'], arguments: [ - { name: "member", type: "member" }, - { name: "role", type: "role" }, + { name: 'member', type: 'member' }, + { name: 'role', type: 'role' }, ], execute: (bot, message, args) => { // checking to see if the user has the role or not if (!args.member.roles.includes(args.role.id)) { - bot.helpers.addRole(message.guildId, args.member.id, args.role.id); + bot.helpers.addRole(message.guildId, args.member.id, args.role.id) bot.helpers.sendMessage(message.channelId, { content: `${args.member.mention} has been given the role: ${args.role.name}`, - }); + }) } else { bot.helpers.sendMessage(message.channelId, { content: `${args.member.mention} already has the role: ${args.role.name}`, - }); + }) } }, -}); +}) ``` Awesome, that is a full command converted from Discord.JS to Discordeno. See how easy it is! Let's convert one more @@ -317,25 +296,25 @@ Discord.JS Kick Command Version ```js // Getting the 'Command' features from Commando -const { Command } = require("discord.js-commando"); -const { RichEmbed } = require("discord.js"); -const chalk = require("chalk"); -const log = console.log; +const { Command } = require('discord.js-commando') +const { RichEmbed } = require('discord.js') +const chalk = require('chalk') +const log = console.log // Code for the command module.exports = class kickCommand extends Command { constructor(client) { super(client, { // name of the command, must be in lowercase - name: "kick", + name: 'kick', // other ways to call the command, must be in lowercase - aliases: ["boot", "tempban"], + aliases: ['boot', 'tempban'], // command group its part of - group: "mod", + group: 'mod', // name within the command group, must be in lowercase - memberName: "kick", + memberName: 'kick', // Is the description used for 'help' command - description: "Kick command.", + description: 'Kick command.', // adds cooldowns to the command throttling: { // usages in certain time x @@ -346,57 +325,52 @@ module.exports = class kickCommand extends Command { // Prevents it from being used in dms guildOnly: true, // Permissions, list found here > `discord.js.org/#/docs/main/11.5.1/class/Permissions?scrollTo=s-FLAGS` - clientPermissions: ["ADMINISTRATOR"], - userPermissions: ["KICK_MEMBERS"], + clientPermissions: ['ADMINISTRATOR'], + userPermissions: ['KICK_MEMBERS'], // Prevents anyone other than owner to use the command ownerOnly: false, - }); + }) } // Run code goes here run(message) { - const messageArry = message.content.split(" "); - const args = messageArry.slice(1); + const messageArry = message.content.split(' ') + const args = messageArry.slice(1) - const kUser = message.guild.member( - message.mentions.users.first() || message.guild.get(args[0]), - ); - if (!kUser) return message.channel.send("User cannot be found!"); - const kreason = args.join(" ").slice(22); + const kUser = message.guild.member(message.mentions.users.first() || message.guild.get(args[0])) + if (!kUser) return message.channel.send('User cannot be found!') + const kreason = args.join(' ').slice(22) // setting up the embed for report/log - const kickEmbed = new RichEmbed() - .setDescription(`Report: ${kUser} Kick`) - .addField("Reason >", `${kreason}`) - .addField("Time", message.createdAt); + const kickEmbed = new RichEmbed().setDescription(`Report: ${kUser} Kick`).addField('Reason >', `${kreason}`).addField('Time', message.createdAt) - const reportchannel = message.guild.channels.find("name", "report"); + const reportchannel = message.guild.channels.find('name', 'report') if (!reportchannel) { - return message.channel.send("*`Report channel cannot be found!`*"); + return message.channel.send('*`Report channel cannot be found!`*') } // Delete the message command // eslint-disable-next-line camelcase - message.delete().catch((O_o) => {}); + message.delete().catch((O_o) => {}) // Kick the user with reason - message.guild.member(kUser).kick(kreason); + message.guild.member(kUser).kick(kreason) // sends the kick report into log/report - reportchannel.send(kickEmbed); + reportchannel.send(kickEmbed) // Logs the kick into the terminal - log(chalk.red("KICK", chalk.underline.bgBlue(kUser) + "!")); + log(chalk.red('KICK', chalk.underline.bgBlue(kUser) + '!')) } -}; +} ``` Discordeno Version ```ts -import { createCommand } from "./../../utils/helpers.ts"; +import { createCommand } from './../../utils/helpers.ts' createCommand({ name: `kick`, - aliases: ["boot", "tempban"], - description: "Kick command.", + aliases: ['boot', 'tempban'], + description: 'Kick command.', // adds cooldowns to the command cooldown: { // usages in certain duration of seconds below @@ -406,23 +380,23 @@ createCommand({ }, // Prevents it from being used in dms guildOnly: true, - botServerPermissions: ["ADMINISTRATOR"], - userServerPermissions: ["KICK_MEMBERS"], + botServerPermissions: ['ADMINISTRATOR'], + userServerPermissions: ['KICK_MEMBERS'], arguments: [ { - name: "member", - type: "member", + name: 'member', + type: 'member', missing: function (message) { - message.reply(`User cannot be found.`); + message.reply(`User cannot be found.`) }, // By default this is true but for the purpose of the guide so you can see this exists. required: true, }, { - name: "reason", + name: 'reason', // The leftover string provided by the user that was not used by previous args. - type: "...string", - defaultValue: "No reason provided.", + type: '...string', + defaultValue: 'No reason provided.', // It is silly to lowercase this but for the purpose of the guide you can see that this is also available to you. lowercase: true, }, @@ -431,26 +405,26 @@ createCommand({ // setting up the embed for report/log const embed = new Embed() .setDescription(`Report: ${args.member.mention} Kick`) - .addField("Reason >", args.reason) - .addField("Time", message.timestamp.toString()); + .addField('Reason >', args.reason) + .addField('Time', message.timestamp.toString()) - const reportchannel = message.guild?.channels.find((channel) => channel.name === "report"); + const reportchannel = message.guild?.channels.find((channel) => channel.name === 'report') if (!reportchannel) { - return bot.helpers.sendMessage(message.channelId, { content: "*`Report channel cannot be found!`*" }); + return bot.helpers.sendMessage(message.channelId, { content: '*`Report channel cannot be found!`*' }) } // Delete the message command - bot.helpers.deleteMessage(message.channelId, { content: "Remove kick command trigger." }); + bot.helpers.deleteMessage(message.channelId, { content: 'Remove kick command trigger.' }) // Kick the user with reason - bot.helpers.kickMember(message.guildId, args.member.id, args.reason); + bot.helpers.kickMember(message.guildId, args.member.id, args.reason) // sends the kick report into log/report - bot.helpers.sendMessage(message.channelId, { embeds: [embed] }); + bot.helpers.sendMessage(message.channelId, { embeds: [embed] }) }, -}); +}) interface KickArgs { - member: Member; - reason: string; + member: Member + reason: string } ``` diff --git a/site/docs/nodejs/CommandHandler/command-manager.md b/site/docs/nodejs/CommandHandler/command-manager.md index 135a13edc..354be6a83 100644 --- a/site/docs/nodejs/CommandHandler/command-manager.md +++ b/site/docs/nodejs/CommandHandler/command-manager.md @@ -7,24 +7,24 @@ sidebar_position: 2 Currently, you probably have something like this in your code: ```js -const Discord = require("discordeno.js"); +const Discord = require('discordeno.js') // Ideally you should move to an `.env` file -const config = require("./config.json"); +const config = require('./config.json') const bot = Discord.createBot({ events: { messageCreate(client, message) { - if (message.content === "!ping") { - client.helpers.sendMessage(message.channelId, { content: "pong" }); + if (message.content === '!ping') { + client.helpers.sendMessage(message.channelId, { content: 'pong' }) } }, }, intents: Discord.Intents.Guilds | Discord.Intents.GuildMessages, token: config.token, -}); -const client = Discord.enableCachePlugin(bot, {}); +}) +const client = Discord.enableCachePlugin(bot, {}) -Discord.startBot(client); +Discord.startBot(client) ``` Of course, if you add more and more commands and as your code base grows, you can lose track very quickly. @@ -50,12 +50,12 @@ To avoid this, it is recommended to store the commands in separate folders divid the [nodejs template](https://github.com/discordeno/discordeno/tree/main/template)** ```js -const CommandManager = require("./template/Managers/CommandManager.js"); -const manager = new CommandManager({}); -manager.load({ plugin: true }); // Load the commands -client.commands = manager; +const CommandManager = require('./template/Managers/CommandManager.js') +const manager = new CommandManager({}) +manager.load({ plugin: true }) // Load the commands +client.commands = manager -client.commands.cache.get("ping"); // Get the `ping` command +client.commands.cache.get('ping') // Get the `ping` command ``` The Manager will automatically iterate through all files in the folder and then load them into the cache property, which @@ -77,16 +77,16 @@ Currently checks for permissions, cooldowns, and rate limits are not covered, bu ```js module.exports = async (client, message) => { - client.commands.isCommand(message); -}; + client.commands.isCommand(message) +} ``` ### Interaction Create Event: ```js module.exports = async (client, interaction) => { - client.commands.isInteraction(interaction); -}; + client.commands.isInteraction(interaction) +} ``` You can also customize the `isCommand` function to your use case. diff --git a/site/docs/nodejs/EventHandler/event-manager.md b/site/docs/nodejs/EventHandler/event-manager.md index bb95281ee..4b02135d7 100644 --- a/site/docs/nodejs/EventHandler/event-manager.md +++ b/site/docs/nodejs/EventHandler/event-manager.md @@ -7,28 +7,28 @@ sidebar_position: 2 In order to process certain events, you must provide the Discordeno client with functions for these events. ```js -const Discord = require("discordeno"); -const config = require("./config.json"); +const Discord = require('discordeno') +const config = require('./config.json') const client = Discord.createBot({ events: { ready(client, payload) { - console.log(`Successfully connected Shard ${payload.shardId} to the gateway`); + console.log(`Successfully connected Shard ${payload.shardId} to the gateway`) }, async messageCreate(client, message) { - if (message.content === "!ping") { - await client.helpers.sendMessage(message.channelId, { content: "pong" }); + if (message.content === '!ping') { + await client.helpers.sendMessage(message.channelId, { content: 'pong' }) } - console.log(`Received message: ${message.content || message.embeds}`); + console.log(`Received message: ${message.content || message.embeds}`) }, }, - intents: ["Guilds", "GuildMessages"], + intents: ['Guilds', 'GuildMessages'], token: config.token, -}); +}) -Discord.startBot(client); +Discord.startBot(client) ``` As you listen to more and more events, the functions code grows along with them, so you can quickly lose track. @@ -52,42 +52,42 @@ Ready Event: module.exports = (client, payload) => { if (payload.shardId + 1 === client.gateway.maxShards) { // All Shards are ready - console.log(`Successfully connected to the gateway as ${payload.user.username}#${payload.user.discriminator}`); + console.log(`Successfully connected to the gateway as ${payload.user.username}#${payload.user.discriminator}`) } -}; +} ``` ## Load your Events ```js -const fs = require("fs"); -const path = require("path"); +const fs = require('fs') +const path = require('path') -const resolveFolder = (folderName) => path.resolve(__dirname, ".", folderName); +const resolveFolder = (folderName) => path.resolve(__dirname, '.', folderName) class EventManager { constructor(client) { - this.cache = new Map(); - this._events = {}; + this.cache = new Map() + this._events = {} } load(options = {}) { - const eventsFolder = resolveFolder("../events"); + const eventsFolder = resolveFolder('../events') fs.readdirSync(eventsFolder).map(async (file) => { - if (!file.endsWith(".js")) return; + if (!file.endsWith('.js')) return - const fileName = path.join(eventsFolder, file); - const event = require(fileName); - const eventName = file.split(".")[0]; + const fileName = path.join(eventsFolder, file) + const event = require(fileName) + const eventName = file.split('.')[0] - this._events[`${eventName}`] = event; - }); + this._events[`${eventName}`] = event + }) - return this._events; + return this._events } } -module.exports = EventManager; +module.exports = EventManager ``` The code above, which can also be found in the @@ -98,19 +98,19 @@ In order to let the client know which events should be processed, you need to pa `createBot.events` object. ```js -const Discord = require("discordeno"); -const config = require("./config.json"); +const Discord = require('discordeno') +const config = require('./config.json') -const EventManager = require("./Managers/EventManager.js"); -const events = new EventManager({}); +const EventManager = require('./Managers/EventManager.js') +const events = new EventManager({}) const client = Discord.createBot({ events: events.load({}), - intents: ["Guilds", "GuildMessages"], + intents: ['Guilds', 'GuildMessages'], token: config.token, -}); +}) -Discord.startBot(client); +Discord.startBot(client) ``` Moreover, you can customize the `EventManager` and add more functionality to it and make it exactly fit your needs or diff --git a/site/docs/nodejs/EventHandler/handle-event.md b/site/docs/nodejs/EventHandler/handle-event.md index 2429f7f1d..12e3eee9a 100644 --- a/site/docs/nodejs/EventHandler/handle-event.md +++ b/site/docs/nodejs/EventHandler/handle-event.md @@ -24,14 +24,14 @@ Sometimes it's important to listen to events, in order to get informed of change This file should be called `messageCreate.js`. ```js -const Message = require("./structures/Message"); +const Message = require('./structures/Message') module.exports = async (client, payload) => { - const message = client.messages.forge(payload); + const message = client.messages.forge(payload) - if (message.author.bot) return; - if (message.content === "!ping") return await message.reply("pong"); -}; + if (message.author.bot) return + if (message.content === '!ping') return await message.reply('pong') +} ``` ### Interaction Event @@ -39,13 +39,13 @@ module.exports = async (client, payload) => { This file should be called `interactionCreate.js`. ```js -const Interaction = require("./structures/Interaction"); +const Interaction = require('./structures/Interaction') module.exports = async (client, payload) => { - const interaction = client.interactions.forge(payload); + const interaction = client.interactions.forge(payload) - if (interaction.data.name === "ping") return await interaction.reply({ content: "pong" }); -}; + if (interaction.data.name === 'ping') return await interaction.reply({ content: 'pong' }) +} ``` ### Ready Event @@ -62,14 +62,14 @@ a `shard` becomes ready. In order to fire the "real event" a small code snippet has to be added to the `ready` Event. ```js -const User = require("../Structures/User"); +const User = require('../Structures/User') module.exports = async (client, payload) => { - client.user = client.users.forge(payload.user); + client.user = client.users.forge(payload.user) if (payload.shardId + 1 === client.gateway.maxShards) { // All Shards are ready - console.log(`Successfully connected to the gateway as ${client.user.tag}`); + console.log(`Successfully connected to the gateway as ${client.user.tag}`) } -}; +} ``` diff --git a/site/docs/nodejs/Structures/collectors.md b/site/docs/nodejs/Structures/collectors.md index f999a8957..aa5233898 100644 --- a/site/docs/nodejs/Structures/collectors.md +++ b/site/docs/nodejs/Structures/collectors.md @@ -22,27 +22,27 @@ We have a pre-made class for collectors which you can find [here](https://github.com/meister03/discordeno.js/blob/master/Util/Collectors.js). ```js -const Discord = require("discordeno.js"); -const filter = (m) => m.data?.customId === "warn_modal" && m.user.id === interaction.user.id; -const listener = client.eventListener; // When the eventListener property is named different -const collector = new Discord.Collector("interactionCreate", { +const Discord = require('discordeno.js') +const filter = (m) => m.data?.customId === 'warn_modal' && m.user.id === interaction.user.id +const listener = client.eventListener // When the eventListener property is named different +const collector = new Discord.Collector('interactionCreate', { client: client, timeout: 60000, filter, max: 20, listener, -}); -collector.on("collect", (m) => { - const interaction = client.interactions.forge(m); +}) +collector.on('collect', (m) => { + const interaction = client.interactions.forge(m) // Stop Collector // collector.stop(); -}); +}) // Fires on a timeout, when the collector has reached the max amount of interactions or when it has been closed -collector.on("end", (collected) => { +collector.on('end', (collected) => { // Map of Collected Interactions - console.log(collected); -}); + console.log(collected) +}) ``` As you can see, this opens up many possibilities. You can listen to any event and get the interaction you need. diff --git a/site/docs/nodejs/Structures/components.md b/site/docs/nodejs/Structures/components.md index 123d52b70..edb9bf516 100644 --- a/site/docs/nodejs/Structures/components.md +++ b/site/docs/nodejs/Structures/components.md @@ -82,20 +82,20 @@ component you want to use. ```js class ActionRow { constructor(options = {}) { - this.type = 1; + this.type = 1 } setComponents(...components) { - this.components = components; - return this; + this.components = components + return this } } ``` ```js -const button = new Button(); -const button2 = new Button(); -const actionRow = new ActionRow().setComponents(button, button2); +const button = new Button() +const button2 = new Button() +const actionRow = new ActionRow().setComponents(button, button2) ``` This code will obviously not work because it's a missing a lot required of data. The other reason is that we can't send @@ -107,34 +107,21 @@ We have a pre-made class for components which you can find ### Button ```js -const Discord = require("discordeno.js"); -const message = client.messages.forge(rawMessage); +const Discord = require('discordeno.js') +const message = client.messages.forge(rawMessage) -const button = new Discord.Component() - .setType("BUTTON") - .setStyle("LINK") - .setLabel("Click me!") - .setUrl("https://google.com") - .toJSON(); +const button = new Discord.Component().setType('BUTTON').setStyle('LINK').setLabel('Click me!').setUrl('https://google.com').toJSON() // Button with raw types -const button2 = new Discord.Component() - .setType(2) - .setStyle(4) - .setLabel("DO NOT CLICK") - .setCustomId("12345") - .toJSON(); +const button2 = new Discord.Component().setType(2).setStyle(4).setLabel('DO NOT CLICK').setCustomId('12345').toJSON() -const actionRow = new Discord.Component() - .setType("ACTION_ROW") - .setComponents(button, button2) - .toJSON(); +const actionRow = new Discord.Component().setType('ACTION_ROW').setComponents(button, button2).toJSON() // Message to send -const messageOptions = { content: "hello", components: [actionRow] }; +const messageOptions = { content: 'hello', components: [actionRow] } // await client.helpers.sendMessage(channelId, messageOptions); // Do it the raw way -message.channel.send(messageOptions); // Do it with the structure +message.channel.send(messageOptions) // Do it with the structure ``` As you can see, for simplicity you can use strings instead of numbers (types), which are hard to remember. @@ -142,79 +129,76 @@ As you can see, for simplicity you can use strings instead of numbers (types), w ### Select Menu ```js -const Discord = require("discordeno.js"); -const message = client.messages.forge(rawMessage); +const Discord = require('discordeno.js') +const message = client.messages.forge(rawMessage) const selectMenu = new Discord.Component() - .setType("SELECT_MENU") - .setCustomId("12345") + .setType('SELECT_MENU') + .setCustomId('12345') .setOptions([ { - label: "Option 1", - value: "1", + label: 'Option 1', + value: '1', description: `This is option 1`, }, { - label: "Option 2", - value: "2", + label: 'Option 2', + value: '2', description: `This is option 2`, }, { - label: "Default Option", - value: "3", + label: 'Default Option', + value: '3', description: `Default option...`, default: true, }, ]) - .setPlaceholder("Select an option") - .toJSON(); + .setPlaceholder('Select an option') + .toJSON() -const actionRow = new Discord.Component() - .setType("ACTION_ROW") - .setComponents(selectMenu) - .toJSON(); +const actionRow = new Discord.Component().setType('ACTION_ROW').setComponents(selectMenu).toJSON() -const messageOptions = { content: "hello", components: [actionRow] }; +const messageOptions = { content: 'hello', components: [actionRow] } // await client.helpers.sendMessage(channelId, messageOptions); // Do it the raw way -message.channel.send(messageOptions); // Do it with the structure +message.channel.send(messageOptions) // Do it with the structure ``` ### Text Input ```js -const Discord = require("discordeno.js"); -const interaction = client.messages.forge(rawInteraction); +const Discord = require('discordeno.js') +const interaction = client.messages.forge(rawInteraction) const textInput = new Component() - .setType("TEXT_INPUT") - .setStyle("SHORT") - .setCustomId("t1") - .setLabel("User ID") - .setPlaceholder("User ID") + .setType('TEXT_INPUT') + .setStyle('SHORT') + .setCustomId('t1') + .setLabel('User ID') + .setPlaceholder('User ID') .setRequired(true) .setMaxLength(20) .setMinLength(1) - .toJSON(); + .toJSON() const textInput2 = new Component() - .setType("TEXT_INPUT") - .setStyle("PARAGRAPH") - .setCustomId("t2") - .setLabel("Reason") - .setPlaceholder("Reason for Ban") + .setType('TEXT_INPUT') + .setStyle('PARAGRAPH') + .setCustomId('t2') + .setLabel('Reason') + .setPlaceholder('Reason for Ban') .setRequired(false) .setMaxLength(300) - .toJSON(); + .toJSON() -const actionRow = new Component().setType("ACTION_ROW").setComponents(textInput).toJSON(); -const actionRow2 = new Component().setType("ACTION_ROW").setComponents(textInput2).toJSON(); +const actionRow = new Component().setType('ACTION_ROW').setComponents(textInput).toJSON() +const actionRow2 = new Component().setType('ACTION_ROW').setComponents(textInput2).toJSON() interaction.popupModal({ - customId: "ban_modal", - title: "Ban User", + customId: 'ban_modal', + title: 'Ban User', components: [actionRow, actionRow2], -}); +}) ``` ### Receive Interactions diff --git a/site/docs/nodejs/Structures/create-structure.md b/site/docs/nodejs/Structures/create-structure.md index 3be34dd12..7bbaa6c4d 100644 --- a/site/docs/nodejs/Structures/create-structure.md +++ b/site/docs/nodejs/Structures/create-structure.md @@ -11,14 +11,14 @@ Imagine you have a channel object to which you want to send a message. ```js const data = { id: 806947972004839444n, - name: "spam-and-bots", -}; + name: 'spam-and-bots', +} ``` The recommended way would be: ```js -await client.helpers.sendMessage(data.id, { content: "hello" }); +await client.helpers.sendMessage(data.id, { content: 'hello' }) ``` However, you probably want to use something shorter, such as the following: @@ -26,13 +26,13 @@ However, you probably want to use something shorter, such as the following: ```js class Channel { constructor(client, data) { - this.client = client; - this.id = data.id; - this.name = data.name; + this.client = client + this.id = data.id + this.name = data.name } async send(options) { - return await this.client.helpers.sendMessage(this.id, options); + return await this.client.helpers.sendMessage(this.id, options) } } ``` @@ -40,8 +40,8 @@ class Channel { Now you can use the `.send()` method on the channel object without using such a long code: ```js -const channel = new Channel(client, data); -await channel.send({ content: "hello" }); +const channel = new Channel(client, data) +await channel.send({ content: 'hello' }) ``` Moreover, you can modify the `.send()` method to better suit your use case e.g not send the message if the channel is @@ -74,22 +74,22 @@ construct the client for following the Guide **Using the Structures:** ```js -const Discord = require("discordeno.js"); -const client = new Discord.Client(clientOptions, cacheOptions); //See the Readme above -Discord.startBot(client); -const guild = client.guilds.forge(guildData); -const channel = guild.channels.forge(channelData); -const role = guild.roles.forge(roleData); -const member = guild.members.forge(memberData); -const user = guild.users.forge(userData); -const message = guild.messages.forge(messageData); -const interaction = guild.interactions.forge(interactionData); -const emoji = guild.emojis.forge(emojiData); +const Discord = require('discordeno.js') +const client = new Discord.Client(clientOptions, cacheOptions) //See the Readme above +Discord.startBot(client) +const guild = client.guilds.forge(guildData) +const channel = guild.channels.forge(channelData) +const role = guild.roles.forge(roleData) +const member = guild.members.forge(memberData) +const user = guild.users.forge(userData) +const message = guild.messages.forge(messageData) +const interaction = guild.interactions.forge(interactionData) +const emoji = guild.emojis.forge(emojiData) -const webhook = new Discord.Webhook(client, webhookData); -const embed = new Discord.Embed(embedData); // embedData is optional -const component = new Discord.Component(componentData); // componentData is optional -const collection = new Discord.Collection(); +const webhook = new Discord.Webhook(client, webhookData) +const embed = new Discord.Embed(embedData) // embedData is optional +const component = new Discord.Component(componentData) // componentData is optional +const collection = new Discord.Collection() ``` Some popular methods have been added to the structures so that you can use them without having to come up with your own. diff --git a/site/docs/nodejs/Structures/embeds.md b/site/docs/nodejs/Structures/embeds.md index 9c2864e16..2a0f0face 100644 --- a/site/docs/nodejs/Structures/embeds.md +++ b/site/docs/nodejs/Structures/embeds.md @@ -32,7 +32,7 @@ Now we have created a class which we can use to create embeds. But we can't just So we need an additional method which will convert the data from the class to the correct format. ```js -class Embed(){ +class Embed(){ constructor() {} setTitle(title) { @@ -50,10 +50,10 @@ class Embed(){ Wow, now you can create a embed and send it to Discord. ```js -const Channel = require("./structures/Channel"); // Path to structure +const Channel = require('./structures/Channel') // Path to structure -const channel = new Channel(client, data); -await channel.send({ embeds: [embed] }); +const channel = new Channel(client, data) +await channel.send({ embeds: [embed] }) ``` You probably want more methods which you can use to create embeds. @@ -62,36 +62,36 @@ You probably want more methods which you can use to create embeds. ### Using the Embed Structure: ```js -const Discord = require("discordeno.js"); +const Discord = require('discordeno.js') -const channel = client.channels.forge(channelData); +const channel = client.channels.forge(channelData) const showCaseEmbed = new Discord.Embed() - .setColor(0x00AE86) - .setTitle("A Random Title") - .setURL("https://github.com/discordeno") + .setColor(0x00ae86) + .setTitle('A Random Title') + .setURL('https://github.com/discordeno') .setAuthor({ - name: "Author name", - iconUrl: "https://raw.githubusercontent.com/discordeno/discordeno/main/site/static/img/logo.png", - url: "https://github.com/discordeno", + name: 'Author name', + iconUrl: 'https://raw.githubusercontent.com/discordeno/discordeno/main/site/static/img/logo.png', + url: 'https://github.com/discordeno', }) - .setDescription("A Random Description") - .setThumbnail("https://raw.githubusercontent.com/discordeno/discordeno/main/site/static/img/logo.png") + .setDescription('A Random Description') + .setThumbnail('https://raw.githubusercontent.com/discordeno/discordeno/main/site/static/img/logo.png') .addFields( - { name: "Field 1 Name", value: "Normal Field Value" }, - { name: "\u200B", value: "\u200B" }, - { name: "Field 2 Name", value: "Inline Field Value", inline: true }, - { name: "Field 3 Name", value: "Inline Field Value", inline: true }, + { name: 'Field 1 Name', value: 'Normal Field Value' }, + { name: '\u200B', value: '\u200B' }, + { name: 'Field 2 Name', value: 'Inline Field Value', inline: true }, + { name: 'Field 3 Name', value: 'Inline Field Value', inline: true }, ) - .addField({ name: "Field 4", value: "Field Value" }) - .setImage("https://raw.githubusercontent.com/discordeno/discordeno/main/site/static/img/logo.png") + .addField({ name: 'Field 4', value: 'Field Value' }) + .setImage('https://raw.githubusercontent.com/discordeno/discordeno/main/site/static/img/logo.png') .setTimestamp() .setFooter({ - text: "A Footer Text", - iconUrl: "https://raw.githubusercontent.com/discordeno/discordeno/main/site/static/img/logo.png", + text: 'A Footer Text', + iconUrl: 'https://raw.githubusercontent.com/discordeno/discordeno/main/site/static/img/logo.png', }) - .toJSON(); + .toJSON() -await channel.send({ embeds: [showCaseEmbed] }); +await channel.send({ embeds: [showCaseEmbed] }) ``` ### Embed Limits: diff --git a/site/docs/nodejs/Structures/getting-started.md b/site/docs/nodejs/Structures/getting-started.md index 1898e757b..b06806d6d 100644 --- a/site/docs/nodejs/Structures/getting-started.md +++ b/site/docs/nodejs/Structures/getting-started.md @@ -9,7 +9,7 @@ As previously mentioned, Discordeno was built with as few classes as possible, t For example, you cannot execute functions on objects. ```diff -- message.channel.send({content: "hello"}) +- message.channel.send({content: "hello"}) + client.helpers.sendMessage(message.channel.id, {content: "hello"}) ``` diff --git a/site/docs/nodejs/design.md b/site/docs/nodejs/design.md index 580e70c7b..86dacc19b 100644 --- a/site/docs/nodejs/design.md +++ b/site/docs/nodejs/design.md @@ -87,9 +87,9 @@ Example: ```js class Command { - static name = "ping"; - static aliases = ["pong"]; - static botPermission = ["SEND_EMBED_LINKS"]; + static name = 'ping' + static aliases = ['pong'] + static botPermission = ['SEND_EMBED_LINKS'] run(message, args) { // do something @@ -106,17 +106,17 @@ by each command. Extending the class makes this extra step obsolete. ```js class BaseCommand { constructor(client) { - this.client = client; - this.basePermission = ["SEND_EMBED_LINKS"]; + this.client = client + this.basePermission = ['SEND_EMBED_LINKS'] } } class Command extends BaseCommand { - static name = "ping"; - static aliases = ["pong"]; + static name = 'ping' + static aliases = ['pong'] constructor(data) { - super(data); + super(data) } run(message, args) { diff --git a/site/docs/nodejs/initial-setup.md b/site/docs/nodejs/initial-setup.md index 04ab56456..3b3cc0c10 100644 --- a/site/docs/nodejs/initial-setup.md +++ b/site/docs/nodejs/initial-setup.md @@ -23,20 +23,20 @@ Create a file named `config.json` in your project folder and insert the followin Open the `index.js` file which you have created earlier and then insert the following content: ```js -const Discord = require("discordeno"); -const config = require("./config.json"); +const Discord = require('discordeno') +const config = require('./config.json') const client = Discord.createBot({ events: { ready(client, payload) { - console.log(`Successfully connected Shard ${payload.shardId} to the gateway`); + console.log(`Successfully connected Shard ${payload.shardId} to the gateway`) }, }, - intents: ["Guilds", "GuildMessages"], + intents: ['Guilds', 'GuildMessages'], token: config.token, -}); +}) -Discord.startBot(client); +Discord.startBot(client) ``` Now you can start your bot by running the following command in your terminal: diff --git a/site/docs/nodejs/slash-command.md b/site/docs/nodejs/slash-command.md index b5effda76..d507d15cf 100644 --- a/site/docs/nodejs/slash-command.md +++ b/site/docs/nodejs/slash-command.md @@ -18,14 +18,14 @@ commands show up directly. For this reason, we will now show how to create guild commands, in order to test them immediately. ```js -const guildId = BigInt("YOUR_GUILD_ID"); +const guildId = BigInt('YOUR_GUILD_ID') const command = { - name: "ping", - description: "Retrieves the Bot latency", + name: 'ping', + description: 'Retrieves the Bot latency', options: [], -}; +} -client.helpers.createApplicationCommand(command, guildId); +client.helpers.createApplicationCommand(command, guildId) ``` This is just very simple example, you can also add sub commands, select options and much more. @@ -36,28 +36,28 @@ Discord sends a WebSocket Event when a user runs a slash command. You can listen `interactionCreate` function in the client. ```js -const Discord = require("discordeno"); -const config = require("./config.json"); +const Discord = require('discordeno') +const config = require('./config.json') const client = Discord.createBot({ events: { ready(client, payload) { - console.log(`Successfully connected Shard ${payload.shardId} to the gateway`); + console.log(`Successfully connected Shard ${payload.shardId} to the gateway`) }, async interactionCreate(client, interaction) { - if (interaction.data?.name === "ping") { + if (interaction.data?.name === 'ping') { return await client.helpers.sendInteractionResponse(interaction.id, interaction.token, { type: Discord.InteractionResponseTypes.ChannelMessageWithSource, - data: { content: "🏓 Pong!" }, - }); + data: { content: '🏓 Pong!' }, + }) } }, }, intents: Discord.Intents.Guilds | Discord.Intents.GuildMessages, token: config.token, -}); +}) -Discord.startBot(client); +Discord.startBot(client) ``` The handling may see complicated in the beginning, but as mentioned before, we will introduce structures to make it diff --git a/site/src/components/Benchmark.tsx b/site/src/components/Benchmark.tsx index f69d4589b..f936cf8b1 100644 --- a/site/src/components/Benchmark.tsx +++ b/site/src/components/Benchmark.tsx @@ -1,49 +1,42 @@ -import { - CategoryScale, - Chart as ChartJS, - Legend, - LinearScale, - LineController, - LineElement, - PointElement, - Title, - Tooltip, -} from "chart.js"; -import React, { useEffect, useState } from "react"; -import { Chart } from "react-chartjs-2"; -ChartJS.register(CategoryScale, LineController, LinearScale, PointElement, LineElement, Title, Tooltip, Legend); +import { CategoryScale, Chart as ChartJS, Legend, LinearScale, LineController, LineElement, PointElement, Title, Tooltip } from 'chart.js' +import React, { useEffect, useState } from 'react' +import { Chart } from 'react-chartjs-2' +ChartJS.register(CategoryScale, LineController, LinearScale, PointElement, LineElement, Title, Tooltip, Legend) -const BenchmarkResultChart = ({ name, dataset }: { - name: string; +const BenchmarkResultChart = ({ + name, + dataset, +}: { + name: string dataset: { bench: { - name: string; - range: string | number; - unit: string; - value: string | number; - extra: string | number | undefined; - }; + name: string + range: string | number + unit: string + value: string | number + extra: string | number | undefined + } commit: { author: { - email: string; - name: string; - username: string; - }; + email: string + name: string + username: string + } committer: { - email: string; - name: string; - username: string; - }; - distinct: true; - id: string; - message: string; - timestamp: string; - tree_id: string; - url: string; - }; - date: number; - tool: string; - }[]; + email: string + name: string + username: string + } + distinct: true + id: string + message: string + timestamp: string + tree_id: string + url: string + } + date: number + tool: string + }[] }) => { const data = { labels: dataset.map((d) => d.commit.id.slice(0, 7)), @@ -51,11 +44,11 @@ const BenchmarkResultChart = ({ name, dataset }: { { label: name, data: dataset.map((d) => d.bench.value), - borderColor: "#ff3838", - backgroundColor: "#ff383860", // Add alpha for #rrggbbaa + borderColor: '#ff3838', + backgroundColor: '#ff383860', // Add alpha for #rrggbbaa }, ], - }; + } return ( 0 ? dataset[0].bench.unit : "", + text: dataset.length > 0 ? dataset[0].bench.unit : '', }, beginAtZero: true, }, @@ -82,92 +75,81 @@ const BenchmarkResultChart = ({ name, dataset }: { tooltip: { callbacks: { afterTitle: (items) => { - const index = items[0].dataIndex; - const data = dataset[index]; - return "\n" + data.commit.message + "\n\n" + data.commit.timestamp + " committed by @" + - data.commit.author.username + "\n"; + const index = items[0].dataIndex + const data = dataset[index] + return '\n' + data.commit.message + '\n\n' + data.commit.timestamp + ' committed by @' + data.commit.author.username + '\n' }, label: (item) => { - let label = item.formattedValue; - const { range, unit } = dataset[item.datasetIndex].bench; - label += " " + unit; + let label = item.formattedValue + const { range, unit } = dataset[item.datasetIndex].bench + label += ' ' + unit if (range) { - label += " (" + range + ")"; + label += ' (' + range + ')' } - return label; + return label }, afterLabel: (item) => { - const { extra } = dataset[item.datasetIndex].bench; - return extra ? "\n" + extra : ""; + const { extra } = dataset[item.datasetIndex].bench + return extra ? '\n' + extra : '' }, }, }, }, onClick: (_mouseEvent, activeElems) => { if (activeElems.length === 0) { - return; + return } // XXX: Undocumented. How can we know the index? - const index = activeElems[0].index; - const url = dataset[index].commit.url; - window.open(url, "_blank"); + const index = activeElems[0].index + const url = dataset[index].commit.url + window.open(url, '_blank') }, }} /> - ); -}; + ) +} export default function BenchmarkResultCharts(): JSX.Element { - const [data, setData] = useState<{ entries: { Benchmark: [] } }>(); + const [data, setData] = useState<{ entries: { Benchmark: [] } }>() useEffect(() => { if (!data) { - (async () => { + ;(async () => { setData( JSON.parse( - (await (await fetch( - "https://raw.githubusercontent.com/discordeno/discordeno/benchies/benchmarksResult/data.js", - )).text()).slice(24), + (await (await fetch('https://raw.githubusercontent.com/discordeno/discordeno/benchies/benchmarksResult/data.js')).text()).slice(24), ), - ); - })(); + ) + })() } - }, []); + }, []) function collectBenchesPerTestCase(entries) { - const dataMap = new Map(); + const dataMap = new Map() for (const entry of entries) { - const { commit, date, tool, benches } = entry; + const { commit, date, tool, benches } = entry for (const bench of benches) { - const result = { commit, date, tool, bench }; - const arr = dataMap.get(bench.name); + const result = { commit, date, tool, bench } + const arr = dataMap.get(bench.name) if (arr === undefined) { - dataMap.set(bench.name, [result]); + dataMap.set(bench.name, [result]) } else { - arr.push(result); + arr.push(result) } } } - return dataMap; + return dataMap } return ( -
- {data - ? Array.from( - collectBenchesPerTestCase(data.entries.Benchmark), - ([key, value]) => ({ benchName: key, benches: value }), - ).map(( - bench, - index, - ) => ( - +
+ {data ? ( + Array.from(collectBenchesPerTestCase(data.entries.Benchmark), ([key, value]) => ({ benchName: key, benches: value })).map((bench, index) => ( + )) - : <>} + ) : ( + <> + )}
- ); + ) } diff --git a/site/src/components/HomepageFeatures.tsx b/site/src/components/HomepageFeatures.tsx index cb8e09feb..bcc9bdba2 100644 --- a/site/src/components/HomepageFeatures.tsx +++ b/site/src/components/HomepageFeatures.tsx @@ -1,18 +1,18 @@ -import useBaseUrl from "@docusaurus/useBaseUrl"; -import React from "react"; -import clsx from "clsx"; -import styles from "./HomepageFeatures.module.css"; +import useBaseUrl from '@docusaurus/useBaseUrl' +import React from 'react' +import clsx from 'clsx' +import styles from './HomepageFeatures.module.css' type FeatureItem = { - title: string; - image: string; - description: JSX.Element; -}; + title: string + image: string + description: JSX.Element +} const FeatureList: FeatureItem[] = [ { - title: "REST does not rest!", - image: "/img/undraw_docusaurus_mountain.svg", + title: 'REST does not rest!', + image: '/img/undraw_docusaurus_mountain.svg', description: ( <>
    @@ -27,14 +27,14 @@ const FeatureList: FeatureItem[] = [ ), }, { - title: "Zero Downtime Updates", - image: "/img/undraw_docusaurus_tree.svg", + title: 'Zero Downtime Updates', + image: '/img/undraw_docusaurus_tree.svg', description: ( <>
    • Instant bot restarts/updates.
    • - Automated sharding &{" "} + Automated sharding &{' '} re @@ -49,8 +49,8 @@ const FeatureList: FeatureItem[] = [ ), }, { - title: "No More Forks!", - image: "/img/undraw_docusaurus_react.svg", + title: 'No More Forks!', + image: '/img/undraw_docusaurus_react.svg', description: ( <>
        @@ -64,11 +64,11 @@ const FeatureList: FeatureItem[] = [ ), }, -]; +] function Feature({ title, image, description }: FeatureItem) { return ( -
        +
        {title}
        @@ -77,7 +77,7 @@ function Feature({ title, image, description }: FeatureItem) {

        {description}

        - ); + ) } export default function HomepageFeatures(): JSX.Element { @@ -85,9 +85,11 @@ export default function HomepageFeatures(): JSX.Element {
        - {FeatureList.map((props, idx) => )} + {FeatureList.map((props, idx) => ( + + ))}
        - ); + ) } diff --git a/site/src/components/architecture/BaseFlowChart.tsx b/site/src/components/architecture/BaseFlowChart.tsx index bc1117bb2..2178ce8a7 100644 --- a/site/src/components/architecture/BaseFlowChart.tsx +++ b/site/src/components/architecture/BaseFlowChart.tsx @@ -1,60 +1,60 @@ -import React, { useEffect, useState } from "react"; -import ReactFlow, { Background, Controls, Edge, Handle, Node, Position, useEdgesState, useNodesState } from "reactflow"; -import "reactflow/dist/style.css"; +import React, { useEffect, useState } from 'react' +import ReactFlow, { Background, Controls, Edge, Handle, Node, Position, useEdgesState, useNodesState } from 'reactflow' +import 'reactflow/dist/style.css' -export const multiplier = 225; -export const height = 40; -export const widthMultiplier = 0.75; +export const multiplier = 225 +export const height = 40 +export const widthMultiplier = 0.75 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[] }, -) { +export default function BaseFlowChart({ initialNodes = [], initialEdges = [] }: { initialNodes: Node[]; initialEdges: Edge[] }) { function getWindowDimensions() { - const { innerWidth: width, innerHeight: height } = window; + const { innerWidth: width, innerHeight: height } = window return { width, height, - }; + } } - const [windowDimensions, setWindowDimensions] = useState(getWindowDimensions()); + const [windowDimensions, setWindowDimensions] = useState(getWindowDimensions()) useEffect(() => { function handleResize() { - setWindowDimensions(getWindowDimensions()); + setWindowDimensions(getWindowDimensions()) } - window.addEventListener("resize", handleResize); - return () => window.removeEventListener("resize", handleResize); - }, []); + window.addEventListener('resize', handleResize) + return () => window.removeEventListener('resize', handleResize) + }, []) - const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes); - const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges); + const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes) + const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges) return ( <>
        = 997 - ? `${ - (100 * - ((windowDimensions.width - 300 - - (windowDimensions.width >= 1620 ? (windowDimensions.width - 1620) * 0.5 : 0)) / - windowDimensions.width) - 2) * widthMultiplier - }vw` - : "95vw", - height: "25vh", + width: + windowDimensions.width >= 997 + ? `${ + (100 * + ((windowDimensions.width - 300 - (windowDimensions.width >= 1620 ? (windowDimensions.width - 1620) * 0.5 : 0)) / + windowDimensions.width) - + 2) * + widthMultiplier + }vw` + : '95vw', + height: '25vh', }} > ( -
        - - +
        + +
        ), baseLineNodeText: (n) => ( -
        +

        {n.data.label}

        ), @@ -89,5 +81,5 @@ export default function BaseFlowChart(
        - ); + ) } diff --git a/site/src/components/architecture/FlowChart.tsx b/site/src/components/architecture/FlowChart.tsx index d89ade8eb..b7ab7fb59 100644 --- a/site/src/components/architecture/FlowChart.tsx +++ b/site/src/components/architecture/FlowChart.tsx @@ -1,103 +1,103 @@ -import React from "react"; -import { Edge, Node } from "reactflow"; -import "reactflow/dist/style.css"; -import BaseFlowChart, { defaultNodeOptions, multiplier } from "./BaseFlowChart"; +import React from 'react' +import { Edge, Node } from 'reactflow' +import 'reactflow/dist/style.css' +import BaseFlowChart, { defaultNodeOptions, multiplier } from './BaseFlowChart' const initialNodes: Node[] = [ { - id: "discordGateway", - type: "input", + id: 'discordGateway', + type: 'input', position: { x: 0 * multiplier, y: 0 }, - data: { label: "Discord Gateway" }, + data: { label: 'Discord Gateway' }, ...defaultNodeOptions, }, - { id: "gateway", position: { x: 1 * multiplier, y: 0 }, data: { label: "Gateway" }, ...defaultNodeOptions }, - { id: "baseLineNode-1", type: "baseLineNode", position: { x: 0.85 * multiplier, y: 170 }, data: {} }, - { id: "baseLineNode-2", type: "baseLineNode", position: { x: 0.85 * multiplier, y: -130 }, data: {} }, - { id: "baseLineNode-3", type: "baseLineNode", position: { x: 2.85 * multiplier, y: 170 }, data: {} }, - { id: "baseLineNode-4", type: "baseLineNode", position: { x: 2.85 * multiplier, y: -130 }, data: {} }, - { id: "baseLineNode-5", type: "baseLineNode", position: { x: 3.85 * multiplier, y: 170 }, data: {} }, - { id: "baseLineNode-6", type: "baseLineNode", position: { x: 3.85 * multiplier, y: -130 }, data: {} }, - { id: "baseLineNode-7", type: "baseLineNode", position: { x: 4.85 * multiplier, y: 170 }, data: {} }, - { id: "baseLineNode-8", type: "baseLineNode", position: { x: 4.85 * multiplier, y: -130 }, data: {} }, + { id: 'gateway', position: { x: 1 * multiplier, y: 0 }, data: { label: 'Gateway' }, ...defaultNodeOptions }, + { id: 'baseLineNode-1', type: 'baseLineNode', position: { x: 0.85 * multiplier, y: 170 }, data: {} }, + { id: 'baseLineNode-2', type: 'baseLineNode', position: { x: 0.85 * multiplier, y: -130 }, data: {} }, + { id: 'baseLineNode-3', type: 'baseLineNode', position: { x: 2.85 * multiplier, y: 170 }, data: {} }, + { id: 'baseLineNode-4', type: 'baseLineNode', position: { x: 2.85 * multiplier, y: -130 }, data: {} }, + { id: 'baseLineNode-5', type: 'baseLineNode', position: { x: 3.85 * multiplier, y: 170 }, data: {} }, + { id: 'baseLineNode-6', type: 'baseLineNode', position: { x: 3.85 * multiplier, y: -130 }, data: {} }, + { id: 'baseLineNode-7', type: 'baseLineNode', position: { x: 4.85 * multiplier, y: 170 }, data: {} }, + { id: 'baseLineNode-8', type: 'baseLineNode', position: { x: 4.85 * multiplier, y: -130 }, data: {} }, { - id: "baseLineNodeText-1", - type: "baseLineNodeText", + id: 'baseLineNodeText-1', + type: 'baseLineNodeText', position: { x: 0 * multiplier, y: -130 }, - data: { label: "Discord" }, + data: { label: 'Discord' }, }, { - id: "baseLineNodeText-2", - type: "baseLineNodeText", + id: 'baseLineNodeText-2', + type: 'baseLineNodeText', position: { x: 1.5 * multiplier, y: -130 }, - data: { label: "Event In" }, + data: { label: 'Event In' }, }, { - id: "baseLineNodeText-3", - type: "baseLineNodeText", + id: 'baseLineNodeText-3', + type: 'baseLineNodeText', position: { x: 3 * multiplier, y: -130 }, - data: { label: "Event Processing" }, + data: { label: 'Event Processing' }, }, { - id: "baseLineNodeText-4", - type: "baseLineNodeText", + id: 'baseLineNodeText-4', + type: 'baseLineNodeText', position: { x: 4 * multiplier, y: -130 }, - data: { label: "Event out" }, + data: { label: 'Event out' }, }, { - id: "baseLineNodeText-6", - type: "baseLineNodeText", + id: 'baseLineNodeText-6', + type: 'baseLineNodeText', position: { x: 5 * multiplier, y: -130 }, - data: { label: "Discord" }, + data: { label: 'Discord' }, }, - { id: "bot", position: { x: 2 * multiplier, y: 0 }, data: { label: "Bot" }, ...defaultNodeOptions }, - { id: "yourCode", position: { x: 3 * multiplier, y: 0 }, data: { label: "Your Code" }, ...defaultNodeOptions }, - { id: "rest", position: { x: 4 * multiplier, y: 0 }, data: { label: "Rest" }, ...defaultNodeOptions }, + { id: 'bot', position: { x: 2 * multiplier, y: 0 }, data: { label: 'Bot' }, ...defaultNodeOptions }, + { id: 'yourCode', position: { x: 3 * multiplier, y: 0 }, data: { label: 'Your Code' }, ...defaultNodeOptions }, + { id: 'rest', position: { x: 4 * multiplier, y: 0 }, data: { label: 'Rest' }, ...defaultNodeOptions }, { - id: "discordApiGateway", - type: "output", + id: 'discordApiGateway', + type: 'output', position: { x: 5 * multiplier, y: 0 }, - data: { label: "Discord Api" }, + data: { label: 'Discord Api' }, ...defaultNodeOptions, }, -]; +] const initialEdges: Edge[] = [ - { id: "d-g", source: "discordGateway", target: "gateway" }, - { id: "g-b", source: "gateway", target: "bot" }, - { id: "b-y", source: "bot", target: "yourCode" }, - { id: "y-r", source: "yourCode", target: "rest" }, - { id: "r-d", source: "rest", target: "discordApiGateway" }, + { id: 'd-g', source: 'discordGateway', target: 'gateway' }, + { id: 'g-b', source: 'gateway', target: 'bot' }, + { id: 'b-y', source: 'bot', target: 'yourCode' }, + { id: 'y-r', source: 'yourCode', target: 'rest' }, + { id: 'r-d', source: 'rest', target: 'discordApiGateway' }, { - id: "baseLine-1", - source: "baseLineNode-1", - target: "baseLineNode-2", - style: { stroke: "blue", strokeDasharray: 20 }, + id: 'baseLine-1', + source: 'baseLineNode-1', + target: 'baseLineNode-2', + style: { stroke: 'blue', strokeDasharray: 20 }, animated: false, }, { - id: "baseLine-2", - source: "baseLineNode-3", - target: "baseLineNode-4", - style: { stroke: "blue", strokeDasharray: 20 }, + id: 'baseLine-2', + source: 'baseLineNode-3', + target: 'baseLineNode-4', + style: { stroke: 'blue', strokeDasharray: 20 }, animated: false, }, { - id: "baseLine-3", - source: "baseLineNode-5", - target: "baseLineNode-6", - style: { stroke: "blue", strokeDasharray: 20 }, + id: 'baseLine-3', + source: 'baseLineNode-5', + target: 'baseLineNode-6', + style: { stroke: 'blue', strokeDasharray: 20 }, animated: false, }, { - id: "baseLine-4", - source: "baseLineNode-7", - target: "baseLineNode-8", - style: { stroke: "blue", strokeDasharray: 20 }, + id: 'baseLine-4', + source: 'baseLineNode-7', + target: 'baseLineNode-8', + style: { stroke: 'blue', strokeDasharray: 20 }, animated: false, }, -]; +] export default function FlowChart() { - return ; + return } diff --git a/site/src/components/architecture/FlowChart2.tsx b/site/src/components/architecture/FlowChart2.tsx index 6f10ee87d..ebb03d361 100644 --- a/site/src/components/architecture/FlowChart2.tsx +++ b/site/src/components/architecture/FlowChart2.tsx @@ -1,198 +1,198 @@ -import React from "react"; -import { Edge, Node, Position } from "reactflow"; -import "reactflow/dist/style.css"; -import BaseFlowChart, { defaultGroupOptions, defaultNodeOptions, multiplier } from "./BaseFlowChart"; +import React from 'react' +import { Edge, Node, Position } from 'reactflow' +import 'reactflow/dist/style.css' +import BaseFlowChart, { defaultGroupOptions, defaultNodeOptions, multiplier } from './BaseFlowChart' const initialNodes: Node[] = [ { - id: "discordGateway", - type: "input", + id: 'discordGateway', + type: 'input', position: { x: 0 * multiplier, y: 0 }, - data: { label: "Discord Gateway" }, + data: { label: 'Discord Gateway' }, ...defaultNodeOptions, }, - { id: "baseLineNode-1", type: "baseLineNode", position: { x: 0.85 * multiplier, y: 170 }, data: {} }, - { id: "baseLineNode-2", type: "baseLineNode", position: { x: 0.85 * multiplier, y: -130 }, data: {} }, - { id: "baseLineNode-3", type: "baseLineNode", position: { x: 3.75 * multiplier, y: 170 }, data: {} }, - { id: "baseLineNode-4", type: "baseLineNode", position: { x: 3.75 * multiplier, y: -130 }, data: {} }, + { id: 'baseLineNode-1', type: 'baseLineNode', position: { x: 0.85 * multiplier, y: 170 }, data: {} }, + { id: 'baseLineNode-2', type: 'baseLineNode', position: { x: 0.85 * multiplier, y: -130 }, data: {} }, + { id: 'baseLineNode-3', type: 'baseLineNode', position: { x: 3.75 * multiplier, y: 170 }, data: {} }, + { id: 'baseLineNode-4', type: 'baseLineNode', position: { x: 3.75 * multiplier, y: -130 }, data: {} }, { - id: "baseLineNodeText-1", - type: "baseLineNodeText", + id: 'baseLineNodeText-1', + type: 'baseLineNodeText', position: { x: 0 * multiplier, y: -130 }, - data: { label: "Discord" }, + data: { label: 'Discord' }, }, { - id: "baseLineNodeText-2", - type: "baseLineNodeText", + id: 'baseLineNodeText-2', + type: 'baseLineNodeText', position: { x: 2 * multiplier, y: -130 }, - data: { label: "Gateway" }, + data: { label: 'Gateway' }, }, { - id: "baseLineNodeText-3", - type: "baseLineNodeText", + id: 'baseLineNodeText-3', + type: 'baseLineNodeText', position: { x: 4 * multiplier, y: -130 }, - data: { label: "Bot" }, + data: { label: 'Bot' }, }, { - id: "gatewayManager", - type: "input", + id: 'gatewayManager', + type: 'input', position: { x: 2.0625 * multiplier, y: -80 }, - data: { label: "Gateway Manager" }, + data: { label: 'Gateway Manager' }, ...defaultNodeOptions, targetPosition: Position.Top, sourcePosition: Position.Bottom, }, { - id: "shard-1", - type: "output", + id: 'shard-1', + type: 'output', position: { x: 1.25 * multiplier, y: -20 }, - data: { label: "Shard-1" }, - style: { width: `${multiplier * 2}px`, height: "80px" }, + data: { label: 'Shard-1' }, + style: { width: `${multiplier * 2}px`, height: '80px' }, ...defaultGroupOptions, }, { - id: "shard-1-socket", + id: 'shard-1-socket', position: { x: 0.125 * multiplier, y: 20 }, - data: { label: "webSocket" }, + data: { label: 'webSocket' }, ...defaultNodeOptions, - parentNode: "shard-1", - extent: "parent", + parentNode: 'shard-1', + extent: 'parent', }, { - id: "shard-1-handleMessage", + id: 'shard-1-handleMessage', position: { x: 1.125 * multiplier, y: 20 }, - data: { label: "HandleMessage" }, + data: { label: 'HandleMessage' }, ...defaultNodeOptions, - parentNode: "shard-1", - extent: "parent", + parentNode: 'shard-1', + extent: 'parent', }, { - id: "shard-2", - type: "output", + id: 'shard-2', + type: 'output', position: { x: 1.375 * multiplier, y: 0 }, - data: { label: "Shard-2" }, - style: { width: `${multiplier * 2}px`, height: "80px" }, + data: { label: 'Shard-2' }, + style: { width: `${multiplier * 2}px`, height: '80px' }, ...defaultGroupOptions, }, { - id: "shard-2-socket", + id: 'shard-2-socket', position: { x: 0.125 * multiplier, y: 20 }, - data: { label: "webSocket" }, + data: { label: 'webSocket' }, ...defaultNodeOptions, - parentNode: "shard-2", - extent: "parent", + parentNode: 'shard-2', + extent: 'parent', }, { - id: "shard-2-handleMessage", + id: 'shard-2-handleMessage', position: { x: 1.125 * multiplier, y: 20 }, - data: { label: "HandleMessage" }, + data: { label: 'HandleMessage' }, ...defaultNodeOptions, - parentNode: "shard-2", - extent: "parent", + parentNode: 'shard-2', + extent: 'parent', }, { - id: "shard-3", - type: "output", + id: 'shard-3', + type: 'output', position: { x: 1.5 * multiplier, y: 20 }, - data: { label: "Shard-3" }, - style: { width: `${multiplier * 2}px`, height: "80px" }, + data: { label: 'Shard-3' }, + style: { width: `${multiplier * 2}px`, height: '80px' }, ...defaultGroupOptions, }, { - id: "shard-3-socket", + id: 'shard-3-socket', position: { x: 0.125 * multiplier, y: 20 }, - data: { label: "webSocket" }, + data: { label: 'webSocket' }, ...defaultNodeOptions, - parentNode: "shard-3", - extent: "parent", + parentNode: 'shard-3', + extent: 'parent', }, { - id: "shard-3-handleMessage", + id: 'shard-3-handleMessage', position: { x: 1.125 * multiplier, y: 20 }, - data: { label: "HandleMessage" }, + data: { label: 'HandleMessage' }, ...defaultNodeOptions, - parentNode: "shard-3", - extent: "parent", + parentNode: 'shard-3', + extent: 'parent', }, { - id: "shard-n", - type: "output", + id: 'shard-n', + type: 'output', position: { x: 1.625 * multiplier, y: 40 }, - data: { label: "Shard-N" }, - style: { width: `${multiplier * 2}px`, height: "80px" }, + data: { label: 'Shard-N' }, + style: { width: `${multiplier * 2}px`, height: '80px' }, ...defaultGroupOptions, }, { - id: "shard-n-socket", + id: 'shard-n-socket', position: { x: 0.125 * multiplier, y: 20 }, - data: { label: "webSocket" }, + data: { label: 'webSocket' }, ...defaultNodeOptions, - parentNode: "shard-n", - extent: "parent", + parentNode: 'shard-n', + extent: 'parent', }, { - id: "shard-n-handleMessage", + id: 'shard-n-handleMessage', position: { x: 1.125 * multiplier, y: 20 }, - data: { label: "HandleMessage" }, + data: { label: 'HandleMessage' }, ...defaultNodeOptions, - parentNode: "shard-n", - extent: "parent", + parentNode: 'shard-n', + extent: 'parent', }, - { id: "bot", type: "output", position: { x: 4 * multiplier, y: 0 }, data: { label: "Bot" }, ...defaultNodeOptions }, -]; + { id: 'bot', type: 'output', position: { x: 4 * multiplier, y: 0 }, data: { label: 'Bot' }, ...defaultNodeOptions }, +] const initialEdges: Edge[] = [ - { id: "d-g", source: "discordGateway", target: "gateway" }, - { id: "g-b", source: "gateway", target: "bot" }, - { id: "b-y", source: "bot", target: "yourCode" }, - { id: "y-r", source: "yourCode", target: "rest" }, - { id: "r-d", source: "rest", target: "discordApiGateway" }, + { id: 'd-g', source: 'discordGateway', target: 'gateway' }, + { id: 'g-b', source: 'gateway', target: 'bot' }, + { id: 'b-y', source: 'bot', target: 'yourCode' }, + { id: 'y-r', source: 'yourCode', target: 'rest' }, + { id: 'r-d', source: 'rest', target: 'discordApiGateway' }, { - id: "baseLine-1", - source: "baseLineNode-1", - target: "baseLineNode-2", - style: { stroke: "blue", strokeDasharray: 20 }, + id: 'baseLine-1', + source: 'baseLineNode-1', + target: 'baseLineNode-2', + style: { stroke: 'blue', strokeDasharray: 20 }, animated: false, }, { - id: "baseLine-2", - source: "baseLineNode-3", - target: "baseLineNode-4", - style: { stroke: "blue", strokeDasharray: 20 }, + id: 'baseLine-2', + source: 'baseLineNode-3', + target: 'baseLineNode-4', + style: { stroke: 'blue', strokeDasharray: 20 }, animated: false, }, { - id: "baseLine-3", - source: "baseLineNode-5", - target: "baseLineNode-6", - style: { stroke: "blue", strokeDasharray: 20 }, + id: 'baseLine-3', + source: 'baseLineNode-5', + target: 'baseLineNode-6', + style: { stroke: 'blue', strokeDasharray: 20 }, animated: false, }, { - id: "baseLine-4", - source: "baseLineNode-7", - target: "baseLineNode-8", - style: { stroke: "blue", strokeDasharray: 20 }, + id: 'baseLine-4', + source: 'baseLineNode-7', + target: 'baseLineNode-8', + style: { stroke: 'blue', strokeDasharray: 20 }, animated: false, }, - { id: "d-shard-1", source: "discordGateway", target: "shard-1-socket", zIndex: 100 }, - { id: "d-shard-2", source: "discordGateway", target: "shard-2-socket", zIndex: 100 }, - { id: "d-shard-3", source: "discordGateway", target: "shard-3-socket", zIndex: 100 }, - { id: "d-shard-n", source: "discordGateway", target: "shard-n-socket", zIndex: 100 }, - { id: "shard-1-socket-handleMessage", source: "shard-1-socket", target: "shard-1-handleMessage", zIndex: 100 }, - { id: "shard-2-socket-handleMessage", source: "shard-2-socket", target: "shard-2-handleMessage", zIndex: 100 }, - { id: "shard-3-socket-handleMessage", source: "shard-3-socket", target: "shard-3-handleMessage", zIndex: 100 }, - { id: "shard-n-socket-handleMessage", source: "shard-n-socket", target: "shard-n-handleMessage", zIndex: 100 }, - { id: "shard-1-handleMessage-bot", source: "shard-1-handleMessage", target: "bot", zIndex: 100 }, - { id: "shard-2-handleMessage-bot", source: "shard-2-handleMessage", target: "bot", zIndex: 100 }, - { id: "shard-3-handleMessage-bot", source: "shard-3-handleMessage", target: "bot", zIndex: 100 }, - { id: "shard-n-handleMessage-bot", source: "shard-n-handleMessage", target: "bot", zIndex: 100 }, - { id: "gatewayManager-shard-1", source: "gatewayManager", target: "shard-1", zIndex: 10 }, - { id: "gatewayManager-shard-2", source: "gatewayManager", target: "shard-2", zIndex: 100 }, - { id: "gatewayManager-shard-3", source: "gatewayManager", target: "shard-3", zIndex: 100 }, - { id: "gatewayManager-shard-n", source: "gatewayManager", target: "shard-n", zIndex: 100 }, -]; + { id: 'd-shard-1', source: 'discordGateway', target: 'shard-1-socket', zIndex: 100 }, + { id: 'd-shard-2', source: 'discordGateway', target: 'shard-2-socket', zIndex: 100 }, + { id: 'd-shard-3', source: 'discordGateway', target: 'shard-3-socket', zIndex: 100 }, + { id: 'd-shard-n', source: 'discordGateway', target: 'shard-n-socket', zIndex: 100 }, + { id: 'shard-1-socket-handleMessage', source: 'shard-1-socket', target: 'shard-1-handleMessage', zIndex: 100 }, + { id: 'shard-2-socket-handleMessage', source: 'shard-2-socket', target: 'shard-2-handleMessage', zIndex: 100 }, + { id: 'shard-3-socket-handleMessage', source: 'shard-3-socket', target: 'shard-3-handleMessage', zIndex: 100 }, + { id: 'shard-n-socket-handleMessage', source: 'shard-n-socket', target: 'shard-n-handleMessage', zIndex: 100 }, + { id: 'shard-1-handleMessage-bot', source: 'shard-1-handleMessage', target: 'bot', zIndex: 100 }, + { id: 'shard-2-handleMessage-bot', source: 'shard-2-handleMessage', target: 'bot', zIndex: 100 }, + { id: 'shard-3-handleMessage-bot', source: 'shard-3-handleMessage', target: 'bot', zIndex: 100 }, + { id: 'shard-n-handleMessage-bot', source: 'shard-n-handleMessage', target: 'bot', zIndex: 100 }, + { id: 'gatewayManager-shard-1', source: 'gatewayManager', target: 'shard-1', zIndex: 10 }, + { id: 'gatewayManager-shard-2', source: 'gatewayManager', target: 'shard-2', zIndex: 100 }, + { id: 'gatewayManager-shard-3', source: 'gatewayManager', target: 'shard-3', zIndex: 100 }, + { id: 'gatewayManager-shard-n', source: 'gatewayManager', target: 'shard-n', zIndex: 100 }, +] export default function FlowChart2() { - return ; + return } diff --git a/site/src/components/architecture/FlowChart3.tsx b/site/src/components/architecture/FlowChart3.tsx index 6131215e4..9e22632a4 100644 --- a/site/src/components/architecture/FlowChart3.tsx +++ b/site/src/components/architecture/FlowChart3.tsx @@ -1,334 +1,285 @@ -import React, { useEffect, useState } from "react"; -import ReactFlow, { - Background, - Controls, - Edge, - Handle, - Node, - NodeMouseHandler, - Position, - useEdgesState, - useNodesState, -} from "reactflow"; -import "reactflow/dist/style.css"; -import { defaultNodeOptions, height, multiplier, widthMultiplier } from "./BaseFlowChart"; +import React, { useEffect, useState } from 'react' +import ReactFlow, { Background, Controls, Edge, Handle, Node, NodeMouseHandler, Position, useEdgesState, useNodesState } from 'reactflow' +import 'reactflow/dist/style.css' +import { defaultNodeOptions, height, multiplier, widthMultiplier } from './BaseFlowChart' const handlers: { [index: string]: { - transformers: string[]; - event: string; - }; + transformers: string[] + event: string + } } = { - handleChannelCreate: { transformers: ["transformers.channel"], event: "events.channelCreate" }, + handleChannelCreate: { transformers: ['transformers.channel'], event: 'events.channelCreate' }, handleChannelDelete: { - transformers: ["transformers.channel", "transformers.snowflake"], - event: "events.channelDelete", + transformers: ['transformers.channel', 'transformers.snowflake'], + event: 'events.channelDelete', }, handleChannelPinsUpdate: { - transformers: ["transformers.snowflake", "transformers.snowflake"], - event: "events.channelPinsUpdate", + transformers: ['transformers.snowflake', 'transformers.snowflake'], + event: 'events.channelPinsUpdate', }, - handleChannelUpdate: { transformers: ["transformers.channel"], event: "events.channelUpdate" }, + handleChannelUpdate: { transformers: ['transformers.channel'], event: 'events.channelUpdate' }, handleStageInstanceCreate: { - transformers: ["transformers.snowflake", "transformers.snowflake", "transformers.snowflake"], - event: "events.stageInstanceCreate", + transformers: ['transformers.snowflake', 'transformers.snowflake', 'transformers.snowflake'], + event: 'events.stageInstanceCreate', }, handleStageInstanceDelete: { - transformers: ["transformers.snowflake", "transformers.snowflake", "transformers.snowflake"], - event: "events.stageInstanceDelete", + transformers: ['transformers.snowflake', 'transformers.snowflake', 'transformers.snowflake'], + event: 'events.stageInstanceDelete', }, handleStageInstanceUpdate: { - transformers: ["transformers.snowflake", "transformers.snowflake", "transformers.snowflake"], - event: "events.stageInstanceUpdate", + transformers: ['transformers.snowflake', 'transformers.snowflake', 'transformers.snowflake'], + event: 'events.stageInstanceUpdate', }, - handleThreadCreate: { transformers: ["transformers.channel"], event: "events.threadCreate" }, - handleThreadDelete: { transformers: ["transformers.channel"], event: "events.threadDelete" }, + handleThreadCreate: { transformers: ['transformers.channel'], event: 'events.threadCreate' }, + handleThreadDelete: { transformers: ['transformers.channel'], event: 'events.threadDelete' }, handleThreadListSync: { - transformers: [ - "transformers.snowflake", - "transformers.snowflake", - "transformers.channel", - "transformers.snowflake", - "transformers.snowflake", - ], + transformers: ['transformers.snowflake', 'transformers.snowflake', 'transformers.channel', 'transformers.snowflake', 'transformers.snowflake'], event: undefined, }, handleThreadMembersUpdate: { - transformers: [ - "transformers.snowflake", - "transformers.snowflake", - "transformers.threadMember", - "transformers.snowflake", - ], - event: "events.threadMembersUpdate", + transformers: ['transformers.snowflake', 'transformers.snowflake', 'transformers.threadMember', 'transformers.snowflake'], + event: 'events.threadMembersUpdate', }, handleThreadMemberUpdate: { - transformers: ["transformers.snowflake", "transformers.snowflake"], - event: "events.threadMemberUpdate", + transformers: ['transformers.snowflake', 'transformers.snowflake'], + event: 'events.threadMemberUpdate', }, - handleThreadUpdate: { transformers: ["transformers.channel"], event: "events.threadUpdate" }, + handleThreadUpdate: { transformers: ['transformers.channel'], event: 'events.threadUpdate' }, handleGuildEmojisUpdate: { - transformers: ["transformers.snowflake", "transformers.snowflake"], - event: "events.guildEmojisUpdate", + transformers: ['transformers.snowflake', 'transformers.snowflake'], + event: 'events.guildEmojisUpdate', }, handleAutoModerationActionExecution: { - transformers: ["transformers.automodActionExecution"], - event: "events.automodActionExecution", + transformers: ['transformers.automodActionExecution'], + event: 'events.automodActionExecution', }, - handleAutoModerationRuleCreate: { transformers: ["transformers.automodRule"], event: "events.automodRuleCreate" }, - handleAutoModerationRuleDelete: { transformers: ["transformers.automodRule"], event: "events.automodRuleDelete" }, - handleAutoModerationRuleUpdate: { transformers: ["transformers.automodRule"], event: "events.automodRuleUpdate" }, + handleAutoModerationRuleCreate: { transformers: ['transformers.automodRule'], event: 'events.automodRuleCreate' }, + handleAutoModerationRuleDelete: { transformers: ['transformers.automodRule'], event: 'events.automodRuleDelete' }, + handleAutoModerationRuleUpdate: { transformers: ['transformers.automodRule'], event: 'events.automodRuleUpdate' }, handleGuildBanAdd: { - transformers: ["transformers.user", "transformers.snowflake"], - event: "events.guildBanAdd", + transformers: ['transformers.user', 'transformers.snowflake'], + event: 'events.guildBanAdd', }, handleGuildBanRemove: { - transformers: ["transformers.user", "transformers.snowflake"], - event: "events.guildBanRemove", + transformers: ['transformers.user', 'transformers.snowflake'], + event: 'events.guildBanRemove', }, - handleGuildCreate: { transformers: ["transformers.guild"], event: "events.guildCreate" }, - handleGuildDelete: { transformers: ["transformers.snowflake"], event: "events.guildDelete" }, - handleGuildIntegrationsUpdate: { transformers: ["transformers.snowflake"], event: "events.integrationUpdate" }, - handleGuildUpdate: { transformers: ["transformers.guild"], event: "events.guildUpdate" }, + handleGuildCreate: { transformers: ['transformers.guild'], event: 'events.guildCreate' }, + handleGuildDelete: { transformers: ['transformers.snowflake'], event: 'events.guildDelete' }, + handleGuildIntegrationsUpdate: { transformers: ['transformers.snowflake'], event: 'events.integrationUpdate' }, + handleGuildUpdate: { transformers: ['transformers.guild'], event: 'events.guildUpdate' }, handleGuildScheduledEventCreate: { - transformers: ["transformers.scheduledEvent"], - event: "events.scheduledEventCreate", + transformers: ['transformers.scheduledEvent'], + event: 'events.scheduledEventCreate', }, handleGuildScheduledEventDelete: { - transformers: ["transformers.scheduledEvent"], - event: "events.scheduledEventDelete", + transformers: ['transformers.scheduledEvent'], + event: 'events.scheduledEventDelete', }, handleGuildScheduledEventUpdate: { - transformers: ["transformers.scheduledEvent"], - event: "events.scheduledEventUpdate", + transformers: ['transformers.scheduledEvent'], + event: 'events.scheduledEventUpdate', }, handleGuildScheduledEventUserAdd: { - transformers: ["transformers.snowflake", "transformers.snowflake", "transformers.snowflake"], - event: "events.scheduledEventUserAdd", + transformers: ['transformers.snowflake', 'transformers.snowflake', 'transformers.snowflake'], + event: 'events.scheduledEventUserAdd', }, handleGuildScheduledEventUserRemove: { - transformers: ["transformers.snowflake", "transformers.snowflake", "transformers.snowflake"], - event: "events.scheduledEventUserRemove", + transformers: ['transformers.snowflake', 'transformers.snowflake', 'transformers.snowflake'], + event: 'events.scheduledEventUserRemove', }, - handleIntegrationCreate: { transformers: ["transformers.integration"], event: "events.integrationCreate" }, + handleIntegrationCreate: { transformers: ['transformers.integration'], event: 'events.integrationCreate' }, handleIntegrationDelete: { - transformers: ["transformers.snowflake", "transformers.snowflake", "transformers.snowflake"], - event: "events.integrationDelete", + transformers: ['transformers.snowflake', 'transformers.snowflake', 'transformers.snowflake'], + event: 'events.integrationDelete', }, - handleIntegrationUpdate: { transformers: ["transformers.integration"], event: "events.integrationUpdate" }, + handleIntegrationUpdate: { transformers: ['transformers.integration'], event: 'events.integrationUpdate' }, handleInteractionCreate: { - transformers: ["transformers.snowflake", "transformers.interaction"], - event: "events.interactionCreate", + transformers: ['transformers.snowflake', 'transformers.interaction'], + event: 'events.interactionCreate', }, - handleInviteCreate: { transformers: ["transformers.invite"], event: "events.inviteCreate" }, + handleInviteCreate: { transformers: ['transformers.invite'], event: 'events.inviteCreate' }, handleInviteDelete: { - transformers: ["transformers.snowflake", "transformers.snowflake"], - event: "events.inviteDelete", + transformers: ['transformers.snowflake', 'transformers.snowflake'], + event: 'events.inviteDelete', }, handleGuildMembersChunk: { transformers: [ - "transformers.snowflake", - "transformers.member", - "transformers.snowflake", - "transformers.snowflake", - "transformers.user", - "transformers.activity", + 'transformers.snowflake', + 'transformers.member', + 'transformers.snowflake', + 'transformers.snowflake', + 'transformers.user', + 'transformers.activity', ], event: undefined, }, handleGuildMemberAdd: { - transformers: ["transformers.snowflake", "transformers.user", "transformers.member"], - event: "events.guildMemberAdd", + transformers: ['transformers.snowflake', 'transformers.user', 'transformers.member'], + event: 'events.guildMemberAdd', }, handleGuildMemberRemove: { - transformers: ["transformers.snowflake", "transformers.user"], - event: "events.guildMemberRemove", + transformers: ['transformers.snowflake', 'transformers.user'], + event: 'events.guildMemberRemove', }, handleGuildMemberUpdate: { - transformers: ["transformers.user", "transformers.member", "transformers.snowflake"], - event: "events.guildMemberUpdate", + transformers: ['transformers.user', 'transformers.member', 'transformers.snowflake'], + event: 'events.guildMemberUpdate', }, - handleMessageCreate: { transformers: ["transformers.message"], event: "events.messageCreate" }, + handleMessageCreate: { transformers: ['transformers.message'], event: 'events.messageCreate' }, handleMessageDelete: { - transformers: ["transformers.snowflake", "transformers.snowflake", "transformers.snowflake"], - event: "events.messageDelete", + transformers: ['transformers.snowflake', 'transformers.snowflake', 'transformers.snowflake'], + event: 'events.messageDelete', }, handleMessageDeleteBulk: { - transformers: [ - "transformers.snowflake", - "transformers.snowflake", - "transformers.snowflake", - "transformers.snowflake", - "transformers.snowflake", - ], - event: "events.messageDeleteBulk", + transformers: ['transformers.snowflake', 'transformers.snowflake', 'transformers.snowflake', 'transformers.snowflake', 'transformers.snowflake'], + event: 'events.messageDeleteBulk', }, handleMessageReactionAdd: { transformers: [ - "transformers.snowflake", - "transformers.snowflake", - "transformers.snowflake", - "transformers.snowflake", - "transformers.member", - "transformers.user", - "transformers.emoji", + 'transformers.snowflake', + 'transformers.snowflake', + 'transformers.snowflake', + 'transformers.snowflake', + 'transformers.member', + 'transformers.user', + 'transformers.emoji', ], - event: "events.reactionAdd", + event: 'events.reactionAdd', }, handleMessageReactionRemove: { - transformers: [ - "transformers.snowflake", - "transformers.snowflake", - "transformers.snowflake", - "transformers.snowflake", - "transformers.emoji", - ], - event: "events.reactionRemove", + transformers: ['transformers.snowflake', 'transformers.snowflake', 'transformers.snowflake', 'transformers.snowflake', 'transformers.emoji'], + event: 'events.reactionRemove', }, handleMessageReactionRemoveAll: { - transformers: ["transformers.snowflake", "transformers.snowflake", "transformers.snowflake"], - event: "events.reactionRemoveAll", + transformers: ['transformers.snowflake', 'transformers.snowflake', 'transformers.snowflake'], + event: 'events.reactionRemoveAll', }, handleMessageReactionRemoveEmoji: { - transformers: [ - "transformers.snowflake", - "transformers.snowflake", - "transformers.snowflake", - "transformers.emoji", - ], - event: "events.reactionRemoveEmoji", + transformers: ['transformers.snowflake', 'transformers.snowflake', 'transformers.snowflake', 'transformers.emoji'], + event: 'events.reactionRemoveEmoji', }, - handleMessageUpdate: { transformers: ["transformers.message"], event: "events.messageUpdate" }, - handlePresenceUpdate: { transformers: ["transformers.presence"], event: "events.presenceUpdate" }, + handleMessageUpdate: { transformers: ['transformers.message'], event: 'events.messageUpdate' }, + handlePresenceUpdate: { transformers: ['transformers.presence'], event: 'events.presenceUpdate' }, handleReady: { - transformers: [ - "transformers.user", - "transformers.snowflake", - "transformers.snowflake", - "transformers.snowflake", - "transformers.snowflake", - ], - event: "events.ready", + transformers: ['transformers.user', 'transformers.snowflake', 'transformers.snowflake', 'transformers.snowflake', 'transformers.snowflake'], + event: 'events.ready', }, handleTypingStart: { - transformers: [ - "transformers.snowflake", - "transformers.snowflake", - "transformers.snowflake", - "transformers.member", - ], - event: "events.typingStart", + transformers: ['transformers.snowflake', 'transformers.snowflake', 'transformers.snowflake', 'transformers.member'], + event: 'events.typingStart', }, - handleUserUpdate: { transformers: ["transformers.user"], event: "events.botUpdate" }, + handleUserUpdate: { transformers: ['transformers.user'], event: 'events.botUpdate' }, handleGuildRoleCreate: { - transformers: ["transformers.role", "transformers.snowflake"], - event: "events.roleCreate", + transformers: ['transformers.role', 'transformers.snowflake'], + event: 'events.roleCreate', }, handleGuildRoleDelete: { - transformers: ["transformers.snowflake", "transformers.snowflake"], - event: "events.roleDelete", + transformers: ['transformers.snowflake', 'transformers.snowflake'], + event: 'events.roleDelete', }, handleGuildRoleUpdate: { - transformers: ["transformers.role", "transformers.snowflake"], - event: "events.roleUpdate", + transformers: ['transformers.role', 'transformers.snowflake'], + event: 'events.roleUpdate', }, - handleVoiceServerUpdate: { transformers: ["transformers.snowflake"], event: "events.voiceServerUpdate" }, + handleVoiceServerUpdate: { transformers: ['transformers.snowflake'], event: 'events.voiceServerUpdate' }, handleVoiceStateUpdate: { - transformers: ["transformers.snowflake", "transformers.voiceState"], - event: "events.voiceStateUpdate", + transformers: ['transformers.snowflake', 'transformers.voiceState'], + event: 'events.voiceStateUpdate', }, handleWebhooksUpdate: { - transformers: ["transformers.snowflake", "transformers.snowflake"], - event: "events.webhooksUpdate", + transformers: ['transformers.snowflake', 'transformers.snowflake'], + event: 'events.webhooksUpdate', }, -}; +} export default function FlowChart({ handlerFilter = (handler: string) => true }) { function getWindowDimensions() { - const { innerWidth: width, innerHeight: height } = window; + const { innerWidth: width, innerHeight: height } = window return { width, height, - }; + } } - const [windowDimensions, setWindowDimensions] = useState(getWindowDimensions()); + const [windowDimensions, setWindowDimensions] = useState(getWindowDimensions()) useEffect(() => { function handleResize() { - setWindowDimensions(getWindowDimensions()); + setWindowDimensions(getWindowDimensions()) } - window.addEventListener("resize", handleResize); - return () => window.removeEventListener("resize", handleResize); - }, []); + window.addEventListener('resize', handleResize) + return () => window.removeEventListener('resize', handleResize) + }, []) - const transformers = []; + const transformers = [] - const events = []; + const events = [] const initialNodes: Node[] = [ { - id: "baseNode-gateway", - type: "input", + id: 'baseNode-gateway', + type: 'input', position: { x: 0 * multiplier, y: 0 }, - data: { label: "gateway" }, + data: { label: 'gateway' }, ...defaultNodeOptions, }, { - id: "baseNode-yourCode", - type: "output", + id: 'baseNode-yourCode', + type: 'output', position: { x: 5 * multiplier, y: 0 }, - data: { label: "Your Code" }, + data: { label: 'Your Code' }, ...defaultNodeOptions, }, - { id: "baseLineNode-1", type: "baseLineNode", position: { x: 0.85 * multiplier, y: 170 }, data: {} }, - { id: "baseLineNode-2", type: "baseLineNode", position: { x: 0.85 * multiplier, y: -130 }, data: {} }, - { id: "baseLineNode-3", type: "baseLineNode", position: { x: 4.85 * multiplier, y: 170 }, data: {} }, - { id: "baseLineNode-4", type: "baseLineNode", position: { x: 4.85 * multiplier, y: -130 }, data: {} }, + { id: 'baseLineNode-1', type: 'baseLineNode', position: { x: 0.85 * multiplier, y: 170 }, data: {} }, + { id: 'baseLineNode-2', type: 'baseLineNode', position: { x: 0.85 * multiplier, y: -130 }, data: {} }, + { id: 'baseLineNode-3', type: 'baseLineNode', position: { x: 4.85 * multiplier, y: 170 }, data: {} }, + { id: 'baseLineNode-4', type: 'baseLineNode', position: { x: 4.85 * multiplier, y: -130 }, data: {} }, { - id: "baseLineNodeText-1", - type: "baseLineNodeText", + id: 'baseLineNodeText-1', + type: 'baseLineNodeText', position: { x: 0 * multiplier, y: -130 }, - data: { label: "Gateway" }, + data: { label: 'Gateway' }, }, { - id: "baseLineNodeText-2", - type: "baseLineNodeText", + id: 'baseLineNodeText-2', + type: 'baseLineNodeText', position: { x: 1 * multiplier, y: -130 }, - data: { label: "Bot" }, + data: { label: 'Bot' }, }, { - id: "baseLineNodeText-3", - type: "baseLineNodeText", + id: 'baseLineNodeText-3', + type: 'baseLineNodeText', position: { x: 5 * multiplier, y: -130 }, - data: { label: "Your Code" }, + data: { label: 'Your Code' }, }, { - id: "baseNode-handleDiscordPayload", + id: 'baseNode-handleDiscordPayload', position: { x: 1 * multiplier, y: 0 }, - data: { label: "Handle discord payload" }, + data: { label: 'Handle discord payload' }, ...defaultNodeOptions, }, - ]; + ] const initialEdges: Edge[] = [ - { id: "baseEdge-1", source: "baseNode-gateway", target: "baseNode-handleDiscordPayload" }, - { id: "baseEdge-3", source: "baseNode-g-1", target: "baseNode-g-2" }, - { id: "baseEdge-4", source: "baseNode-g-2", target: "baseNode-handleDiscordPayload" }, + { id: 'baseEdge-1', source: 'baseNode-gateway', target: 'baseNode-handleDiscordPayload' }, + { id: 'baseEdge-3', source: 'baseNode-g-1', target: 'baseNode-g-2' }, + { id: 'baseEdge-4', source: 'baseNode-g-2', target: 'baseNode-handleDiscordPayload' }, { - id: "baseLine-1", - source: "baseLineNode-1", - target: "baseLineNode-2", - style: { stroke: "blue", strokeDasharray: 20 }, + id: 'baseLine-1', + source: 'baseLineNode-1', + target: 'baseLineNode-2', + style: { stroke: 'blue', strokeDasharray: 20 }, }, { - id: "baseLine-2", - source: "baseLineNode-3", - target: "baseLineNode-4", - style: { stroke: "blue", strokeDasharray: 20 }, + id: 'baseLine-2', + source: 'baseLineNode-3', + target: 'baseLineNode-4', + style: { stroke: 'blue', strokeDasharray: 20 }, }, - ]; + ] //@ts-ignore for (const [index, handler] of Object.keys(handlers).filter(handlerFilter).entries()) { @@ -336,38 +287,35 @@ export default function FlowChart({ handlerFilter = (handler: string) => true }) id: handler, position: { x: 2 * multiplier, - y: index * (height + 10) - Object.keys(handlers).filter(handlerFilter).length * ((height + 10) / 2) + - height / 2, + y: index * (height + 10) - Object.keys(handlers).filter(handlerFilter).length * ((height + 10) / 2) + height / 2, }, data: { label: handler.slice(6) }, ...defaultNodeOptions, - }); + }) initialEdges.push({ id: `handleDiscordPayload-${handler}`, - source: "baseNode-handleDiscordPayload", + 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", - }); + 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 }); + initialEdges.push({ id: `${handler}-${transformer}`, source: handler, target: transformer }) } - if ( - !initialEdges.find((edge) => edge.id === `${transformer}-${handlers[handler].event}`) && handlers[handler].event - ) { + 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, - }); + }) } } } @@ -382,7 +330,7 @@ export default function FlowChart({ handlerFilter = (handler: string) => true }) }, data: { label: transformer.slice(13) }, ...defaultNodeOptions, - }); + }) } //@ts-ignore @@ -392,239 +340,244 @@ export default function FlowChart({ handlerFilter = (handler: string) => true }) position: { x: 4 * multiplier, y: index * (height + 10) - events.length * ((height + 10) / 2) + height / 2 }, data: { label: event.slice(7) }, ...defaultNodeOptions, - }); + }) } initialNodes.unshift( { - id: "handlers", - type: "group", + id: 'handlers', + type: 'group', position: { x: 1.925 * multiplier, y: -Object.keys(handlers).filter(handlerFilter).length * ((height + 10) / 2) - 45, }, - data: { label: "" }, + data: { label: '' }, style: { height: `${Object.keys(handlers).filter(handlerFilter).length * (height + 10) + 75}px`, width: `${multiplier * 0.9}px`, - borderColor: "rgba(0,0,0,0.25)", + borderColor: 'rgba(0,0,0,0.25)', }, draggable: false, }, { - id: "baseLineNodeText-4", - type: "baseLineNodeText", + id: 'baseLineNodeText-4', + type: 'baseLineNodeText', position: { x: 2 * multiplier, - y: -Object.keys(handlers).filter(handlerFilter).length * ((height + 10) / 2) - ((height + 10) / 2), + y: -Object.keys(handlers).filter(handlerFilter).length * ((height + 10) / 2) - (height + 10) / 2, }, - data: { label: "Handlers" }, + data: { label: 'Handlers' }, draggable: false, }, { - id: "transformers", - type: "group", + id: 'transformers', + type: 'group', position: { x: 2.925 * multiplier, y: -transformers.length * ((height + 10) / 2) - 45 }, - data: { label: "" }, + data: { label: '' }, style: { height: `${transformers.length * (height + 10) + 75}px`, width: `${multiplier * 0.9}px`, - borderColor: "rgba(0,0,0,0.25)", + borderColor: 'rgba(0,0,0,0.25)', }, draggable: false, }, { - id: "baseLineNodeText-5", - type: "baseLineNodeText", - position: { x: 3 * multiplier, y: -transformers.length * ((height + 10) / 2) - ((height + 10) / 2) }, - data: { label: "Transformers" }, + id: 'baseLineNodeText-5', + type: 'baseLineNodeText', + position: { x: 3 * multiplier, y: -transformers.length * ((height + 10) / 2) - (height + 10) / 2 }, + data: { label: 'Transformers' }, draggable: false, }, { - id: "events", - type: "group", + id: 'events', + type: 'group', position: { x: 3.925 * multiplier, y: -events.length * ((height + 10) / 2) - 45 }, - data: { label: "" }, + data: { label: '' }, style: { height: `${events.length * (height + 10) + 75}px`, width: `${multiplier * 0.9}px`, - borderColor: "rgba(0,0,0,0.25)", + borderColor: 'rgba(0,0,0,0.25)', }, draggable: false, }, { - id: "baseLineNodeText-6", - type: "baseLineNodeText", - position: { x: 4 * multiplier, y: -events.length * ((height + 10) / 2) - ((height + 10) / 2) }, - data: { label: "Event" }, + id: 'baseLineNodeText-6', + type: 'baseLineNodeText', + position: { x: 4 * multiplier, y: -events.length * ((height + 10) / 2) - (height + 10) / 2 }, + data: { label: 'Event' }, draggable: false, }, - ); + ) - const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes); - const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges); - const [handlerIndex, setHandlerIndex] = useState(0); - const [userClick, setUserClick] = useState(false); + const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes) + const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges) + const [handlerIndex, setHandlerIndex] = useState(0) + const [userClick, setUserClick] = useState(false) const nodeMouseHandler: NodeMouseHandler = (_, node, userTrigger = true) => { - if (userTrigger) setUserClick(true); - if (node.id.split("-")[0] === "baseNode") { + 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 (Object.keys(handlers).find((h) => handlers[h].event === node.id)) { - const handlerName = Object.keys(handlers).find((h) => handlers[h].event === node.id); - const handler = handlers[handlerName]; + const handlerName = Object.keys(handlers).find((h) => handlers[h].event === node.id) + const handler = handlers[handlerName] edges.forEach((e) => { - if (e.id.startsWith("baseLine")) return; - if (e.id.split("-")[0] === "baseEdge") { - e.animated = true; - e.style = { stroke: "blue" }; - return; + if (e.id.startsWith('baseLine')) return + if (e.id.split('-')[0] === 'baseEdge') { + 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; + if (e.id.split('-')[0] === 'handleDiscordPayload' && e.id.split('-')[1] === handlerName) { + 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; + if (e.id.split('-')[0] === handlerName && handler.transformers.includes(e.id.split('-')[1])) { + 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; + if (handler.transformers.includes(e.id.split('-')[0]) && e.id.split('-')[1] === handler.event) { + 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; + if (e.id.split('-')[0] === handler.event && e.id.split('-')[1] === 'yourCode') { + 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 (Object.keys(handlers).find((h) => handlers[h].transformers.includes(node.id))) { edges.forEach((e) => { - if (e.id.startsWith("baseLine")) return; - if (e.id.split("-")[0] === "baseEdge") { - e.animated = true; - e.style = { stroke: "blue" }; - return; + if (e.id.startsWith('baseLine')) return + if (e.id.split('-')[0] === 'baseEdge') { + e.animated = true + e.style = { stroke: 'blue' } + return } if ( - e.id.split("-")[0] === "handleDiscordPayload" && - Object.keys(handlers).filter((h) => handlers[h].transformers.includes(node.id)).includes(e.id.split("-")[1]) + e.id.split('-')[0] === 'handleDiscordPayload' && + Object.keys(handlers) + .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 ( - Object.keys(handlers).filter((h) => handlers[h].transformers.includes(node.id)).includes( - e.id.split("-")[0], - ) && e.id.split("-")[1] === node.id + Object.keys(handlers) + .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; + if (e.id.split('-')[0] === node.id) { + 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.split("-")[0] === "baseEdge") { - e.animated = true; - e.style = { stroke: "blue" }; - return; + if (e.id.startsWith('baseLine')) return + if (e.id.split('-')[0] === 'baseEdge') { + 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; + if (e.id.split('-')[0] === 'handleDiscordPayload' && e.id.split('-')[1] === node.id) { + 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; + if (e.id.split('-')[0] === node.id && handler.transformers.includes(e.id.split('-')[1])) { + 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; + if (handler.transformers.includes(e.id.split('-')[0]) && e.id.split('-')[1] === handler.event) { + e.animated = true + e.style = { stroke: 'blue' } + return } - if (e.id.split("-")[0] === handler.event) { - 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 = 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((Object.keys(handlers).filter(handlerFilter).length - 1) * Math.random()); + const randomIndex = Math.round((Object.keys(handlers).filter(handlerFilter).length - 1) * Math.random()) if (!userClick) { - nodeMouseHandler(undefined, { id: Object.keys(handlers).filter(handlerFilter)[randomIndex] }, false); + nodeMouseHandler(undefined, { id: Object.keys(handlers).filter(handlerFilter)[randomIndex] }, false) } - setHandlerIndex(randomIndex); - }, 1000); - return () => clearInterval(interval); - }, [userClick]); + setHandlerIndex(randomIndex) + }, 1000) + return () => clearInterval(interval) + }, [userClick]) useEffect(() => { if (userClick) { const timeout = setTimeout(() => { - setUserClick(false); - }, 10000); - return () => clearTimeout(timeout); + setUserClick(false) + }, 10000) + return () => clearTimeout(timeout) } - }, [userClick]); + }, [userClick]) return ( <>
        = 997 - ? `${ - (100 * - ((windowDimensions.width - 300 - - (windowDimensions.width >= 1620 ? (windowDimensions.width - 1620) * 0.5 : 0)) / - windowDimensions.width) - 2) * widthMultiplier - }vw` - : "95vw", - height: "50vh", + width: + windowDimensions.width >= 997 + ? `${ + (100 * + ((windowDimensions.width - 300 - (windowDimensions.width >= 1620 ? (windowDimensions.width - 1620) * 0.5 : 0)) / + windowDimensions.width) - + 2) * + widthMultiplier + }vw` + : '95vw', + height: '50vh', }} > true }) onNodeClick={nodeMouseHandler} onClick={(e) => { //@ts-ignore - if (e.target.className === "react-flow__pane") nodeMouseHandler(e, { id: " - ", data: { label: " - " } }); + if (e.target.className === 'react-flow__pane') nodeMouseHandler(e, { id: ' - ', data: { label: ' - ' } }) }} nodeTypes={{ baseLineNode: () => ( -
        - - +
        + +
        ), baseLineNodeText: (n) => ( -
        +

        {n.data.label}

        ), @@ -665,5 +610,5 @@ export default function FlowChart({ handlerFilter = (handler: string) => true })
        - ); + ) } diff --git a/site/src/pages/index.tsx b/site/src/pages/index.tsx index 21d3bc09e..7a1add0ed 100644 --- a/site/src/pages/index.tsx +++ b/site/src/pages/index.tsx @@ -1,42 +1,36 @@ -import Link from "@docusaurus/Link"; -import useDocusaurusContext from "@docusaurus/useDocusaurusContext"; -import Layout from "@theme/Layout"; -import clsx from "clsx"; -import React from "react"; -import HomepageFeatures from "../components/HomepageFeatures"; -import styles from "./index.module.css"; +import Link from '@docusaurus/Link' +import useDocusaurusContext from '@docusaurus/useDocusaurusContext' +import Layout from '@theme/Layout' +import clsx from 'clsx' +import React from 'react' +import HomepageFeatures from '../components/HomepageFeatures' +import styles from './index.module.css' function HomepageHeader() { - const { siteConfig } = useDocusaurusContext(); + const { siteConfig } = useDocusaurusContext() return ( -
        +

        {siteConfig.title}

        {siteConfig.tagline}

        - + Discordeno Tutorial
        - ); + ) } export default function Home(): JSX.Element { - const { siteConfig } = useDocusaurusContext(); + const { siteConfig } = useDocusaurusContext() return ( - +
        - ); + ) } diff --git a/site/tutorial/amethyst/exampleBot.md b/site/tutorial/amethyst/exampleBot.md index 8dd89659e..74424ff5f 100644 --- a/site/tutorial/amethyst/exampleBot.md +++ b/site/tutorial/amethyst/exampleBot.md @@ -17,54 +17,47 @@ npm i @thereallonewolf/amethystframework - **Step 4**: Add following code in index.ts file, replacing TOKEN with your bot token. ```ts -import { createBot, GatewayIntents, startBot } from "discordeno"; -import { enableCachePlugin, enableCacheSweepers } from "discordeno/cache-plugin"; -import { - AmethystBot, - Category, - Command, - Context, - enableAmethystPlugin, - Event, -} from "@thereallonewolf/amethystframework"; +import { createBot, GatewayIntents, startBot } from 'discordeno' +import { enableCachePlugin, enableCacheSweepers } from 'discordeno/cache-plugin' +import { AmethystBot, Category, Command, Context, enableAmethystPlugin, Event } from '@thereallonewolf/amethystframework' let baseClient = createBot({ - token: "TOKEN", + token: 'TOKEN', intents: GatewayIntents.Guilds | GatewayIntents.GuildMessages | GatewayIntents.MessageContent, -}); +}) //@ts-ignore let client = enableAmethystPlugin(enableCachePlugin(baseClient), { botMentionAsPrefix: true, - prefix: "!", //Can be a function or a string. + prefix: '!', //Can be a function or a string. ignoreBots: false, -}); -enableCacheSweepers(client); +}) +enableCacheSweepers(client) -startBot(client); +startBot(client) @Category({ - name: "general", - description: "My general commands", + name: 'general', + description: 'My general commands', uniqueCommands: true, - default: "", //As all the commands are unique so no need to set the default command. + default: '', //As all the commands are unique so no need to set the default command. }) export class General { @Command({ - name: "ping", - description: "Pong!", - commandType: ["application", "message"], - category: "general", + name: 'ping', + description: 'Pong!', + commandType: ['application', 'message'], + category: 'general', args: [], }) async ping(bot: AmethystBot, ctx: Context) { - ctx.reply({ content: "Pong!" }); + ctx.reply({ content: 'Pong!' }) } - @Event("ready") + @Event('ready') async ready() { - console.log("I am ready!"); - client.amethystUtils.updateSlashCommands(); + console.log('I am ready!') + client.amethystUtils.updateSlashCommands() } } ``` diff --git a/site/tutorial/big-bot-guide/cache.md b/site/tutorial/big-bot-guide/cache.md index da148767a..18302f8c0 100644 --- a/site/tutorial/big-bot-guide/cache.md +++ b/site/tutorial/big-bot-guide/cache.md @@ -80,15 +80,15 @@ Now we will initiate our cache service. This may be different for you based on y using PGSQL for our cache layer, we will now instantiate it. ```ts -import { postgres } from "../../../deps.ts"; +import { postgres } from '../../../deps.ts' // YOU CUSTOM PGSQL INFO GOES HERE -const DATABASE_USERNAME = ""; -const DATABASE_PASSWORD = ""; -const DATABASE_NAME = ""; -const DATABASE_HOST = ""; -const DATABASE_PORT = 8956; -const DATABASE_MAX = 20; +const DATABASE_USERNAME = '' +const DATABASE_PASSWORD = '' +const DATABASE_NAME = '' +const DATABASE_HOST = '' +const DATABASE_PORT = 8956 +const DATABASE_MAX = 20 export const psql = postgres({ username: DATABASE_USERNAME, @@ -103,14 +103,14 @@ export const psql = postgres({ types: { bigint: postgres.BigInt, }, -}); +}) ``` To use the PGSQL driver we are using in this guide you can insert this into your `deps.ts`. ```ts // @deno-types="https://denopkg.com/porsager/postgres@e2a8595d7aa8c3c838b83b9bca7b890c1707ad2c/types/index.d.ts" -export { default as postgres } from "https://denopkg.com/porsager/postgres@e2a8595d7aa8c3c838b83b9bca7b890c1707ad2c/deno/lib/index.js"; +export { default as postgres } from 'https://denopkg.com/porsager/postgres@e2a8595d7aa8c3c838b83b9bca7b890c1707ad2c/deno/lib/index.js' ``` > Note: Remember you can use any driver you like. For deno users we prefer to use this library for PGSQL because it is diff --git a/site/tutorial/big-bot-guide/events.md b/site/tutorial/big-bot-guide/events.md index 2abb18f3f..deceb7a38 100644 --- a/site/tutorial/big-bot-guide/events.md +++ b/site/tutorial/big-bot-guide/events.md @@ -24,9 +24,9 @@ reloaded instantly. Create a file path like `src/bot/mod.ts`. ```ts -import { DISCORD_TOKEN } from "../../configs.ts"; -import { Collection, createBot, Intents } from "../../deps.ts"; -import { psql } from "./cache/mod.ts"; +import { DISCORD_TOKEN } from '../../configs.ts' +import { Collection, createBot, Intents } from '../../deps.ts' +import { psql } from './cache/mod.ts' export const bot = createBot({ token: DISCORD_TOKEN, @@ -34,10 +34,10 @@ export const bot = createBot({ intents: Intents.Guilds | Intents.GuildMessages, events: { messageCreate: function (bot, message) { - console.log("message arrived"); + console.log('message arrived') }, }, -}); +}) ``` Alright that was a lot of code. Now let's break it down little by little. @@ -69,56 +69,36 @@ Here we'll have some basic functions to make use of the cache we created in step const cache = { /** Get a single item from the table */ async get(key) { - return await psql`SELECT * FROM ${ - psql( - tables[table], - ) - } WHERE "id" = ${psql.types.bigint(key)}`; + return await psql`SELECT * FROM ${psql(tables[table])} WHERE "id" = ${psql.types.bigint(key)}` }, /** Completely empty this table. */ async clear() { - await psql`TRUNCATE TABLE ${psql(tables[table])}`; + await psql`TRUNCATE TABLE ${psql(tables[table])}` }, /** Delete the data related to this key from table. */ async delete(key) { - await psql`DELETE FROM ${ - psql( - tables[table], - ) - } WHERE "id" = ${psql.types.bigint(key)}`; - return true; + await psql`DELETE FROM ${psql(tables[table])} WHERE "id" = ${psql.types.bigint(key)}` + return true }, /** Check if there is data assigned to this key. */ async has(key) { - return Boolean( - await psql`SELECT 1 FROM ${ - psql( - tables[table], - ) - } WHERE "id" = ${psql.types.bigint(key)}`, - ); + return Boolean(await psql`SELECT 1 FROM ${psql(tables[table])} WHERE "id" = ${psql.types.bigint(key)}`) }, /** Check how many items are stored in this table. */ async size() { - return (await psql`SELECT COUNT("id") FROM ${psql(tables[table])}`) - .count; + return (await psql`SELECT COUNT("id") FROM ${psql(tables[table])}`).count }, /** Store new data to this table. */ async set(key, data) { - await psql`INSERT INTO ${psql(tables[table])} ${ - psql( - data, - ...Object.keys(data), - ) - }`; - return true; + await psql`INSERT INTO ${psql(tables[table])} ${psql(data, ...Object.keys(data))}` + return true }, // THESE TWO ARE USELESS FOR CUSTOM CACHE BUT NEED TO SHUT UP TS ERRORS async forEach(callback) {}, async filter(callback) { - return new Collection(); + return new Collection() }, -}; +} ``` You can insert any code you desire for your cache system here. Since we were using PGSQL, we used sql queries to make @@ -146,47 +126,44 @@ below simply to keep code cleaner and simpler, in expectation that it will grow as you wish. ```ts -import { Bot } from "../../../deps.ts"; -import { customizeBotTransformers } from "./transformers/mod.ts"; +import { Bot } from '../../../deps.ts' +import { customizeBotTransformers } from './transformers/mod.ts' export function customizeBotInternals(bot: Bot) { - bot = customizeBotTransformers(bot); + bot = customizeBotTransformers(bot) // ADD AS MANY MORE CUSTOMIZATIONS HERE AS YOU LIKE TO HANDLERS, HELPERS, UTILS ETC... - return bot; + return bot } ``` We also need to add another file now at `src/bot/internals/transformers/mod.ts` ```ts -import { Bot } from "../../../../deps.ts"; -import { customizeUserTransformer } from "./user.ts"; +import { Bot } from '../../../../deps.ts' +import { customizeUserTransformer } from './user.ts' export function customizeBotTransformers(bot: Bot) { - bot = customizeUserTransformer(bot); + bot = customizeUserTransformer(bot) // ADD ANY MORE CUSTOM TRANSFORMERS HERE - return bot; + return bot } ``` One more file at `src/bot/internals/transformers/user.ts` ```ts -import { Bot, DiscordenoUser, transformUser } from "../../../../deps.ts"; +import { Bot, DiscordenoUser, transformUser } from '../../../../deps.ts' export function customizeUserTransformer(bot: Bot) { bot.transformers.user = function (bot, payload) { // REMOVE USELESS PROPS OUR BOT DOESNT USE - const { system, locale, verified, email, flags, mfaEnabled, premiumType, publicFlags, ...user } = transformUser( - bot, - payload, - ); + const { system, locale, verified, email, flags, mfaEnabled, premiumType, publicFlags, ...user } = transformUser(bot, payload) // RETURN ONLY USEFUL PROPS WE NEED TO USE AND CACHE IF NECESSARY - return user as DiscordenoUser; - }; + return user as DiscordenoUser + } - return bot; + return bot } ``` @@ -210,51 +187,51 @@ Create a file in a path like `src/bot/gatewayEventsListener.ts` Now we should create a http listener, check for authorization in headers, run `bot.events.raw` and `bot.handlers[event]` ```ts -import { DiscordGatewayPayload } from "discordeno"; -import { EVENT_HANDLER_PORT, REST_AUTHORIZATION } from "../../configs.ts"; +import { DiscordGatewayPayload } from 'discordeno' +import { EVENT_HANDLER_PORT, REST_AUTHORIZATION } from '../../configs.ts' -const server = Deno.listen({ port: EVENT_HANDLER_PORT }); +const server = Deno.listen({ port: EVENT_HANDLER_PORT }) // Connections to the server will be yielded up as an async iterable. for await (const conn of server) { // In order to not be blocking, we need to handle each connection individually // in its own async function. - handleRequest(conn); + handleRequest(conn) } async function handleRequest(conn: Deno.Conn) { // This "upgrades" a network connection into an HTTP connection. - const httpConn = Deno.serveHttp(conn); + const httpConn = Deno.serveHttp(conn) // Each request sent over the HTTP connection will be yielded as an async // iterator from the HTTP connection. for await (const requestEvent of httpConn) { - if (!REST_AUTHORIZATION || REST_AUTHORIZATION !== requestEvent.request.headers.get("AUTHORIZATION")) { + if (!REST_AUTHORIZATION || REST_AUTHORIZATION !== requestEvent.request.headers.get('AUTHORIZATION')) { return requestEvent.respondWith( - new Response(JSON.stringify({ error: "Invalid authorization key." }), { + new Response(JSON.stringify({ error: 'Invalid authorization key.' }), { status: 401, }), - ); + ) } const json = (await requestEvent.request.json()) as { - message: DiscordGatewayPayload; - shardId: number; - }; + message: DiscordGatewayPayload + shardId: number + } // Run raw event. - bot.events.raw(bot, json.message, json.shardId); + bot.events.raw(bot, json.message, json.shardId) - if (json.message.t && json.message.t !== "RESUMED") { + if (json.message.t && json.message.t !== 'RESUMED') { // When a guild or something isn't in cache this will fetch it before doing anything else. - if (!["READY", "GUILD_LOADED_DD"].includes(json.message.t)) { - await bot.events.dispatchRequirements(bot, json.message, json.shardId); + if (!['READY', 'GUILD_LOADED_DD'].includes(json.message.t)) { + await bot.events.dispatchRequirements(bot, json.message, json.shardId) } // Run event function provided in bot.events - bot.handlers[json.message.t]?.(bot, json.message, json.shardId); + bot.handlers[json.message.t]?.(bot, json.message, json.shardId) } - new Response(undefined, { status: 200 }); + new Response(undefined, { status: 200 }) } } ``` diff --git a/site/tutorial/big-bot-guide/gateway.md b/site/tutorial/big-bot-guide/gateway.md index 7f79dd954..5f76d30ed 100644 --- a/site/tutorial/big-bot-guide/gateway.md +++ b/site/tutorial/big-bot-guide/gateway.md @@ -61,14 +61,14 @@ Before, we dive into how, here is a quick summary of why you will want a standal Create a file under some path like `src/gateway/mod.ts`. ```ts -import { DISCORD_TOKEN, REST_AUTHORIZATION, REST_PORT } from "../../configs.ts"; -import { BASE_URL, createRestManager } from "../../deps.ts"; +import { DISCORD_TOKEN, REST_AUTHORIZATION, REST_PORT } from '../../configs.ts' +import { BASE_URL, createRestManager } from '../../deps.ts' const rest = createRestManager({ token: DISCORD_TOKEN, secretKey: REST_AUTHORIZATION, customUrl: `http://localhost:${REST_PORT}`, -}); +}) ``` Throw another rest manager here which will be responsible for calling the main REST process we created in Step 1. This @@ -84,16 +84,16 @@ Now we need to use this rest manager to call the api to get information about ho your bot. ```ts -import { routes } from "../../deps.ts"; +import { routes } from '../../deps.ts' const rest = createRestManager({ token: DISCORD_TOKEN, secretKey: REST_AUTHORIZATION, customUrl: `http://localhost:${REST_PORT}`, -}); +}) // CALL THE REST PROCESS TO GET GATEWAY DATA -const gatewayBot = await rest.runMethod(rest, "GET", routes.GATEWAY_BOT()).then((res) => ({ +const gatewayBot = await rest.runMethod(rest, 'GET', routes.GATEWAY_BOT()).then((res) => ({ url: res.url, shards: res.shards, sessionStartLimit: { @@ -102,7 +102,7 @@ const gatewayBot = await rest.runMethod(rest, "GET", routes.GATEWAY_BOT()).then( resetAfter: res.session_start_limit.reset_after, maxConcurrency: res.session_start_limit.max_concurrency, }, -})); +})) ``` With this info, we can now create our gateway manager. @@ -110,7 +110,7 @@ With this info, we can now create our gateway manager. ### Understanding Gateway Manager ```ts -import { INTENTS, SHARDS_PER_WORKER, TOTAL_WORKERS } from "../../configs.ts"; +import { INTENTS, SHARDS_PER_WORKER, TOTAL_WORKERS } from '../../configs.ts' const gateway = createGatewayManager({ gatewayBot, @@ -124,7 +124,7 @@ const gateway = createGatewayManager({ // debug: console.log, // THIS WILL BE USED LATER IN WORKER SO LEAVE IT HERE handleDiscordPayload: () => {}, -}); +}) ``` #### Basic Keys @@ -171,7 +171,7 @@ change the logic in any method it is as simple as: // TYPINGS WILL BE AUTOMATICALLY PROVIDED gateway.heartbeat = function (gateway, shardId, interval) { // YOUR CUSTOM HANDLING CODE HERE -}; +} ``` ## Workers @@ -188,20 +188,20 @@ to create workers and send message: ```ts gateway.tellWorkerToIdentify = async (_gateway, workerId, shardId, _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) } // TYPE TYPE WorkerMessage IS FROM WORKER FILE, DISCUSSED IN DETAIL BELOW const identify: WorkerMessage = { - type: "IDENTIFY_SHARD", + type: 'IDENTIFY_SHARD', shardId, - }; + } - worker.postMessage(identify); -}; + worker.postMessage(identify) +} ``` You can choose to replace the handler with any desired functionality you like. For example, should should you want to @@ -212,13 +212,13 @@ Now that we've setup our initial gateway manager and added `tellWorkerToIdentify of the work: creating workers, spawning shards etc. ```ts -import { EVENT_HANDLER_SECRET_KEY, EVENT_HANDLER_URL } from "../../configs.ts"; -import { Worker } from "worker_threads"; -import { WorkerCreateData, WorkerGetShardInfo, WorkerMessage, WorkerShardInfo, WorkerShardPayload } from "./worker.js"; +import { EVENT_HANDLER_SECRET_KEY, EVENT_HANDLER_URL } from '../../configs.ts' +import { Worker } from 'worker_threads' +import { WorkerCreateData, WorkerGetShardInfo, WorkerMessage, WorkerShardInfo, WorkerShardPayload } from './worker.js' // A COLLECTION OF WORKERS -const workers = new Collection(); -const nonces = new Collection void>(); +const workers = new Collection() +const nonces = new Collection void>() function createWorker(workerId: number) { const workerData: WorkerCreateData = { @@ -227,51 +227,51 @@ function createWorker(workerId: number) { // TODO: PUT THIS SEPARATELY. CAN USE MULTIPLE URLS IF YOU HAVE MULTIPLE BOT PROCESSES HANDLING DIFFERENT SHARDS' EVENTS handlerUrls: [EVENT_HANDLER_URL], handlerAuthorization: EVENT_HANDLER_SECRET_KEY, - path: "./worker.ts", + path: './worker.ts', totalShards: gateway.manager.totalShards, workerId, - }; + } - const worker = new Worker("./worker.js", { + const worker = new Worker('./worker.js', { workerData, - }); + }) - worker.on("message", async (data: ManagerMessage) => { + worker.on('message', async (data: ManagerMessage) => { switch (data.type) { - case "REQUEST_IDENTIFY": { - await gateway.manager.requestIdentify(data.shardId); + case 'REQUEST_IDENTIFY': { + await gateway.manager.requestIdentify(data.shardId) const allowIdentify: WorkerMessage = { - type: "ALLOW_IDENTIFY", + type: 'ALLOW_IDENTIFY', shardId: data.shardId, - }; + } - worker.postMessage(allowIdentify); + worker.postMessage(allowIdentify) - break; + break } - case "NONCE_REPLY": { - nonces.get(data.nonce)?.(data.data); + case 'NONCE_REPLY': { + nonces.get(data.nonce)?.(data.data) } } - }); + }) - return worker; + return worker } // TYPES WE USE -export type ManagerMessage = ManagerRequestIdentify | ManagerNonceReply; +export type ManagerMessage = ManagerRequestIdentify | ManagerNonceReply export type ManagerRequestIdentify = { - type: "REQUEST_IDENTIFY"; - shardId: number; -}; + type: 'REQUEST_IDENTIFY' + shardId: number +} export type ManagerNonceReply = { - type: "NONCE_REPLY"; - nonce: string; - data: T; -}; + type: 'NONCE_REPLY' + nonce: string + data: T +} ``` ## Spawning Shards @@ -279,7 +279,7 @@ export type ManagerNonceReply = { Once you are ready and the gateway has been created as you desired, we can begin spawning the shards. ```ts -gateway.spawnShards(gateway); +gateway.spawnShards(gateway) ``` This code now handles creating gateway manager, creating workers, spawning shards and sending the info to each workers. @@ -297,25 +297,25 @@ import { REST_PORT, SHARDS_PER_WORKER, TOTAL_WORKERS, -} from "../../configs.ts"; -import { BASE_URL, createRestManager, routes } from "../../deps.ts"; -import { Worker } from "worker_threads"; -import { WorkerCreateData, WorkerGetShardInfo, WorkerMessage, WorkerShardInfo, WorkerShardPayload } from "./worker.ts"; +} from '../../configs.ts' +import { BASE_URL, createRestManager, routes } from '../../deps.ts' +import { Worker } from 'worker_threads' +import { WorkerCreateData, WorkerGetShardInfo, WorkerMessage, WorkerShardInfo, WorkerShardPayload } from './worker.ts' const rest = createRestManager({ token: DISCORD_TOKEN, secretKey: REST_AUTHORIZATION, customUrl: `http://localhost:${REST_PORT}`, -}); +}) const rest = createRestManager({ token: DISCORD_TOKEN, secretKey: REST_AUTHORIZATION, customUrl: `http://localhost:${REST_PORT}`, -}); +}) // CALL THE REST PROCESS TO GET GATEWAY DATA -const gatewayBot = await rest.runMethod(rest, "GET", routes.GATEWAY_BOT()).then((res) => ({ +const gatewayBot = await rest.runMethod(rest, 'GET', routes.GATEWAY_BOT()).then((res) => ({ url: res.url, shards: res.shards, sessionStartLimit: { @@ -324,7 +324,7 @@ const gatewayBot = await rest.runMethod(rest, "GET", routes.GATEWAY_BOT()).then( resetAfter: res.session_start_limit.reset_after, maxConcurrency: res.session_start_limit.max_concurrency, }, -})); +})) const gateway = createGatewayManager({ gatewayBot, @@ -338,25 +338,25 @@ const gateway = createGatewayManager({ // debug: console.log, handleDiscordPayload: () => {}, tellWorkerToIdentify: async (_gateway, workerId, shardId, _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) } // TYPE TYPE WorkerMessage IS FROM WORKER FILE, DISCUSSED IN DETAIL BELOW const identify: WorkerMessage = { - type: "IDENTIFY_SHARD", + type: 'IDENTIFY_SHARD', shardId, - }; + } - worker.postMessage(identify); + worker.postMessage(identify) }, -}); +}) // A COLLECTION OF WORKERS -const workers = new Collection(); -const nonces = new Collection void>(); +const workers = new Collection() +const nonces = new Collection void>() function createWorker(workerId: number) { const workerData: WorkerCreateData = { @@ -364,54 +364,54 @@ function createWorker(workerId: number) { token: DISCORD_TOKEN, handlerUrls: [EVENT_HANDLER_URL], handlerAuthorization: EVENT_HANDLER_SECRET_KEY, - path: "./worker.ts", + path: './worker.ts', totalShards: gateway.manager.totalShards, workerId, - }; + } - const worker = new Worker("./worker.ts", { + const worker = new Worker('./worker.ts', { workerData, - }); + }) - worker.on("message", async (data: ManagerMessage) => { + worker.on('message', async (data: ManagerMessage) => { switch (data.type) { - case "REQUEST_IDENTIFY": { - await gateway.manager.requestIdentify(data.shardId); + case 'REQUEST_IDENTIFY': { + await gateway.manager.requestIdentify(data.shardId) const allowIdentify: WorkerMessage = { - type: "ALLOW_IDENTIFY", + type: 'ALLOW_IDENTIFY', shardId: data.shardId, - }; + } - worker.postMessage(allowIdentify); + worker.postMessage(allowIdentify) - break; + break } - case "NONCE_REPLY": { - nonces.get(data.nonce)?.(data.data); + case 'NONCE_REPLY': { + nonces.get(data.nonce)?.(data.data) } } - }); + }) - return worker; + return worker } // TYPES WE USE -export type ManagerMessage = ManagerRequestIdentify | ManagerNonceReply; +export type ManagerMessage = ManagerRequestIdentify | ManagerNonceReply export type ManagerRequestIdentify = { - type: "REQUEST_IDENTIFY"; - shardId: number; -}; + type: 'REQUEST_IDENTIFY' + shardId: number +} export type ManagerNonceReply = { - type: "NONCE_REPLY"; - nonce: string; - data: T; -}; + type: 'NONCE_REPLY' + nonce: string + data: T +} // SPAWN SHARDS INTO WORKERS -gateway.spawnShards(); +gateway.spawnShards() ``` ## Worker File @@ -424,17 +424,17 @@ Create a file in a path like `src/gateway/worker.ts`. Now we'll have to create a Shard Manager, this is what will handle identifying, receiving events. ```ts -import { createShardManager } from "discordeno"; -import { parentPort, workerData } from "worker_threads"; +import { createShardManager } from 'discordeno' +import { parentPort, workerData } from 'worker_threads' if (!parentPort) { - throw new Error("Parent port is null"); + throw new Error('Parent port is null') } // THE DATA WE GET FROM GATEWAY FILE -const script: WorkerCreateData = workerData; +const script: WorkerCreateData = workerData -const identifyPromises = new Map void>(); +const identifyPromises = new Map void>() const manager = createShardManager({ gatewayConfig: { @@ -446,7 +446,7 @@ const manager = createShardManager({ // WE WILL COVER THESE TWO FUNCTIONS IN LATER PART OF THE GUIDE, FOR NOW, LEAVE IT THIS WAY handleMessage: () => {}, requestIdentify: async () => {}, -}); +}) ``` The above code only creates a shard manager, we now have 3 more things to do: @@ -461,7 +461,7 @@ In order for the shards to receive events and send to bot process, we need to re first, we can do this by using `message` event in `parentPort` like shown below: ```ts -import { Shard } from "discordeno"; +import { Shard } from 'discordeno' function buildShardInfo(shard: Shard): WorkerShardInfo { return { @@ -469,84 +469,84 @@ function buildShardInfo(shard: Shard): WorkerShardInfo { shardId: shard.id, rtt: shard.heart.rtt || -1, state: shard.state, - }; + } } -parentPort.on("message", async (data: WorkerMessage) => { +parentPort.on('message', async (data: WorkerMessage) => { switch (data.type) { // Gateway sends IDENTIFY_SHARD in gateway.tellWorkerToIdentify - case "IDENTIFY_SHARD": { - await manager.identify(data.shardId); + case 'IDENTIFY_SHARD': { + await manager.identify(data.shardId) - break; + break } // Gateway sends ALLOW_IDENTIFY when worker requests to identify - case "ALLOW_IDENTIFY": { - identifyPromises.get(data.shardId)?.(); - identifyPromises.delete(data.shardId); + case 'ALLOW_IDENTIFY': { + identifyPromises.get(data.shardId)?.() + identifyPromises.delete(data.shardId) - break; + break } // Gateway sends SHARD_PAYLOAD for every events it receives from Discord - case "SHARD_PAYLOAD": { - manager.shards.get(data.shardId)?.send(data.data); + case 'SHARD_PAYLOAD': { + manager.shards.get(data.shardId)?.send(data.data) - break; + break } // Send shard info if gateway sends GET_SHARD_INFO - case "GET_SHARD_INFO": { - const infos = manager.shards.map(buildShardInfo); + case 'GET_SHARD_INFO': { + const infos = manager.shards.map(buildShardInfo) - parentPort?.postMessage({ type: "NONCE_REPLY", nonce: data.nonce, data: infos }); + parentPort?.postMessage({ type: 'NONCE_REPLY', nonce: data.nonce, data: infos }) } } -}); +}) ``` Now TypeScript will error because of missing types, add these to your code: ```ts -import { ShardSocketRequest, ShardState } from "discordeno"; +import { ShardSocketRequest, ShardState } from 'discordeno' -export type WorkerMessage = WorkerIdentifyShard | WorkerAllowIdentify | WorkerShardPayload | WorkerGetShardInfo; +export type WorkerMessage = WorkerIdentifyShard | WorkerAllowIdentify | WorkerShardPayload | WorkerGetShardInfo export type WorkerIdentifyShard = { - type: "IDENTIFY_SHARD"; - shardId: number; -}; + type: 'IDENTIFY_SHARD' + shardId: number +} export type WorkerAllowIdentify = { - type: "ALLOW_IDENTIFY"; - shardId: number; -}; + type: 'ALLOW_IDENTIFY' + shardId: number +} export type WorkerShardPayload = { - type: "SHARD_PAYLOAD"; - shardId: number; - data: ShardSocketRequest; -}; + type: 'SHARD_PAYLOAD' + shardId: number + data: ShardSocketRequest +} export type WorkerGetShardInfo = { - type: "GET_SHARD_INFO"; - nonce: string; -}; + type: 'GET_SHARD_INFO' + nonce: string +} export type WorkerCreateData = { - intents: number; - token: string; - handlerUrls: string[]; - handlerAuthorization: string; - path: string; - totalShards: number; - workerId: number; -}; + intents: number + token: string + handlerUrls: string[] + handlerAuthorization: string + path: string + totalShards: number + workerId: number +} export type WorkerShardInfo = { - workerId: number; - shardId: number; - rtt: number; - state: ShardState; -}; + workerId: number + shardId: number + rtt: number + state: ShardState +} ``` ## Handling Discord Payloads @@ -558,15 +558,15 @@ with anything you like. ```ts manager.createShardOptions.handleMessage = async (shard, message) => { - const url = script.handlerUrls[shard.id % script.handlerUrls.length]; - if (!url) return console.error("ERROR: NO URL FOUND TO SEND MESSAGE"); + const url = script.handlerUrls[shard.id % script.handlerUrls.length] + if (!url) return console.error('ERROR: NO URL FOUND TO SEND MESSAGE') await fetch(url, { - method: "POST", + method: 'POST', body: JSON.stringify({ message, shardId: shard.id }), - headers: { "Content-Type": "application/json", Authorization: script.handlerAuthorization }, - }).catch((error) => console.error(error)); -}; + headers: { 'Content-Type': 'application/json', Authorization: script.handlerAuthorization }, + }).catch((error) => console.error(error)) +} ``` You can change this function to use a WS or any form of communication you prefer to use to send this to your event @@ -597,21 +597,21 @@ Now TypeScript will probably throw some errors at your face, so let's fix those hold the queue of events for our gateway. ```ts -import { DiscordGatewayPayload } from "discordeno"; +import { DiscordGatewayPayload } from 'discordeno' const queue: GatewayQueue = { processing: false, events: [], -}; +} export interface QueuedEvent { - message: DiscordGatewayPayload; - shardId: number; + message: DiscordGatewayPayload + shardId: number } export interface GatewayQueue { - processing: boolean; - events: QueuedEvent[]; + processing: boolean + events: QueuedEvent[] } async function handleQueue() { @@ -644,38 +644,33 @@ automatically respond to the ones that can not be deferred. For the interactions defer them and add this event to the queue. ```ts -import { DiscordInteraction, InteractionResponseTypes, InteractionTypes, routes } from "discordeno"; -import { BOT_SERVER_INVITE_CODE } from "../../configs.ts"; +import { DiscordInteraction, InteractionResponseTypes, InteractionTypes, routes } from 'discordeno' +import { BOT_SERVER_INVITE_CODE } from '../../configs.ts' async function handleInteractionQueueing(message: DiscordGatewayPayload, shardId: number) { - if (message.t !== "INTERACTION_CREATE") return; + if (message.t !== 'INTERACTION_CREATE') return - const interaction = message.d as DiscordInteraction; + const interaction = message.d as DiscordInteraction // IF THIS INTERACTION IS NOT DEFERABLE if ([InteractionTypes.ModalSubmit, InteractionTypes.ApplicationCommandAutocomplete].includes(interaction.type)) { - return await rest.runMethod( - rest, - "POST", - routes.INTERACTION_ID_TOKEN(BigInt(interaction.id), interaction.token), - { - type: InteractionResponseTypes.ChannelMessageWithSource, - data: { - content: - `The bot is having a temporary issue, please try again or contact us at https://discord.gg/${BOT_SERVER_INVITE_CODE}`, - }, + return await rest.runMethod(rest, 'POST', routes.INTERACTION_ID_TOKEN(BigInt(interaction.id), interaction.token), { + type: InteractionResponseTypes.ChannelMessageWithSource, + data: { + content: `The bot is having a temporary issue, please try again or contact us at https://discord.gg/${BOT_SERVER_INVITE_CODE}`, }, - ); + }) } - await rest.runMethod(rest, "POST", endpoints.INTERACTION_ID_TOKEN(BigInt(interaction.id), interaction.token), { + await rest.runMethod(rest, 'POST', endpoints.INTERACTION_ID_TOKEN(BigInt(interaction.id), interaction.token), { // MESSAGE COMPONENTS NEED SPECIAL DEFER - type: InteractionTypes.MessageComponent === interaction.type - ? InteractionResponseTypes.DeferredUpdateMessage - : InteractionResponseTypes.DeferredChannelMessageWithSource, - }); + type: + InteractionTypes.MessageComponent === interaction.type + ? InteractionResponseTypes.DeferredUpdateMessage + : InteractionResponseTypes.DeferredChannelMessageWithSource, + }) // ADD EVENT TO QUEUE - queue.events.push({ shardId, message }); + queue.events.push({ shardId, message }) } ``` @@ -687,7 +682,7 @@ const rest = createRestManager({ token: DISCORD_TOKEN, secretKey: REST_AUTHORIZATION, customUrl: REST_URL, -}); +}) ``` So now there is only one thing left the `handleQueue` function. First we get the first item from the queue using @@ -698,34 +693,34 @@ again to run the next item in the queue. ```ts async function handleQueue() { - const event = queue.events.shift(); + const event = queue.events.shift() // QUEUE IS EMPTY if (!event) { - console.log("GATEWAY QUEUE ENDING"); - queue.processing = false; - return; + console.log('GATEWAY QUEUE ENDING') + queue.processing = false + return } await fetch(EVENT_HANDLER_URL, { headers: { Authorization: EVENT_HANDLER_SECRET_KEY, - "Content-Type": "application/json", + 'Content-Type': 'application/json', }, - method: "POST", + method: 'POST', body: JSON.stringify({ shardId: event.shardId, message: event.message, }), }) .then((res) => { - res.text(); - handleQueue(); + res.text() + handleQueue() }) .catch(() => { // EVENT HANDLER STILL NOT ACCEPTING REQUEST. SO ADD BACK TO QUEUE - queue.events.unshift(event); - setTimeout(handleQueue, 1000); - }); + queue.events.unshift(event) + setTimeout(handleQueue, 1000) + }) } ``` @@ -735,20 +730,20 @@ We need to request identify in order to trigger initial handshake with the gatew to do this. ```ts -import { ManagerMessage } from "./mod.ts"; +import { ManagerMessage } from './mod.ts' manager.requestIdentify = async function (shardId: number): Promise { return await new Promise((resolve) => { - identifyPromises.set(shardId, resolve); + identifyPromises.set(shardId, resolve) const identifyRequest: ManagerMessage = { - type: "REQUEST_IDENTIFY", + type: 'REQUEST_IDENTIFY', shardId, - }; + } - parentPort?.postMessage(identifyRequest); - }); -}; + parentPort?.postMessage(identifyRequest) + }) +} ``` That's all, you've now setup your gateway and worker. Here's the full code of `src/gateway/worker.ts`: @@ -765,32 +760,25 @@ import { Shard, ShardSocketRequest, ShardState, -} from "discordeno"; -import { parentPort, workerData } from "worker_threads"; -import { ManagerMessage } from "./mod"; -import { - BOT_SERVER_INVITE_CODE, - DISCORD_TOKEN, - EVENT_HANDLER_SECRET_KEY, - EVENT_HANDLER_URL, - REST_AUTHORIZATION, - REST_URL, -} from "../../configs.ts"; +} from 'discordeno' +import { parentPort, workerData } from 'worker_threads' +import { ManagerMessage } from './mod' +import { BOT_SERVER_INVITE_CODE, DISCORD_TOKEN, EVENT_HANDLER_SECRET_KEY, EVENT_HANDLER_URL, REST_AUTHORIZATION, REST_URL } from '../../configs.ts' if (!parentPort) { - throw new Error("Parent port is null"); + throw new Error('Parent port is null') } // THE DATA WE GET FROM GATEWAY FILE -const script: WorkerCreateData = workerData; +const script: WorkerCreateData = workerData -const identifyPromises = new Map void>(); +const identifyPromises = new Map void>() const rest = createRestManager({ token: DISCORD_TOKEN, secretKey: REST_AUTHORIZATION, customUrl: REST_URL, -}); +}) const manager = createShardManager({ gatewayConfig: { @@ -800,34 +788,34 @@ const manager = createShardManager({ shardIds: [], totalShards: script.totalShards, handleMessage: async (shard, message) => { - const url = script.handlerUrls[shard.id % script.handlerUrls.length]; - if (!url) return console.error("ERROR: NO URL FOUND TO SEND MESSAGE"); + const url = script.handlerUrls[shard.id % script.handlerUrls.length] + if (!url) return console.error('ERROR: NO URL FOUND TO SEND MESSAGE') await fetch(url, { - method: "POST", + method: 'POST', body: JSON.stringify({ message, shardId: shard.id }), - headers: { "Content-Type": "application/json", Authorization: script.handlerAuthorization }, + headers: { 'Content-Type': 'application/json', Authorization: script.handlerAuthorization }, }).catch(() => { // IF FAILED TRY TO QUEUE MAYBE LISTENER IS DOWN - if (message.t === "INTERACTION_CREATE") handleInteractionQueueing(message, shard.id); - else queue.events.push({ shardId: shard.id, message }); + if (message.t === 'INTERACTION_CREATE') handleInteractionQueueing(message, shard.id) + else queue.events.push({ shardId: shard.id, message }) - setTimeout(handleQueue, 1000); - }); + setTimeout(handleQueue, 1000) + }) }, requestIdentify: async function (shardId: number): Promise { return await new Promise((resolve) => { - identifyPromises.set(shardId, resolve); + identifyPromises.set(shardId, resolve) const identifyRequest: ManagerMessage = { - type: "REQUEST_IDENTIFY", + type: 'REQUEST_IDENTIFY', shardId, - }; + } - parentPort?.postMessage(identifyRequest); - }); + parentPort?.postMessage(identifyRequest) + }) }, -}); +}) function buildShardInfo(shard: Shard): WorkerShardInfo { return { @@ -835,149 +823,149 @@ function buildShardInfo(shard: Shard): WorkerShardInfo { shardId: shard.id, rtt: shard.heart.rtt || -1, state: shard.state, - }; + } } -parentPort.on("message", async (data: WorkerMessage) => { +parentPort.on('message', async (data: WorkerMessage) => { switch (data.type) { // Gateway sends IDENTIFY_SHARD in gateway.tellWorkerToIdentify - case "IDENTIFY_SHARD": { - await manager.identify(data.shardId); + case 'IDENTIFY_SHARD': { + await manager.identify(data.shardId) - break; + break } // Gateway sends ALLOW_IDENTIFY when worker requests to identify - case "ALLOW_IDENTIFY": { - identifyPromises.get(data.shardId)?.(); - identifyPromises.delete(data.shardId); + case 'ALLOW_IDENTIFY': { + identifyPromises.get(data.shardId)?.() + identifyPromises.delete(data.shardId) - break; + break } // Gateway sends SHARD_PAYLOAD for every events it receives from Discord - case "SHARD_PAYLOAD": { - manager.shards.get(data.shardId)?.send(data.data); + case 'SHARD_PAYLOAD': { + manager.shards.get(data.shardId)?.send(data.data) - break; + break } // Send shard info if gateway sends GET_SHARD_INFO - case "GET_SHARD_INFO": { - const infos = manager.shards.map(buildShardInfo); + case 'GET_SHARD_INFO': { + const infos = manager.shards.map(buildShardInfo) - parentPort?.postMessage({ type: "NONCE_REPLY", nonce: data.nonce, data: infos }); + parentPort?.postMessage({ type: 'NONCE_REPLY', nonce: data.nonce, data: infos }) } } -}); +}) const queue: GatewayQueue = { processing: false, events: [], -}; +} async function handleQueue() { - const event = queue.events.shift(); + const event = queue.events.shift() // QUEUE IS EMPTY if (!event) { - console.log("GATEWAY QUEUE ENDING"); - queue.processing = false; - return; + console.log('GATEWAY QUEUE ENDING') + queue.processing = false + return } await fetch(EVENT_HANDLER_URL, { headers: { Authorization: EVENT_HANDLER_SECRET_KEY, - "Content-Type": "application/json", + 'Content-Type': 'application/json', }, - method: "POST", + method: 'POST', body: JSON.stringify({ shardId: event.shardId, message: event.message, }), }) .then((res) => { - res.text(); - handleQueue(); + res.text() + handleQueue() }) .catch(() => { // EVENT HANDLER STILL NOT ACCEPTING REQUEST. SO ADD BACK TO QUEUE - queue.events.unshift(event); - setTimeout(handleQueue, 1000); - }); + queue.events.unshift(event) + setTimeout(handleQueue, 1000) + }) } async function handleInteractionQueueing(message: DiscordGatewayPayload, shardId: number) { - if (message.t !== "INTERACTION_CREATE") return; + if (message.t !== 'INTERACTION_CREATE') return - const interaction = message.d as DiscordInteraction; + const interaction = message.d as DiscordInteraction // IF THIS INTERACTION IS NOT DEFERABLE if ([InteractionTypes.ModalSubmit, InteractionTypes.ApplicationCommandAutocomplete].includes(interaction.type)) { - return await rest.runMethod(rest, "POST", routes.INTERACTION_ID_TOKEN(BigInt(interaction.id), interaction.token), { + return await rest.runMethod(rest, 'POST', routes.INTERACTION_ID_TOKEN(BigInt(interaction.id), interaction.token), { type: InteractionResponseTypes.ChannelMessageWithSource, data: { - content: - `The bot is having a temporary issue, please try again or contact us at https://discord.gg/${BOT_SERVER_INVITE_CODE}`, + content: `The bot is having a temporary issue, please try again or contact us at https://discord.gg/${BOT_SERVER_INVITE_CODE}`, }, - }); + }) } - await rest.runMethod(rest, "POST", routes.INTERACTION_ID_TOKEN(BigInt(interaction.id), interaction.token), { + await rest.runMethod(rest, 'POST', routes.INTERACTION_ID_TOKEN(BigInt(interaction.id), interaction.token), { // MESSAGE COMPONENTS NEED SPECIAL DEFER - type: InteractionTypes.MessageComponent === interaction.type - ? InteractionResponseTypes.DeferredUpdateMessage - : InteractionResponseTypes.DeferredChannelMessageWithSource, - }); + type: + InteractionTypes.MessageComponent === interaction.type + ? InteractionResponseTypes.DeferredUpdateMessage + : InteractionResponseTypes.DeferredChannelMessageWithSource, + }) // ADD EVENT TO QUEUE - queue.events.push({ shardId, message }); + queue.events.push({ shardId, message }) } -export type WorkerMessage = WorkerIdentifyShard | WorkerAllowIdentify | WorkerShardPayload | WorkerGetShardInfo; +export type WorkerMessage = WorkerIdentifyShard | WorkerAllowIdentify | WorkerShardPayload | WorkerGetShardInfo export type WorkerIdentifyShard = { - type: "IDENTIFY_SHARD"; - shardId: number; -}; + type: 'IDENTIFY_SHARD' + shardId: number +} export type WorkerAllowIdentify = { - type: "ALLOW_IDENTIFY"; - shardId: number; -}; + type: 'ALLOW_IDENTIFY' + shardId: number +} export type WorkerShardPayload = { - type: "SHARD_PAYLOAD"; - shardId: number; - data: ShardSocketRequest; -}; + type: 'SHARD_PAYLOAD' + shardId: number + data: ShardSocketRequest +} export type WorkerGetShardInfo = { - type: "GET_SHARD_INFO"; - nonce: string; -}; + type: 'GET_SHARD_INFO' + nonce: string +} export type WorkerCreateData = { - intents: number; - token: string; - handlerUrls: string[]; - handlerAuthorization: string; - path: string; - totalShards: number; - workerId: number; -}; + intents: number + token: string + handlerUrls: string[] + handlerAuthorization: string + path: string + totalShards: number + workerId: number +} export type WorkerShardInfo = { - workerId: number; - shardId: number; - rtt: number; - state: ShardState; -}; + workerId: number + shardId: number + rtt: number + state: ShardState +} export interface QueuedEvent { - message: DiscordGatewayPayload; - shardId: number; + message: DiscordGatewayPayload + shardId: number } export interface GatewayQueue { - processing: boolean; - events: QueuedEvent[]; + processing: boolean + events: QueuedEvent[] } ``` diff --git a/site/tutorial/big-bot-guide/rest.md b/site/tutorial/big-bot-guide/rest.md index f33b3e137..2195203ed 100644 --- a/site/tutorial/big-bot-guide/rest.md +++ b/site/tutorial/big-bot-guide/rest.md @@ -43,14 +43,14 @@ Before going further, you should have already made the following pieces: Now let's open up that rest file and start coding. ```ts -import { DISCORD_TOKEN, REST_AUTHORIZATION, REST_PORT } from "../../configs.ts"; -import { BASE_URL, createRestManager } from "../../deps.ts"; +import { DISCORD_TOKEN, REST_AUTHORIZATION, REST_PORT } from '../../configs.ts' +import { BASE_URL, createRestManager } from '../../deps.ts' const rest = createRestManager({ token: DISCORD_TOKEN, secretKey: REST_AUTHORIZATION, customUrl: `http://localhost:${REST_PORT}`, -}); +}) ``` - `createRestManager` is imported from your deps file which should have exported everything from discordeno. @@ -70,36 +70,31 @@ guides on this out there. I will only cover the rough functionality. ```ts // START LISTENING TO THE URL(localhost) -const server = Deno.listen({ port: REST_PORT }); -console.info( - `HTTP webserver running. Access it at: http://localhost:${REST_PORT}/`, -); +const server = Deno.listen({ port: REST_PORT }) +console.info(`HTTP webserver running. Access it at: http://localhost:${REST_PORT}/`) // Connections to the server will be yielded up as an async iterable. for await (const conn of server) { // In order to not be blocking, we need to handle each connection individually // in its own async function. - handleRequest(conn); + handleRequest(conn) } async function handleRequest(conn: Deno.Conn) { // This "upgrades" a network connection into an HTTP connection. - const httpConn = Deno.serveHttp(conn); + const httpConn = Deno.serveHttp(conn) // Each request sent over the HTTP connection will be yielded as an async // iterator from the HTTP connection. for await (const requestEvent of httpConn) { - if ( - !REST_AUTHORIZATION || - REST_AUTHORIZATION !== requestEvent.request.headers.get("AUTHORIZATION") - ) { + if (!REST_AUTHORIZATION || REST_AUTHORIZATION !== requestEvent.request.headers.get('AUTHORIZATION')) { return requestEvent.respondWith( - new Response(JSON.stringify({ error: "Invalid authorization key." }), { + new Response(JSON.stringify({ error: 'Invalid authorization key.' }), { status: 401, }), - ); + ) } - const json = (await requestEvent.request.json()) as any; + const json = (await requestEvent.request.json()) as any // IMPLEMENT ANY ERROR HANDLING HERE IF YOU WOULD LIKE BY WRAPPING THIS IN A CATCH @@ -109,13 +104,9 @@ async function handleRequest(conn: Deno.Conn) { // USE THE SAME METHOD THAT CAME IN. IF DELETE CAME IN WE SEND DELETE OUT requestEvent.request.method as any, // OVERWRITE THE CUSTOM URL WITH DISCORDS BASE URL - `${BASE_URL}/v${rest.version}${ - requestEvent.request.url.substring( - rest.customUrl.length, - ) - }`, + `${BASE_URL}/v${rest.version}${requestEvent.request.url.substring(rest.customUrl.length)}`, json, - ); + ) // RETURN DISCORDS RESPONSE BACK TO THE PROCESS MAKING THE REQUEST if (result) { @@ -123,13 +114,13 @@ async function handleRequest(conn: Deno.Conn) { new Response(JSON.stringify(result), { status: 200, }), - ); + ) } else { requestEvent.respondWith( new Response(undefined, { status: 204, }), - ); + ) } } } diff --git a/site/tutorial/nodejs/CommandHandler/command-manager.md b/site/tutorial/nodejs/CommandHandler/command-manager.md index 135a13edc..354be6a83 100644 --- a/site/tutorial/nodejs/CommandHandler/command-manager.md +++ b/site/tutorial/nodejs/CommandHandler/command-manager.md @@ -7,24 +7,24 @@ sidebar_position: 2 Currently, you probably have something like this in your code: ```js -const Discord = require("discordeno.js"); +const Discord = require('discordeno.js') // Ideally you should move to an `.env` file -const config = require("./config.json"); +const config = require('./config.json') const bot = Discord.createBot({ events: { messageCreate(client, message) { - if (message.content === "!ping") { - client.helpers.sendMessage(message.channelId, { content: "pong" }); + if (message.content === '!ping') { + client.helpers.sendMessage(message.channelId, { content: 'pong' }) } }, }, intents: Discord.Intents.Guilds | Discord.Intents.GuildMessages, token: config.token, -}); -const client = Discord.enableCachePlugin(bot, {}); +}) +const client = Discord.enableCachePlugin(bot, {}) -Discord.startBot(client); +Discord.startBot(client) ``` Of course, if you add more and more commands and as your code base grows, you can lose track very quickly. @@ -50,12 +50,12 @@ To avoid this, it is recommended to store the commands in separate folders divid the [nodejs template](https://github.com/discordeno/discordeno/tree/main/template)** ```js -const CommandManager = require("./template/Managers/CommandManager.js"); -const manager = new CommandManager({}); -manager.load({ plugin: true }); // Load the commands -client.commands = manager; +const CommandManager = require('./template/Managers/CommandManager.js') +const manager = new CommandManager({}) +manager.load({ plugin: true }) // Load the commands +client.commands = manager -client.commands.cache.get("ping"); // Get the `ping` command +client.commands.cache.get('ping') // Get the `ping` command ``` The Manager will automatically iterate through all files in the folder and then load them into the cache property, which @@ -77,16 +77,16 @@ Currently checks for permissions, cooldowns, and rate limits are not covered, bu ```js module.exports = async (client, message) => { - client.commands.isCommand(message); -}; + client.commands.isCommand(message) +} ``` ### Interaction Create Event: ```js module.exports = async (client, interaction) => { - client.commands.isInteraction(interaction); -}; + client.commands.isInteraction(interaction) +} ``` You can also customize the `isCommand` function to your use case. diff --git a/site/tutorial/nodejs/EventHandler/event-manager.md b/site/tutorial/nodejs/EventHandler/event-manager.md index bb95281ee..4b02135d7 100644 --- a/site/tutorial/nodejs/EventHandler/event-manager.md +++ b/site/tutorial/nodejs/EventHandler/event-manager.md @@ -7,28 +7,28 @@ sidebar_position: 2 In order to process certain events, you must provide the Discordeno client with functions for these events. ```js -const Discord = require("discordeno"); -const config = require("./config.json"); +const Discord = require('discordeno') +const config = require('./config.json') const client = Discord.createBot({ events: { ready(client, payload) { - console.log(`Successfully connected Shard ${payload.shardId} to the gateway`); + console.log(`Successfully connected Shard ${payload.shardId} to the gateway`) }, async messageCreate(client, message) { - if (message.content === "!ping") { - await client.helpers.sendMessage(message.channelId, { content: "pong" }); + if (message.content === '!ping') { + await client.helpers.sendMessage(message.channelId, { content: 'pong' }) } - console.log(`Received message: ${message.content || message.embeds}`); + console.log(`Received message: ${message.content || message.embeds}`) }, }, - intents: ["Guilds", "GuildMessages"], + intents: ['Guilds', 'GuildMessages'], token: config.token, -}); +}) -Discord.startBot(client); +Discord.startBot(client) ``` As you listen to more and more events, the functions code grows along with them, so you can quickly lose track. @@ -52,42 +52,42 @@ Ready Event: module.exports = (client, payload) => { if (payload.shardId + 1 === client.gateway.maxShards) { // All Shards are ready - console.log(`Successfully connected to the gateway as ${payload.user.username}#${payload.user.discriminator}`); + console.log(`Successfully connected to the gateway as ${payload.user.username}#${payload.user.discriminator}`) } -}; +} ``` ## Load your Events ```js -const fs = require("fs"); -const path = require("path"); +const fs = require('fs') +const path = require('path') -const resolveFolder = (folderName) => path.resolve(__dirname, ".", folderName); +const resolveFolder = (folderName) => path.resolve(__dirname, '.', folderName) class EventManager { constructor(client) { - this.cache = new Map(); - this._events = {}; + this.cache = new Map() + this._events = {} } load(options = {}) { - const eventsFolder = resolveFolder("../events"); + const eventsFolder = resolveFolder('../events') fs.readdirSync(eventsFolder).map(async (file) => { - if (!file.endsWith(".js")) return; + if (!file.endsWith('.js')) return - const fileName = path.join(eventsFolder, file); - const event = require(fileName); - const eventName = file.split(".")[0]; + const fileName = path.join(eventsFolder, file) + const event = require(fileName) + const eventName = file.split('.')[0] - this._events[`${eventName}`] = event; - }); + this._events[`${eventName}`] = event + }) - return this._events; + return this._events } } -module.exports = EventManager; +module.exports = EventManager ``` The code above, which can also be found in the @@ -98,19 +98,19 @@ In order to let the client know which events should be processed, you need to pa `createBot.events` object. ```js -const Discord = require("discordeno"); -const config = require("./config.json"); +const Discord = require('discordeno') +const config = require('./config.json') -const EventManager = require("./Managers/EventManager.js"); -const events = new EventManager({}); +const EventManager = require('./Managers/EventManager.js') +const events = new EventManager({}) const client = Discord.createBot({ events: events.load({}), - intents: ["Guilds", "GuildMessages"], + intents: ['Guilds', 'GuildMessages'], token: config.token, -}); +}) -Discord.startBot(client); +Discord.startBot(client) ``` Moreover, you can customize the `EventManager` and add more functionality to it and make it exactly fit your needs or diff --git a/site/tutorial/nodejs/EventHandler/handle-event.md b/site/tutorial/nodejs/EventHandler/handle-event.md index 2429f7f1d..12e3eee9a 100644 --- a/site/tutorial/nodejs/EventHandler/handle-event.md +++ b/site/tutorial/nodejs/EventHandler/handle-event.md @@ -24,14 +24,14 @@ Sometimes it's important to listen to events, in order to get informed of change This file should be called `messageCreate.js`. ```js -const Message = require("./structures/Message"); +const Message = require('./structures/Message') module.exports = async (client, payload) => { - const message = client.messages.forge(payload); + const message = client.messages.forge(payload) - if (message.author.bot) return; - if (message.content === "!ping") return await message.reply("pong"); -}; + if (message.author.bot) return + if (message.content === '!ping') return await message.reply('pong') +} ``` ### Interaction Event @@ -39,13 +39,13 @@ module.exports = async (client, payload) => { This file should be called `interactionCreate.js`. ```js -const Interaction = require("./structures/Interaction"); +const Interaction = require('./structures/Interaction') module.exports = async (client, payload) => { - const interaction = client.interactions.forge(payload); + const interaction = client.interactions.forge(payload) - if (interaction.data.name === "ping") return await interaction.reply({ content: "pong" }); -}; + if (interaction.data.name === 'ping') return await interaction.reply({ content: 'pong' }) +} ``` ### Ready Event @@ -62,14 +62,14 @@ a `shard` becomes ready. In order to fire the "real event" a small code snippet has to be added to the `ready` Event. ```js -const User = require("../Structures/User"); +const User = require('../Structures/User') module.exports = async (client, payload) => { - client.user = client.users.forge(payload.user); + client.user = client.users.forge(payload.user) if (payload.shardId + 1 === client.gateway.maxShards) { // All Shards are ready - console.log(`Successfully connected to the gateway as ${client.user.tag}`); + console.log(`Successfully connected to the gateway as ${client.user.tag}`) } -}; +} ``` diff --git a/site/tutorial/nodejs/Structures/collectors.md b/site/tutorial/nodejs/Structures/collectors.md index f999a8957..aa5233898 100644 --- a/site/tutorial/nodejs/Structures/collectors.md +++ b/site/tutorial/nodejs/Structures/collectors.md @@ -22,27 +22,27 @@ We have a pre-made class for collectors which you can find [here](https://github.com/meister03/discordeno.js/blob/master/Util/Collectors.js). ```js -const Discord = require("discordeno.js"); -const filter = (m) => m.data?.customId === "warn_modal" && m.user.id === interaction.user.id; -const listener = client.eventListener; // When the eventListener property is named different -const collector = new Discord.Collector("interactionCreate", { +const Discord = require('discordeno.js') +const filter = (m) => m.data?.customId === 'warn_modal' && m.user.id === interaction.user.id +const listener = client.eventListener // When the eventListener property is named different +const collector = new Discord.Collector('interactionCreate', { client: client, timeout: 60000, filter, max: 20, listener, -}); -collector.on("collect", (m) => { - const interaction = client.interactions.forge(m); +}) +collector.on('collect', (m) => { + const interaction = client.interactions.forge(m) // Stop Collector // collector.stop(); -}); +}) // Fires on a timeout, when the collector has reached the max amount of interactions or when it has been closed -collector.on("end", (collected) => { +collector.on('end', (collected) => { // Map of Collected Interactions - console.log(collected); -}); + console.log(collected) +}) ``` As you can see, this opens up many possibilities. You can listen to any event and get the interaction you need. diff --git a/site/tutorial/nodejs/Structures/components.md b/site/tutorial/nodejs/Structures/components.md index 123d52b70..edb9bf516 100644 --- a/site/tutorial/nodejs/Structures/components.md +++ b/site/tutorial/nodejs/Structures/components.md @@ -82,20 +82,20 @@ component you want to use. ```js class ActionRow { constructor(options = {}) { - this.type = 1; + this.type = 1 } setComponents(...components) { - this.components = components; - return this; + this.components = components + return this } } ``` ```js -const button = new Button(); -const button2 = new Button(); -const actionRow = new ActionRow().setComponents(button, button2); +const button = new Button() +const button2 = new Button() +const actionRow = new ActionRow().setComponents(button, button2) ``` This code will obviously not work because it's a missing a lot required of data. The other reason is that we can't send @@ -107,34 +107,21 @@ We have a pre-made class for components which you can find ### Button ```js -const Discord = require("discordeno.js"); -const message = client.messages.forge(rawMessage); +const Discord = require('discordeno.js') +const message = client.messages.forge(rawMessage) -const button = new Discord.Component() - .setType("BUTTON") - .setStyle("LINK") - .setLabel("Click me!") - .setUrl("https://google.com") - .toJSON(); +const button = new Discord.Component().setType('BUTTON').setStyle('LINK').setLabel('Click me!').setUrl('https://google.com').toJSON() // Button with raw types -const button2 = new Discord.Component() - .setType(2) - .setStyle(4) - .setLabel("DO NOT CLICK") - .setCustomId("12345") - .toJSON(); +const button2 = new Discord.Component().setType(2).setStyle(4).setLabel('DO NOT CLICK').setCustomId('12345').toJSON() -const actionRow = new Discord.Component() - .setType("ACTION_ROW") - .setComponents(button, button2) - .toJSON(); +const actionRow = new Discord.Component().setType('ACTION_ROW').setComponents(button, button2).toJSON() // Message to send -const messageOptions = { content: "hello", components: [actionRow] }; +const messageOptions = { content: 'hello', components: [actionRow] } // await client.helpers.sendMessage(channelId, messageOptions); // Do it the raw way -message.channel.send(messageOptions); // Do it with the structure +message.channel.send(messageOptions) // Do it with the structure ``` As you can see, for simplicity you can use strings instead of numbers (types), which are hard to remember. @@ -142,79 +129,76 @@ As you can see, for simplicity you can use strings instead of numbers (types), w ### Select Menu ```js -const Discord = require("discordeno.js"); -const message = client.messages.forge(rawMessage); +const Discord = require('discordeno.js') +const message = client.messages.forge(rawMessage) const selectMenu = new Discord.Component() - .setType("SELECT_MENU") - .setCustomId("12345") + .setType('SELECT_MENU') + .setCustomId('12345') .setOptions([ { - label: "Option 1", - value: "1", + label: 'Option 1', + value: '1', description: `This is option 1`, }, { - label: "Option 2", - value: "2", + label: 'Option 2', + value: '2', description: `This is option 2`, }, { - label: "Default Option", - value: "3", + label: 'Default Option', + value: '3', description: `Default option...`, default: true, }, ]) - .setPlaceholder("Select an option") - .toJSON(); + .setPlaceholder('Select an option') + .toJSON() -const actionRow = new Discord.Component() - .setType("ACTION_ROW") - .setComponents(selectMenu) - .toJSON(); +const actionRow = new Discord.Component().setType('ACTION_ROW').setComponents(selectMenu).toJSON() -const messageOptions = { content: "hello", components: [actionRow] }; +const messageOptions = { content: 'hello', components: [actionRow] } // await client.helpers.sendMessage(channelId, messageOptions); // Do it the raw way -message.channel.send(messageOptions); // Do it with the structure +message.channel.send(messageOptions) // Do it with the structure ``` ### Text Input ```js -const Discord = require("discordeno.js"); -const interaction = client.messages.forge(rawInteraction); +const Discord = require('discordeno.js') +const interaction = client.messages.forge(rawInteraction) const textInput = new Component() - .setType("TEXT_INPUT") - .setStyle("SHORT") - .setCustomId("t1") - .setLabel("User ID") - .setPlaceholder("User ID") + .setType('TEXT_INPUT') + .setStyle('SHORT') + .setCustomId('t1') + .setLabel('User ID') + .setPlaceholder('User ID') .setRequired(true) .setMaxLength(20) .setMinLength(1) - .toJSON(); + .toJSON() const textInput2 = new Component() - .setType("TEXT_INPUT") - .setStyle("PARAGRAPH") - .setCustomId("t2") - .setLabel("Reason") - .setPlaceholder("Reason for Ban") + .setType('TEXT_INPUT') + .setStyle('PARAGRAPH') + .setCustomId('t2') + .setLabel('Reason') + .setPlaceholder('Reason for Ban') .setRequired(false) .setMaxLength(300) - .toJSON(); + .toJSON() -const actionRow = new Component().setType("ACTION_ROW").setComponents(textInput).toJSON(); -const actionRow2 = new Component().setType("ACTION_ROW").setComponents(textInput2).toJSON(); +const actionRow = new Component().setType('ACTION_ROW').setComponents(textInput).toJSON() +const actionRow2 = new Component().setType('ACTION_ROW').setComponents(textInput2).toJSON() interaction.popupModal({ - customId: "ban_modal", - title: "Ban User", + customId: 'ban_modal', + title: 'Ban User', components: [actionRow, actionRow2], -}); +}) ``` ### Receive Interactions diff --git a/site/tutorial/nodejs/Structures/create-structure.md b/site/tutorial/nodejs/Structures/create-structure.md index 3be34dd12..7bbaa6c4d 100644 --- a/site/tutorial/nodejs/Structures/create-structure.md +++ b/site/tutorial/nodejs/Structures/create-structure.md @@ -11,14 +11,14 @@ Imagine you have a channel object to which you want to send a message. ```js const data = { id: 806947972004839444n, - name: "spam-and-bots", -}; + name: 'spam-and-bots', +} ``` The recommended way would be: ```js -await client.helpers.sendMessage(data.id, { content: "hello" }); +await client.helpers.sendMessage(data.id, { content: 'hello' }) ``` However, you probably want to use something shorter, such as the following: @@ -26,13 +26,13 @@ However, you probably want to use something shorter, such as the following: ```js class Channel { constructor(client, data) { - this.client = client; - this.id = data.id; - this.name = data.name; + this.client = client + this.id = data.id + this.name = data.name } async send(options) { - return await this.client.helpers.sendMessage(this.id, options); + return await this.client.helpers.sendMessage(this.id, options) } } ``` @@ -40,8 +40,8 @@ class Channel { Now you can use the `.send()` method on the channel object without using such a long code: ```js -const channel = new Channel(client, data); -await channel.send({ content: "hello" }); +const channel = new Channel(client, data) +await channel.send({ content: 'hello' }) ``` Moreover, you can modify the `.send()` method to better suit your use case e.g not send the message if the channel is @@ -74,22 +74,22 @@ construct the client for following the Guide **Using the Structures:** ```js -const Discord = require("discordeno.js"); -const client = new Discord.Client(clientOptions, cacheOptions); //See the Readme above -Discord.startBot(client); -const guild = client.guilds.forge(guildData); -const channel = guild.channels.forge(channelData); -const role = guild.roles.forge(roleData); -const member = guild.members.forge(memberData); -const user = guild.users.forge(userData); -const message = guild.messages.forge(messageData); -const interaction = guild.interactions.forge(interactionData); -const emoji = guild.emojis.forge(emojiData); +const Discord = require('discordeno.js') +const client = new Discord.Client(clientOptions, cacheOptions) //See the Readme above +Discord.startBot(client) +const guild = client.guilds.forge(guildData) +const channel = guild.channels.forge(channelData) +const role = guild.roles.forge(roleData) +const member = guild.members.forge(memberData) +const user = guild.users.forge(userData) +const message = guild.messages.forge(messageData) +const interaction = guild.interactions.forge(interactionData) +const emoji = guild.emojis.forge(emojiData) -const webhook = new Discord.Webhook(client, webhookData); -const embed = new Discord.Embed(embedData); // embedData is optional -const component = new Discord.Component(componentData); // componentData is optional -const collection = new Discord.Collection(); +const webhook = new Discord.Webhook(client, webhookData) +const embed = new Discord.Embed(embedData) // embedData is optional +const component = new Discord.Component(componentData) // componentData is optional +const collection = new Discord.Collection() ``` Some popular methods have been added to the structures so that you can use them without having to come up with your own. diff --git a/site/tutorial/nodejs/Structures/embeds.md b/site/tutorial/nodejs/Structures/embeds.md index 9c2864e16..2a0f0face 100644 --- a/site/tutorial/nodejs/Structures/embeds.md +++ b/site/tutorial/nodejs/Structures/embeds.md @@ -32,7 +32,7 @@ Now we have created a class which we can use to create embeds. But we can't just So we need an additional method which will convert the data from the class to the correct format. ```js -class Embed(){ +class Embed(){ constructor() {} setTitle(title) { @@ -50,10 +50,10 @@ class Embed(){ Wow, now you can create a embed and send it to Discord. ```js -const Channel = require("./structures/Channel"); // Path to structure +const Channel = require('./structures/Channel') // Path to structure -const channel = new Channel(client, data); -await channel.send({ embeds: [embed] }); +const channel = new Channel(client, data) +await channel.send({ embeds: [embed] }) ``` You probably want more methods which you can use to create embeds. @@ -62,36 +62,36 @@ You probably want more methods which you can use to create embeds. ### Using the Embed Structure: ```js -const Discord = require("discordeno.js"); +const Discord = require('discordeno.js') -const channel = client.channels.forge(channelData); +const channel = client.channels.forge(channelData) const showCaseEmbed = new Discord.Embed() - .setColor(0x00AE86) - .setTitle("A Random Title") - .setURL("https://github.com/discordeno") + .setColor(0x00ae86) + .setTitle('A Random Title') + .setURL('https://github.com/discordeno') .setAuthor({ - name: "Author name", - iconUrl: "https://raw.githubusercontent.com/discordeno/discordeno/main/site/static/img/logo.png", - url: "https://github.com/discordeno", + name: 'Author name', + iconUrl: 'https://raw.githubusercontent.com/discordeno/discordeno/main/site/static/img/logo.png', + url: 'https://github.com/discordeno', }) - .setDescription("A Random Description") - .setThumbnail("https://raw.githubusercontent.com/discordeno/discordeno/main/site/static/img/logo.png") + .setDescription('A Random Description') + .setThumbnail('https://raw.githubusercontent.com/discordeno/discordeno/main/site/static/img/logo.png') .addFields( - { name: "Field 1 Name", value: "Normal Field Value" }, - { name: "\u200B", value: "\u200B" }, - { name: "Field 2 Name", value: "Inline Field Value", inline: true }, - { name: "Field 3 Name", value: "Inline Field Value", inline: true }, + { name: 'Field 1 Name', value: 'Normal Field Value' }, + { name: '\u200B', value: '\u200B' }, + { name: 'Field 2 Name', value: 'Inline Field Value', inline: true }, + { name: 'Field 3 Name', value: 'Inline Field Value', inline: true }, ) - .addField({ name: "Field 4", value: "Field Value" }) - .setImage("https://raw.githubusercontent.com/discordeno/discordeno/main/site/static/img/logo.png") + .addField({ name: 'Field 4', value: 'Field Value' }) + .setImage('https://raw.githubusercontent.com/discordeno/discordeno/main/site/static/img/logo.png') .setTimestamp() .setFooter({ - text: "A Footer Text", - iconUrl: "https://raw.githubusercontent.com/discordeno/discordeno/main/site/static/img/logo.png", + text: 'A Footer Text', + iconUrl: 'https://raw.githubusercontent.com/discordeno/discordeno/main/site/static/img/logo.png', }) - .toJSON(); + .toJSON() -await channel.send({ embeds: [showCaseEmbed] }); +await channel.send({ embeds: [showCaseEmbed] }) ``` ### Embed Limits: diff --git a/site/tutorial/nodejs/Structures/getting-started.md b/site/tutorial/nodejs/Structures/getting-started.md index 1898e757b..b06806d6d 100644 --- a/site/tutorial/nodejs/Structures/getting-started.md +++ b/site/tutorial/nodejs/Structures/getting-started.md @@ -9,7 +9,7 @@ As previously mentioned, Discordeno was built with as few classes as possible, t For example, you cannot execute functions on objects. ```diff -- message.channel.send({content: "hello"}) +- message.channel.send({content: "hello"}) + client.helpers.sendMessage(message.channel.id, {content: "hello"}) ``` diff --git a/site/tutorial/nodejs/design.md b/site/tutorial/nodejs/design.md index 580e70c7b..86dacc19b 100644 --- a/site/tutorial/nodejs/design.md +++ b/site/tutorial/nodejs/design.md @@ -87,9 +87,9 @@ Example: ```js class Command { - static name = "ping"; - static aliases = ["pong"]; - static botPermission = ["SEND_EMBED_LINKS"]; + static name = 'ping' + static aliases = ['pong'] + static botPermission = ['SEND_EMBED_LINKS'] run(message, args) { // do something @@ -106,17 +106,17 @@ by each command. Extending the class makes this extra step obsolete. ```js class BaseCommand { constructor(client) { - this.client = client; - this.basePermission = ["SEND_EMBED_LINKS"]; + this.client = client + this.basePermission = ['SEND_EMBED_LINKS'] } } class Command extends BaseCommand { - static name = "ping"; - static aliases = ["pong"]; + static name = 'ping' + static aliases = ['pong'] constructor(data) { - super(data); + super(data) } run(message, args) { diff --git a/site/tutorial/nodejs/initial-setup.md b/site/tutorial/nodejs/initial-setup.md index 04ab56456..3b3cc0c10 100644 --- a/site/tutorial/nodejs/initial-setup.md +++ b/site/tutorial/nodejs/initial-setup.md @@ -23,20 +23,20 @@ Create a file named `config.json` in your project folder and insert the followin Open the `index.js` file which you have created earlier and then insert the following content: ```js -const Discord = require("discordeno"); -const config = require("./config.json"); +const Discord = require('discordeno') +const config = require('./config.json') const client = Discord.createBot({ events: { ready(client, payload) { - console.log(`Successfully connected Shard ${payload.shardId} to the gateway`); + console.log(`Successfully connected Shard ${payload.shardId} to the gateway`) }, }, - intents: ["Guilds", "GuildMessages"], + intents: ['Guilds', 'GuildMessages'], token: config.token, -}); +}) -Discord.startBot(client); +Discord.startBot(client) ``` Now you can start your bot by running the following command in your terminal: diff --git a/site/tutorial/nodejs/slash-command.md b/site/tutorial/nodejs/slash-command.md index b5effda76..d507d15cf 100644 --- a/site/tutorial/nodejs/slash-command.md +++ b/site/tutorial/nodejs/slash-command.md @@ -18,14 +18,14 @@ commands show up directly. For this reason, we will now show how to create guild commands, in order to test them immediately. ```js -const guildId = BigInt("YOUR_GUILD_ID"); +const guildId = BigInt('YOUR_GUILD_ID') const command = { - name: "ping", - description: "Retrieves the Bot latency", + name: 'ping', + description: 'Retrieves the Bot latency', options: [], -}; +} -client.helpers.createApplicationCommand(command, guildId); +client.helpers.createApplicationCommand(command, guildId) ``` This is just very simple example, you can also add sub commands, select options and much more. @@ -36,28 +36,28 @@ Discord sends a WebSocket Event when a user runs a slash command. You can listen `interactionCreate` function in the client. ```js -const Discord = require("discordeno"); -const config = require("./config.json"); +const Discord = require('discordeno') +const config = require('./config.json') const client = Discord.createBot({ events: { ready(client, payload) { - console.log(`Successfully connected Shard ${payload.shardId} to the gateway`); + console.log(`Successfully connected Shard ${payload.shardId} to the gateway`) }, async interactionCreate(client, interaction) { - if (interaction.data?.name === "ping") { + if (interaction.data?.name === 'ping') { return await client.helpers.sendInteractionResponse(interaction.id, interaction.token, { type: Discord.InteractionResponseTypes.ChannelMessageWithSource, - data: { content: "🏓 Pong!" }, - }); + data: { content: '🏓 Pong!' }, + }) } }, }, intents: Discord.Intents.Guilds | Discord.Intents.GuildMessages, token: config.token, -}); +}) -Discord.startBot(client); +Discord.startBot(client) ``` The handling may see complicated in the beginning, but as mentioned before, we will introduce structures to make it diff --git a/typedoc.json b/typedoc.json index 49f5d79ba..04efead4e 100644 --- a/typedoc.json +++ b/typedoc.json @@ -1,12 +1,19 @@ { "entryPointStrategy": "packages", "entryPoints": [ + "packages/bot", + "packages/client", + "packages/gateway", + "packages/rest", "packages/types", "packages/utils" ], "logger": "console", "skipErrorChecking": true, - "cleanOutputDir": true, - "excludeNotDocumented": true, - "out": "./website/docs/generated/" + "out": "./website/docs/generated/", + "cleanOutputDir": false, + "plugin": [ + "typedoc-plugin-markdown" + ], + "commentStyle": "all" } diff --git a/website/babel.config.js b/website/babel.config.js index e00595dae..3a532fc17 100644 --- a/website/babel.config.js +++ b/website/babel.config.js @@ -1,3 +1,6 @@ module.exports = { - presets: [require.resolve('@docusaurus/core/lib/babel/preset')], + presets: [ + require.resolve('@docusaurus/core/lib/babel/preset'), + + ], }; diff --git a/website/docs/generated/Docs.md b/website/docs/generated/Docs.md deleted file mode 100644 index 8b132e32e..000000000 --- a/website/docs/generated/Docs.md +++ /dev/null @@ -1,5 +0,0 @@ -discordeno-monorepo / [Modules](modules.md) - -# Discordeno - -how to make this not reset? diff --git a/website/docs/generated/README.md b/website/docs/generated/README.md new file mode 100644 index 000000000..c265002e0 --- /dev/null +++ b/website/docs/generated/README.md @@ -0,0 +1,111 @@ +discordeno-monorepo / [Modules](modules.md) + +# Discordeno + + + +Discord API library for [Node.JS](https://nodejs.org), [Deno](https://deno.land) & [Bun](https://bun.sh/) + +[![Discord](https://img.shields.io/discord/785384884197392384?color=7289da&logo=discord&logoColor=dark)](https://discord.com/invite/5vBgXk3UcZ) +[![codecov](https://codecov.io/gh/discordeno/discordeno/branch/main/graph/badge.svg?token=SQI9OYJ7AK)](https://codecov.io/gh/discordeno/discordeno) + +## Tips + +- If you are already convinced about using Discordeno, go to [Getting Started](https://discordeno.mod.land) +- To learn if Discordeno is right for you, read everything below. + +## Packages + +| Package | npm | Tests | Coverage | +| ------------------------------------------------------------------------ | ----------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [discordeno](https://www.npmjs.com/package/discordeno) | ![npm (scoped)](https://img.shields.io/npm/v/discordeno) | ![action status](https://github.com/discordeno/discordeno/actions/workflows/discordeno-test.yml/badge.svg?event=push) | [![codecov](https://codecov.io/gh/discordeno/discordeno/branch/main/graph/badge.svg?token=SQI9OYJ7AK&flag=discordeno)](https://codecov.io/gh/discordeno/discordeno) | +| [@discordeno/types](https://www.npmjs.com/package/@discordeno/types) | ![npm (scoped)](https://img.shields.io/npm/v/@discordeno/types) | ![action status](https://github.com/discordeno/discordeno/actions/workflows/types-test.yml/badge.svg?event=push) | [![codecov](https://codecov.io/gh/discordeno/discordeno/branch/main/graph/badge.svg?token=SQI9OYJ7AK&flag=types)](https://codecov.io/gh/discordeno/discordeno) | +| [@discordeno/utils](https://www.npmjs.com/package/@discordeno/utils) | ![npm (scoped)](https://img.shields.io/npm/v/@discordeno/utils) | ![action status](https://github.com/discordeno/discordeno/actions/workflows/utils-test.yml/badge.svg?event=push) | [![codecov](https://codecov.io/gh/discordeno/discordeno/branch/main/graph/badge.svg?token=SQI9OYJ7AK&flag=utils)](https://codecov.io/gh/discordeno/discordeno) | +| [@discordeno/rest](https://www.npmjs.com/package/@discordeno/rest) | ![npm (scoped)](https://img.shields.io/npm/v/@discordeno/rest) | ![action status](https://github.com/discordeno/discordeno/actions/workflows/rest-test.yml/badge.svg?event=push) | [![codecov](https://codecov.io/gh/discordeno/discordeno/branch/main/graph/badge.svg?token=SQI9OYJ7AK&flag=rest)](https://codecov.io/gh/discordeno/discordeno) | +| [@discordeno/gateway](https://www.npmjs.com/package/@discordeno/gateway) | ![npm (scoped)](https://img.shields.io/npm/v/@discordeno/gateway) | ![action status](https://github.com/discordeno/discordeno/actions/workflows/gateway-test.yml/badge.svg?event=push) | [![codecov](https://codecov.io/gh/discordeno/discordeno/branch/main/graph/badge.svg?token=SQI9OYJ7AK&flag=gateway)](https://codecov.io/gh/discordeno/discordeno) | +| [@discordeno/bot](https://www.npmjs.com/package/@discordeno/bot) | ![npm (scoped)](https://img.shields.io/npm/v/@discordeno/bot) | ![action status](https://github.com/discordeno/discordeno/actions/workflows/bot-test.yml/badge.svg?event=push) | [![codecov](https://codecov.io/gh/discordeno/discordeno/branch/main/graph/badge.svg?token=SQI9OYJ7AK&flag=bot)](https://codecov.io/gh/discordeno/discordeno) | + +## Features + +Discordeno is actively maintained to guarantee **excellent performance, latest features, and ease of use.** + +- **Simple, Efficient, and Lightweight**: Discordeno is lightweight, simple to use, and adaptable. + - By default: No caching. +- **Functional & Class API**: Discordeno is flexible enough to provide both methods. + - The functional API eliminates the challenges of extending built-in classes and inheritance while ensuring overall simple but performant code. + - The class based API, client package, provides a similar api as the [Eris](https://github.com/abalabahaha/eris) library to provide the best class based experience. +- **Cross Runtime**: Supports the Node.js, Deno, and Bun runtimes. +- **Standalone components**: Discordeno offers the option to have practically any component of a bot as a separate + piece, including standalone REST, gateways, custom caches, and more. +- **Flexibility/Scalability:** Remove any properties, if your bot doesn't need them. For instance, remove `Channel.topic` if your bot doesn't require it. You may save GBs of RAM in this way. A few lines of code are all that are needed to accomplish this for any property on any object. + +### REST + +- Freedom from 1 hour downtimes due to invalid requests + - Prevent your bot from being down for an hour, by lowering the maximum downtime to 10 minutes. +- Freedom from global rate limit errors + - As a bot grows, you need to handle global rate limits better. Shards don't communicate fast enough to truly + handle it properly. With one point of contact to discords API, you will never have issues again. + - Numerous instances of your bot on different hosts, all of which can connect to the same REST server. +- REST does not rest! + - Separate rest guarantees that your queued requests will continue to be processed even if your bot breaks for + whatever reason. + - Seamless updates! When updating/restarting a bot, you'll lose a lot of messages or replies that are queued/processing. +- Single point of contact to Discord API + - Send requests from any location, even a bot dashboard directly. + - Don't send requests from dashboard to bot process to send a request to discord. Your bot process should + be freed up to handle bot events! +- Scalability! Scalability! Scalability! + +### Gateway + +- **Zero Downtime Updates:** + - Others: With non-proxy bots, it takes about 5s per shard bucket to start up. With 100,000 servers, this would be minimum of 8+ minutes of downtime for bot updates. + - Discordeno Proxy Gateway: Resume the bot code almost instantly without worrying about any delays or wasting your identify limits. +- **Zero Downtime Resharding:** + - Discord stops allowing your bot to be added to new servers when you max out your existing max shards. Consider a bot started with 150 shards + operating on 150,000 servers. Your shards support a maximum of 150 \* 2500 = 375,000 servers. Your + bot will be unable to join new servers once it reaches this point until it re-shards. + - DD proxy provides 2 types of re-sharding. Automated and manual. You can also have both. + - Automated: This system will automatically begin a Zero-downtime resharding process behind the scenes when you + reach 80% of your maximum servers allowed by your shards. For example, since 375,000 was the max, at 300,000 we + would begin re-sharding behind the scenes with ZERO DOWNTIME. + - 80% of maximum servers reached (The % of 80% is customizable.) + - Identify limits have room to allow re-sharding. (Also customizable) + - Manual: You can also trigger this manually should you choose. + - When discord releases a new API version, updates your gateways to new version with no downtime. +- **Horizontal Scaling:** + - When your bot grows a lot, you have + two options: you can either keep investing money to upgrade your server or you may expand horizontally by purchasing + several more affordable servers. The proxy enables WS handling on multiple servers. +- **No Loss Restarts:** + - Without the proxy mechanism, you would typically lose a lot of events while restarting. Users could issue + instructions or send messages that are not automoderated. As your bot grows, this amount grows sharply. + Users who don't receive the automatic roles or any other activities your bot should do. + - While your bot is unavailable, events can be added to a queue, and once the bot is back online, the queue will start processing all of the events. +- **Flexibility:** + - You have complete control over everything inside the gateway thanks to the controller aspect. Need to customize, the way the manager talks to the workers? Simply, plug in and override the method. +- **Clustering With Workers:** + - Utilize all of your CPU cores to their greatest potential by distributing the workload across workers. To enhance + efficiency, manage how shards per worker. + +### Custom Cache + +Have your cache setup in any way you like. Redis, PGSQL or any cache layer you would like. + +## Getting Started + +Interested? [Check the website](https://discordeno.mod.land) for more details on getting started. + +### Tools + +This library is not intended for beginners, however if you still want to utilise it, check out these excellent official +and unofficial templates: + +## Links + +- [Website](https://discordeno.mod.land) +- [Documentation](https://doc.deno.land/https/deno.land/x/discordeno/mod.ts) +- [Discord](https://discord.com/invite/5vBgXk3UcZ) + +Discordeno follows [semantic versioning](https://semver.org/) diff --git a/website/docs/generated/_category_.json b/website/docs/generated/_category_.json index 8aabd333f..4b8730a1d 100644 --- a/website/docs/generated/_category_.json +++ b/website/docs/generated/_category_.json @@ -1,9 +1,8 @@ { - "label": "Docs", - "position": 2, - "link": { - "type": "generated-index", - "description": "If you need any help, please contact us on [Discord](https://discord.gg/ddeno)." - } + "label": "Docs (API References)", + "position": 2, + "link": { + "type": "generated-index", + "description": "Automatically generated documentation." } - \ No newline at end of file +} diff --git a/website/docs/generated/enums/_category_.json b/website/docs/generated/enums/_category_.json index a7c3ef65c..9316484f9 100644 --- a/website/docs/generated/enums/_category_.json +++ b/website/docs/generated/enums/_category_.json @@ -1,9 +1,8 @@ { - "label": "Enums", - "position": 1, - "link": { - "type": "generated-index", - "description": "All the enums available for use from the @discordeno/types package." - } + "label": "Enums", + "position": 3, + "link": { + "type": "generated-index", + "description": "Automatically generated documentation for enums." } - \ No newline at end of file +} diff --git a/website/docs/generated/interfaces/_category_.json b/website/docs/generated/interfaces/_category_.json index 424b13747..e0159a1d1 100644 --- a/website/docs/generated/interfaces/_category_.json +++ b/website/docs/generated/interfaces/_category_.json @@ -1,9 +1,8 @@ { - "label": "Interfaces", - "position": 2, - "link": { - "type": "generated-index", - "description": "All the interfaces available for use from the @discordeno/types package." - } + "label": "Interfaces", + "position": 4, + "link": { + "type": "generated-index", + "description": "Automatically generated documentation for interfaces" } - \ No newline at end of file +} diff --git a/website/docs/generated/modules.md b/website/docs/generated/modules.md new file mode 100644 index 000000000..28c163e67 --- /dev/null +++ b/website/docs/generated/modules.md @@ -0,0 +1,14 @@ +[discordeno-monorepo](README.md) / Modules + +# discordeno-monorepo + +## Table of contents + +### Modules + +- [@discordeno/bot](modules/discordeno_bot.md) +- [@discordeno/client](modules/discordeno_client.md) +- [@discordeno/gateway](modules/discordeno_gateway.md) +- [@discordeno/rest](modules/discordeno_rest.md) +- [@discordeno/types](modules/discordeno_types.md) +- [@discordeno/utils](modules/discordeno_utils.md) diff --git a/website/docs/generated/modules/_category_.json b/website/docs/generated/modules/_category_.json index 68a8c1f44..5c9f94daf 100644 --- a/website/docs/generated/modules/_category_.json +++ b/website/docs/generated/modules/_category_.json @@ -1,9 +1,8 @@ { - "label": "Modules", - "position": 3, - "link": { - "type": "generated-index", - "description": "All the modules(packages) available for use from @discordeno." - } + "label": "Modules", + "position": 5, + "link": { + "type": "generated-index", + "description": "Automatically generated documentation for modules." } - \ No newline at end of file +} diff --git a/website/docs/generated/modules_bot.md b/website/docs/generated/modules_bot.md new file mode 100644 index 000000000..464ce0813 --- /dev/null +++ b/website/docs/generated/modules_bot.md @@ -0,0 +1,2719 @@ +[discordeno-monorepo](../README.md) / [Modules](../modules.md) / @discordeno/bot + +# Module: @discordeno/bot + +## Table of contents + +### Enumerations + +- [ActivityTypes](../enums/ActivityTypes.md) +- [AllowedMentionsTypes](../enums/AllowedMentionsTypes.md) +- [ApplicationCommandOptionTypes](../enums/ApplicationCommandOptionTypes.md) +- [ApplicationCommandPermissionTypes](../enums/ApplicationCommandPermissionTypes.md) +- [ApplicationCommandTypes](../enums/ApplicationCommandTypes.md) +- [ApplicationFlags](../enums/ApplicationFlags.md) +- [AuditLogEvents](../enums/AuditLogEvents.md) +- [AutoModerationActionType](../enums/AutoModerationActionType.md) +- [AutoModerationEventTypes](../enums/AutoModerationEventTypes.md) +- [AutoModerationTriggerTypes](../enums/AutoModerationTriggerTypes.md) +- [BitwisePermissionFlags](../enums/BitwisePermissionFlags.md) +- [ButtonStyles](../enums/ButtonStyles.md) +- [ChannelFlags](../enums/ChannelFlags.md) +- [ChannelTypes](../enums/ChannelTypes.md) +- [DefaultMessageNotificationLevels](../enums/DefaultMessageNotificationLevels.md) +- [DiscordAutoModerationRuleTriggerMetadataPresets](../enums/DiscordAutoModerationRuleTriggerMetadataPresets.md) +- [ExplicitContentFilterLevels](../enums/ExplicitContentFilterLevels.md) +- [GatewayCloseEventCodes](../enums/GatewayCloseEventCodes.md) +- [GatewayIntents](../enums/GatewayIntents.md) +- [GatewayOpcodes](../enums/GatewayOpcodes.md) +- [GuildFeatures](../enums/GuildFeatures.md) +- [GuildNsfwLevel](../enums/GuildNsfwLevel.md) +- [IntegrationExpireBehaviors](../enums/IntegrationExpireBehaviors.md) +- [InteractionResponseTypes](../enums/InteractionResponseTypes.md) +- [InteractionTypes](../enums/InteractionTypes.md) +- [Locales](../enums/Locales.md) +- [LogDepth](../enums/LogDepth.md) +- [LogLevels](../enums/LogLevels.md) +- [MessageActivityTypes](../enums/MessageActivityTypes.md) +- [MessageComponentTypes](../enums/MessageComponentTypes.md) +- [MessageTypes](../enums/MessageTypes.md) +- [MfaLevels](../enums/MfaLevels.md) +- [OverwriteTypes](../enums/OverwriteTypes.md) +- [PremiumTiers](../enums/PremiumTiers.md) +- [PremiumTypes](../enums/PremiumTypes.md) +- [PresenceStatus](../enums/PresenceStatus.md) +- [ScheduledEventEntityType](../enums/ScheduledEventEntityType.md) +- [ScheduledEventPrivacyLevel](../enums/ScheduledEventPrivacyLevel.md) +- [ScheduledEventStatus](../enums/ScheduledEventStatus.md) +- [ShardSocketCloseCodes](../enums/ShardSocketCloseCodes.md) +- [ShardState](../enums/ShardState.md) +- [SortOrderTypes](../enums/SortOrderTypes.md) +- [StickerFormatTypes](../enums/StickerFormatTypes.md) +- [StickerTypes](../enums/StickerTypes.md) +- [SystemChannelFlags](../enums/SystemChannelFlags.md) +- [TargetTypes](../enums/TargetTypes.md) +- [TeamMembershipStates](../enums/TeamMembershipStates.md) +- [TextStyles](../enums/TextStyles.md) +- [UserFlags](../enums/UserFlags.md) +- [VerificationLevels](../enums/VerificationLevels.md) +- [VideoQualityModes](../enums/VideoQualityModes.md) +- [WebhookTypes](../enums/WebhookTypes.md) + +### Classes + +- [Collection](../classes/Collection.md) +- [DiscordenoShard](../classes/DiscordenoShard.md) +- [Queue](../classes/Queue.md) + +### Interfaces + +- [ActionRow](../interfaces/ActionRow.md) +- [AllowedMentions](../interfaces/AllowedMentions.md) +- [ApplicationCommandOption](../interfaces/ApplicationCommandOption.md) +- [ApplicationCommandOptionChoice](../interfaces/ApplicationCommandOptionChoice.md) +- [ApplicationCommandPermissions](../interfaces/ApplicationCommandPermissions.md) +- [BeginGuildPrune](../interfaces/BeginGuildPrune.md) +- [Bot](../interfaces/Bot.md) +- [BotActivity](../interfaces/BotActivity.md) +- [BotStatusUpdate](../interfaces/BotStatusUpdate.md) +- [ButtonComponent](../interfaces/ButtonComponent.md) +- [Code](../interfaces/Code.md) +- [CollectionOptions](../interfaces/CollectionOptions.md) +- [CollectionSweeper](../interfaces/CollectionSweeper.md) +- [CreateAutoModerationRuleOptions](../interfaces/CreateAutoModerationRuleOptions.md) +- [CreateBotOptions](../interfaces/CreateBotOptions.md) +- [CreateChannelInvite](../interfaces/CreateChannelInvite.md) +- [CreateContextApplicationCommand](../interfaces/CreateContextApplicationCommand.md) +- [CreateForumPostWithMessage](../interfaces/CreateForumPostWithMessage.md) +- [CreateGatewayManagerOptions](../interfaces/CreateGatewayManagerOptions.md) +- [CreateGuild](../interfaces/CreateGuild.md) +- [CreateGuildBan](../interfaces/CreateGuildBan.md) +- [CreateGuildChannel](../interfaces/CreateGuildChannel.md) +- [CreateGuildEmoji](../interfaces/CreateGuildEmoji.md) +- [CreateGuildFromTemplate](../interfaces/CreateGuildFromTemplate.md) +- [CreateGuildRole](../interfaces/CreateGuildRole.md) +- [CreateGuildStickerOptions](../interfaces/CreateGuildStickerOptions.md) +- [CreateMessageOptions](../interfaces/CreateMessageOptions.md) +- [CreateRequestBodyOptions](../interfaces/CreateRequestBodyOptions.md) +- [CreateRestManagerOptions](../interfaces/CreateRestManagerOptions.md) +- [CreateScheduledEvent](../interfaces/CreateScheduledEvent.md) +- [CreateSlashApplicationCommand](../interfaces/CreateSlashApplicationCommand.md) +- [CreateStageInstance](../interfaces/CreateStageInstance.md) +- [CreateTemplate](../interfaces/CreateTemplate.md) +- [CreateWebhook](../interfaces/CreateWebhook.md) +- [DeleteWebhookMessageOptions](../interfaces/DeleteWebhookMessageOptions.md) +- [DiscordActionRow](../interfaces/DiscordActionRow.md) +- [DiscordActiveThreads](../interfaces/DiscordActiveThreads.md) +- [DiscordActivity](../interfaces/DiscordActivity.md) +- [DiscordActivityAssets](../interfaces/DiscordActivityAssets.md) +- [DiscordActivityButton](../interfaces/DiscordActivityButton.md) +- [DiscordActivityEmoji](../interfaces/DiscordActivityEmoji.md) +- [DiscordActivityParty](../interfaces/DiscordActivityParty.md) +- [DiscordActivitySecrets](../interfaces/DiscordActivitySecrets.md) +- [DiscordActivityTimestamps](../interfaces/DiscordActivityTimestamps.md) +- [DiscordAllowedMentions](../interfaces/DiscordAllowedMentions.md) +- [DiscordApplication](../interfaces/DiscordApplication.md) +- [DiscordApplicationCommand](../interfaces/DiscordApplicationCommand.md) +- [DiscordApplicationCommandOption](../interfaces/DiscordApplicationCommandOption.md) +- [DiscordApplicationCommandOptionChoice](../interfaces/DiscordApplicationCommandOptionChoice.md) +- [DiscordApplicationCommandPermissions](../interfaces/DiscordApplicationCommandPermissions.md) +- [DiscordApplicationWebhook](../interfaces/DiscordApplicationWebhook.md) +- [DiscordAttachment](../interfaces/DiscordAttachment.md) +- [DiscordAuditLog](../interfaces/DiscordAuditLog.md) +- [DiscordAuditLogEntry](../interfaces/DiscordAuditLogEntry.md) +- [DiscordAutoModerationAction](../interfaces/DiscordAutoModerationAction.md) +- [DiscordAutoModerationActionExecution](../interfaces/DiscordAutoModerationActionExecution.md) +- [DiscordAutoModerationActionMetadata](../interfaces/DiscordAutoModerationActionMetadata.md) +- [DiscordAutoModerationRule](../interfaces/DiscordAutoModerationRule.md) +- [DiscordAutoModerationRuleTriggerMetadata](../interfaces/DiscordAutoModerationRuleTriggerMetadata.md) +- [DiscordBan](../interfaces/DiscordBan.md) +- [DiscordButtonComponent](../interfaces/DiscordButtonComponent.md) +- [DiscordChannel](../interfaces/DiscordChannel.md) +- [DiscordChannelMention](../interfaces/DiscordChannelMention.md) +- [DiscordChannelPinsUpdate](../interfaces/DiscordChannelPinsUpdate.md) +- [DiscordClientStatus](../interfaces/DiscordClientStatus.md) +- [DiscordCreateApplicationCommand](../interfaces/DiscordCreateApplicationCommand.md) +- [DiscordCreateForumPostWithMessage](../interfaces/DiscordCreateForumPostWithMessage.md) +- [DiscordCreateGuildChannel](../interfaces/DiscordCreateGuildChannel.md) +- [DiscordCreateGuildEmoji](../interfaces/DiscordCreateGuildEmoji.md) +- [DiscordCreateMessage](../interfaces/DiscordCreateMessage.md) +- [DiscordCreateWebhook](../interfaces/DiscordCreateWebhook.md) +- [DiscordDefaultReactionEmoji](../interfaces/DiscordDefaultReactionEmoji.md) +- [DiscordEditChannelPermissionOverridesOptions](../interfaces/DiscordEditChannelPermissionOverridesOptions.md) +- [DiscordEmbed](../interfaces/DiscordEmbed.md) +- [DiscordEmbedAuthor](../interfaces/DiscordEmbedAuthor.md) +- [DiscordEmbedField](../interfaces/DiscordEmbedField.md) +- [DiscordEmbedFooter](../interfaces/DiscordEmbedFooter.md) +- [DiscordEmbedImage](../interfaces/DiscordEmbedImage.md) +- [DiscordEmbedProvider](../interfaces/DiscordEmbedProvider.md) +- [DiscordEmbedThumbnail](../interfaces/DiscordEmbedThumbnail.md) +- [DiscordEmbedVideo](../interfaces/DiscordEmbedVideo.md) +- [DiscordEmoji](../interfaces/DiscordEmoji.md) +- [DiscordFollowAnnouncementChannel](../interfaces/DiscordFollowAnnouncementChannel.md) +- [DiscordFollowedChannel](../interfaces/DiscordFollowedChannel.md) +- [DiscordForumTag](../interfaces/DiscordForumTag.md) +- [DiscordGatewayPayload](../interfaces/DiscordGatewayPayload.md) +- [DiscordGetGatewayBot](../interfaces/DiscordGetGatewayBot.md) +- [DiscordGuild](../interfaces/DiscordGuild.md) +- [DiscordGuildApplicationCommandPermissions](../interfaces/DiscordGuildApplicationCommandPermissions.md) +- [DiscordGuildBanAddRemove](../interfaces/DiscordGuildBanAddRemove.md) +- [DiscordGuildEmojisUpdate](../interfaces/DiscordGuildEmojisUpdate.md) +- [DiscordGuildIntegrationsUpdate](../interfaces/DiscordGuildIntegrationsUpdate.md) +- [DiscordGuildMemberAdd](../interfaces/DiscordGuildMemberAdd.md) +- [DiscordGuildMemberRemove](../interfaces/DiscordGuildMemberRemove.md) +- [DiscordGuildMemberUpdate](../interfaces/DiscordGuildMemberUpdate.md) +- [DiscordGuildMembersChunk](../interfaces/DiscordGuildMembersChunk.md) +- [DiscordGuildPreview](../interfaces/DiscordGuildPreview.md) +- [DiscordGuildRoleCreate](../interfaces/DiscordGuildRoleCreate.md) +- [DiscordGuildRoleDelete](../interfaces/DiscordGuildRoleDelete.md) +- [DiscordGuildRoleUpdate](../interfaces/DiscordGuildRoleUpdate.md) +- [DiscordGuildStickersUpdate](../interfaces/DiscordGuildStickersUpdate.md) +- [DiscordGuildWidget](../interfaces/DiscordGuildWidget.md) +- [DiscordGuildWidgetSettings](../interfaces/DiscordGuildWidgetSettings.md) +- [DiscordHello](../interfaces/DiscordHello.md) +- [DiscordIncomingWebhook](../interfaces/DiscordIncomingWebhook.md) +- [DiscordInputTextComponent](../interfaces/DiscordInputTextComponent.md) +- [DiscordInstallParams](../interfaces/DiscordInstallParams.md) +- [DiscordIntegration](../interfaces/DiscordIntegration.md) +- [DiscordIntegrationAccount](../interfaces/DiscordIntegrationAccount.md) +- [DiscordIntegrationApplication](../interfaces/DiscordIntegrationApplication.md) +- [DiscordIntegrationCreateUpdate](../interfaces/DiscordIntegrationCreateUpdate.md) +- [DiscordIntegrationDelete](../interfaces/DiscordIntegrationDelete.md) +- [DiscordInteraction](../interfaces/DiscordInteraction.md) +- [DiscordInteractionData](../interfaces/DiscordInteractionData.md) +- [DiscordInteractionDataOption](../interfaces/DiscordInteractionDataOption.md) +- [DiscordInteractionMember](../interfaces/DiscordInteractionMember.md) +- [DiscordInvite](../interfaces/DiscordInvite.md) +- [DiscordInviteCreate](../interfaces/DiscordInviteCreate.md) +- [DiscordInviteDelete](../interfaces/DiscordInviteDelete.md) +- [DiscordInviteMetadata](../interfaces/DiscordInviteMetadata.md) +- [DiscordInviteStageInstance](../interfaces/DiscordInviteStageInstance.md) +- [DiscordListActiveThreads](../interfaces/DiscordListActiveThreads.md) +- [DiscordListArchivedThreads](../interfaces/DiscordListArchivedThreads.md) +- [DiscordMember](../interfaces/DiscordMember.md) +- [DiscordMemberWithUser](../interfaces/DiscordMemberWithUser.md) +- [DiscordMessage](../interfaces/DiscordMessage.md) +- [DiscordMessageActivity](../interfaces/DiscordMessageActivity.md) +- [DiscordMessageDelete](../interfaces/DiscordMessageDelete.md) +- [DiscordMessageDeleteBulk](../interfaces/DiscordMessageDeleteBulk.md) +- [DiscordMessageInteraction](../interfaces/DiscordMessageInteraction.md) +- [DiscordMessageReactionAdd](../interfaces/DiscordMessageReactionAdd.md) +- [DiscordMessageReactionRemove](../interfaces/DiscordMessageReactionRemove.md) +- [DiscordMessageReactionRemoveAll](../interfaces/DiscordMessageReactionRemoveAll.md) +- [DiscordMessageReference](../interfaces/DiscordMessageReference.md) +- [DiscordModifyChannel](../interfaces/DiscordModifyChannel.md) +- [DiscordModifyGuildChannelPositions](../interfaces/DiscordModifyGuildChannelPositions.md) +- [DiscordModifyGuildEmoji](../interfaces/DiscordModifyGuildEmoji.md) +- [DiscordModifyGuildWelcomeScreen](../interfaces/DiscordModifyGuildWelcomeScreen.md) +- [DiscordOptionalAuditEntryInfo](../interfaces/DiscordOptionalAuditEntryInfo.md) +- [DiscordOverwrite](../interfaces/DiscordOverwrite.md) +- [DiscordPresenceUpdate](../interfaces/DiscordPresenceUpdate.md) +- [DiscordPrunedCount](../interfaces/DiscordPrunedCount.md) +- [DiscordReaction](../interfaces/DiscordReaction.md) +- [DiscordReady](../interfaces/DiscordReady.md) +- [DiscordRole](../interfaces/DiscordRole.md) +- [DiscordRoleTags](../interfaces/DiscordRoleTags.md) +- [DiscordScheduledEvent](../interfaces/DiscordScheduledEvent.md) +- [DiscordScheduledEventEntityMetadata](../interfaces/DiscordScheduledEventEntityMetadata.md) +- [DiscordScheduledEventUserAdd](../interfaces/DiscordScheduledEventUserAdd.md) +- [DiscordScheduledEventUserRemove](../interfaces/DiscordScheduledEventUserRemove.md) +- [DiscordSelectMenuComponent](../interfaces/DiscordSelectMenuComponent.md) +- [DiscordSelectOption](../interfaces/DiscordSelectOption.md) +- [DiscordSessionStartLimit](../interfaces/DiscordSessionStartLimit.md) +- [DiscordStageInstance](../interfaces/DiscordStageInstance.md) +- [DiscordSticker](../interfaces/DiscordSticker.md) +- [DiscordStickerItem](../interfaces/DiscordStickerItem.md) +- [DiscordStickerPack](../interfaces/DiscordStickerPack.md) +- [DiscordTeam](../interfaces/DiscordTeam.md) +- [DiscordTeamMember](../interfaces/DiscordTeamMember.md) +- [DiscordTemplate](../interfaces/DiscordTemplate.md) +- [DiscordThreadListSync](../interfaces/DiscordThreadListSync.md) +- [DiscordThreadMember](../interfaces/DiscordThreadMember.md) +- [DiscordThreadMemberUpdate](../interfaces/DiscordThreadMemberUpdate.md) +- [DiscordThreadMembersUpdate](../interfaces/DiscordThreadMembersUpdate.md) +- [DiscordThreadMetadata](../interfaces/DiscordThreadMetadata.md) +- [DiscordTypingStart](../interfaces/DiscordTypingStart.md) +- [DiscordUnavailableGuild](../interfaces/DiscordUnavailableGuild.md) +- [DiscordUser](../interfaces/DiscordUser.md) +- [DiscordVanityUrl](../interfaces/DiscordVanityUrl.md) +- [DiscordVoiceRegion](../interfaces/DiscordVoiceRegion.md) +- [DiscordVoiceServerUpdate](../interfaces/DiscordVoiceServerUpdate.md) +- [DiscordVoiceState](../interfaces/DiscordVoiceState.md) +- [DiscordWebhookUpdate](../interfaces/DiscordWebhookUpdate.md) +- [DiscordWelcomeScreen](../interfaces/DiscordWelcomeScreen.md) +- [DiscordWelcomeScreenChannel](../interfaces/DiscordWelcomeScreenChannel.md) +- [EditAutoModerationRuleOptions](../interfaces/EditAutoModerationRuleOptions.md) +- [EditBotMemberOptions](../interfaces/EditBotMemberOptions.md) +- [EditChannelPermissionOverridesOptions](../interfaces/EditChannelPermissionOverridesOptions.md) +- [EditGuildRole](../interfaces/EditGuildRole.md) +- [EditGuildStickerOptions](../interfaces/EditGuildStickerOptions.md) +- [EditMessage](../interfaces/EditMessage.md) +- [EditOwnVoiceState](../interfaces/EditOwnVoiceState.md) +- [EditScheduledEvent](../interfaces/EditScheduledEvent.md) +- [EditStageInstanceOptions](../interfaces/EditStageInstanceOptions.md) +- [EditUserVoiceState](../interfaces/EditUserVoiceState.md) +- [EventHandlers](../interfaces/EventHandlers.md) +- [ExecuteWebhook](../interfaces/ExecuteWebhook.md) +- [FileContent](../interfaces/FileContent.md) +- [GatewayManager](../interfaces/GatewayManager.md) +- [GetBans](../interfaces/GetBans.md) +- [GetGuildAuditLog](../interfaces/GetGuildAuditLog.md) +- [GetGuildPruneCountQuery](../interfaces/GetGuildPruneCountQuery.md) +- [GetGuildWidgetImageQuery](../interfaces/GetGuildWidgetImageQuery.md) +- [GetInvite](../interfaces/GetInvite.md) +- [GetMessagesAfter](../interfaces/GetMessagesAfter.md) +- [GetMessagesAround](../interfaces/GetMessagesAround.md) +- [GetMessagesBefore](../interfaces/GetMessagesBefore.md) +- [GetMessagesLimit](../interfaces/GetMessagesLimit.md) +- [GetReactions](../interfaces/GetReactions.md) +- [GetScheduledEventUsers](../interfaces/GetScheduledEventUsers.md) +- [GetScheduledEvents](../interfaces/GetScheduledEvents.md) +- [GetWebhookMessageOptions](../interfaces/GetWebhookMessageOptions.md) +- [InputTextComponent](../interfaces/InputTextComponent.md) +- [InteractionCallbackData](../interfaces/InteractionCallbackData.md) +- [InteractionResponse](../interfaces/InteractionResponse.md) +- [InvalidRequestBucket](../interfaces/InvalidRequestBucket.md) +- [InvalidRequestBucketOptions](../interfaces/InvalidRequestBucketOptions.md) +- [LeakyBucket](../interfaces/LeakyBucket.md) +- [ListArchivedThreads](../interfaces/ListArchivedThreads.md) +- [ListGuildMembers](../interfaces/ListGuildMembers.md) +- [ModifyChannel](../interfaces/ModifyChannel.md) +- [ModifyGuild](../interfaces/ModifyGuild.md) +- [ModifyGuildChannelPositions](../interfaces/ModifyGuildChannelPositions.md) +- [ModifyGuildEmoji](../interfaces/ModifyGuildEmoji.md) +- [ModifyGuildMember](../interfaces/ModifyGuildMember.md) +- [ModifyGuildTemplate](../interfaces/ModifyGuildTemplate.md) +- [ModifyRolePositions](../interfaces/ModifyRolePositions.md) +- [ModifyWebhook](../interfaces/ModifyWebhook.md) +- [OverwriteReadable](../interfaces/OverwriteReadable.md) +- [PlaceHolderBot](../interfaces/PlaceHolderBot.md) +- [QueueOptions](../interfaces/QueueOptions.md) +- [RequestBody](../interfaces/RequestBody.md) +- [RequestGuildMembers](../interfaces/RequestGuildMembers.md) +- [RequestMemberRequest](../interfaces/RequestMemberRequest.md) +- [RestManager](../interfaces/RestManager.md) +- [RestRateLimitedPath](../interfaces/RestRateLimitedPath.md) +- [RestRequestRejection](../interfaces/RestRequestRejection.md) +- [RestRequestResponse](../interfaces/RestRequestResponse.md) +- [RestRoutes](../interfaces/RestRoutes.md) +- [Rgb](../interfaces/Rgb.md) +- [SearchMembers](../interfaces/SearchMembers.md) +- [SelectMenuChannelsComponent](../interfaces/SelectMenuChannelsComponent.md) +- [SelectMenuComponent](../interfaces/SelectMenuComponent.md) +- [SelectMenuRolesComponent](../interfaces/SelectMenuRolesComponent.md) +- [SelectMenuUsersAndRolesComponent](../interfaces/SelectMenuUsersAndRolesComponent.md) +- [SelectMenuUsersComponent](../interfaces/SelectMenuUsersComponent.md) +- [SelectOption](../interfaces/SelectOption.md) +- [SendRequestOptions](../interfaces/SendRequestOptions.md) +- [ShardCreateOptions](../interfaces/ShardCreateOptions.md) +- [ShardEvents](../interfaces/ShardEvents.md) +- [ShardGatewayConfig](../interfaces/ShardGatewayConfig.md) +- [ShardHeart](../interfaces/ShardHeart.md) +- [ShardSocketRequest](../interfaces/ShardSocketRequest.md) +- [StartThreadWithMessage](../interfaces/StartThreadWithMessage.md) +- [StartThreadWithoutMessage](../interfaces/StartThreadWithoutMessage.md) +- [StatusUpdate](../interfaces/StatusUpdate.md) +- [UpdateVoiceState](../interfaces/UpdateVoiceState.md) +- [WebhookMessageEditor](../interfaces/WebhookMessageEditor.md) +- [WithReason](../interfaces/WithReason.md) + +### Type Aliases + +- [ApiVersions](md#apiversions) +- [AtLeastOne](md#atleastone) +- [BigString](md#bigstring) +- [CamelCase](md#camelcase) +- [Camelize](md#camelize) +- [CreateApplicationCommand](md#createapplicationcommand) +- [DiscordArchivedThreads](md#discordarchivedthreads) +- [DiscordAuditLogChange](md#discordauditlogchange) +- [DiscordMessageComponents](md#discordmessagecomponents) +- [DiscordMessageReactionRemoveEmoji](md#discordmessagereactionremoveemoji) +- [DiscordWebhook](md#discordwebhook) +- [EmbedTypes](md#embedtypes) +- [GatewayDispatchEventNames](md#gatewaydispatcheventnames) +- [GatewayEventNames](md#gatewayeventnames) +- [GetMessagesOptions](md#getmessagesoptions) +- [ImageFormat](md#imageformat) +- [ImageSize](md#imagesize) +- [Localization](md#localization) +- [MessageComponents](md#messagecomponents) +- [PermissionStrings](md#permissionstrings) +- [PickPartial](md#pickpartial) +- [RequestMethods](md#requestmethods) +- [SnakeCase](md#snakecase) +- [Snakelize](md#snakelize) + +### Variables + +- [Intents](md#intents) +- [logger](md#logger) + +### Functions + +- [acquire](md#acquire) +- [avatarUrl](md#avatarurl) +- [bgBlack](md#bgblack) +- [bgBlue](md#bgblue) +- [bgBrightBlack](md#bgbrightblack) +- [bgBrightBlue](md#bgbrightblue) +- [bgBrightCyan](md#bgbrightcyan) +- [bgBrightGreen](md#bgbrightgreen) +- [bgBrightMagenta](md#bgbrightmagenta) +- [bgBrightRed](md#bgbrightred) +- [bgBrightWhite](md#bgbrightwhite) +- [bgBrightYellow](md#bgbrightyellow) +- [bgCyan](md#bgcyan) +- [bgGreen](md#bggreen) +- [bgMagenta](md#bgmagenta) +- [bgRed](md#bgred) +- [bgRgb24](md#bgrgb24) +- [bgRgb8](md#bgrgb8) +- [bgWhite](md#bgwhite) +- [bgYellow](md#bgyellow) +- [black](md#black) +- [blue](md#blue) +- [bold](md#bold) +- [brightBlack](md#brightblack) +- [brightBlue](md#brightblue) +- [brightCyan](md#brightcyan) +- [brightGreen](md#brightgreen) +- [brightMagenta](md#brightmagenta) +- [brightRed](md#brightred) +- [brightWhite](md#brightwhite) +- [brightYellow](md#brightyellow) +- [calculateBits](md#calculatebits) +- [calculatePermissions](md#calculatepermissions) +- [camelToSnakeCase](md#cameltosnakecase) +- [camelize](md#camelize-1) +- [coerceToFileContent](md#coercetofilecontent) +- [createBot](md#createbot) +- [createGatewayManager](md#creategatewaymanager) +- [createInvalidRequestBucket](md#createinvalidrequestbucket) +- [createLeakyBucket](md#createleakybucket) +- [createLogger](md#createlogger) +- [createRestManager](md#createrestmanager) +- [cyan](md#cyan) +- [decode](md#decode) +- [delay](md#delay) +- [dim](md#dim) +- [emojiUrl](md#emojiurl) +- [encode](md#encode) +- [findFiles](md#findfiles) +- [formatImageUrl](md#formatimageurl) +- [getBotIdFromToken](md#getbotidfromtoken) +- [getColorEnabled](md#getcolorenabled) +- [getWidgetImageUrl](md#getwidgetimageurl) +- [gray](md#gray) +- [green](md#green) +- [guildBannerUrl](md#guildbannerurl) +- [guildIconUrl](md#guildiconurl) +- [guildSplashUrl](md#guildsplashurl) +- [hasProperty](md#hasproperty) +- [hidden](md#hidden) +- [iconBigintToHash](md#iconbiginttohash) +- [iconHashToBigInt](md#iconhashtobigint) +- [inverse](md#inverse) +- [isGetMessagesAfter](md#isgetmessagesafter) +- [isGetMessagesAround](md#isgetmessagesaround) +- [isGetMessagesBefore](md#isgetmessagesbefore) +- [isGetMessagesLimit](md#isgetmessageslimit) +- [italic](md#italic) +- [magenta](md#magenta) +- [nextRefill](md#nextrefill) +- [processReactionString](md#processreactionstring) +- [red](md#red) +- [removeTokenPrefix](md#removetokenprefix) +- [reset](md#reset) +- [rgb24](md#rgb24) +- [rgb8](md#rgb8) +- [setColorEnabled](md#setcolorenabled) +- [snakeToCamelCase](md#snaketocamelcase) +- [snakelize](md#snakelize-1) +- [strikethrough](md#strikethrough) +- [stripColor](md#stripcolor) +- [underline](md#underline) +- [updateTokens](md#updatetokens) +- [urlToBase64](md#urltobase64) +- [white](md#white) +- [yellow](md#yellow) + +## Type Aliases + +### ApiVersions + +Ƭ **ApiVersions**: ``9`` \| ``10`` + +#### Defined in + +packages/rest/dist/types.d.ts:2325 + +___ + +### AtLeastOne + +Ƭ **AtLeastOne**<`T`, `U`\>: `Partial`<`T`\> & `U`[keyof `U`] + +#### Type parameters + +| Name | Type | +| :------ | :------ | +| `T` | `T` | +| `U` | { [K in keyof T]: Pick } | + +#### Defined in + +packages/types/dist/shared.d.ts:831 + +___ + +### BigString + +Ƭ **BigString**: `bigint` \| `string` + +#### Defined in + +packages/types/dist/shared.d.ts:1 + +___ + +### CamelCase + +Ƭ **CamelCase**<`S`\>: `S` extends \`${infer T}\_${infer U}\` ? \`${T}${Capitalize\>}\` : `S` + +#### Type parameters + +| Name | Type | +| :------ | :------ | +| `S` | extends `string` | + +#### Defined in + +packages/types/dist/shared.d.ts:834 + +___ + +### Camelize + +Ƭ **Camelize**<`T`\>: `T` extends `any`[] ? `T` extends `Record`<`any`, `any`\>[] ? [`Camelize`](md#camelize)<`T`[`number`]\>[] : `T` : `T` extends `Record`<`any`, `any`\> ? { [K in keyof T as CamelCase]: Camelize } : `T` + +#### Type parameters + +| Name | +| :------ | +| `T` | + +#### Defined in + +packages/types/dist/shared.d.ts:836 + +___ + +### CreateApplicationCommand + +Ƭ **CreateApplicationCommand**: [`CreateSlashApplicationCommand`](../interfaces/CreateSlashApplicationCommand.md) \| [`CreateContextApplicationCommand`](../interfaces/CreateContextApplicationCommand.md) + +#### Defined in + +packages/types/dist/discordeno.d.ts:309 + +___ + +### DiscordArchivedThreads + +Ƭ **DiscordArchivedThreads**: [`DiscordActiveThreads`](../interfaces/DiscordActiveThreads.md) & { `hasMore`: `boolean` } + +#### Defined in + +packages/types/dist/discord.d.ts:2297 + +___ + +### DiscordAuditLogChange + +Ƭ **DiscordAuditLogChange**: { `key`: ``"name"`` \| ``"description"`` \| ``"discovery_splash_hash"`` \| ``"banner_hash"`` \| ``"preferred_locale"`` \| ``"rules_channel_id"`` \| ``"public_updates_channel_id"`` \| ``"icon_hash"`` \| ``"image_hash"`` \| ``"splash_hash"`` \| ``"owner_id"`` \| ``"region"`` \| ``"afk_channel_id"`` \| ``"vanity_url_code"`` \| ``"widget_channel_id"`` \| ``"system_channel_id"`` \| ``"topic"`` \| ``"application_id"`` \| ``"permissions"`` \| ``"allow"`` \| ``"deny"`` \| ``"code"`` \| ``"channel_id"`` \| ``"inviter_id"`` \| ``"nick"`` \| ``"avatar_hash"`` \| ``"id"`` \| ``"location"`` \| ``"command_id"`` ; `new_value`: `string` ; `old_value`: `string` } \| { `key`: ``"afk_timeout"`` \| ``"mfa_level"`` \| ``"verification_level"`` \| ``"explicit_content_filter"`` \| ``"default_message_notifications"`` \| ``"prune_delete_days"`` \| ``"position"`` \| ``"bitrate"`` \| ``"rate_limit_per_user"`` \| ``"color"`` \| ``"max_uses"`` \| ``"uses"`` \| ``"max_age"`` \| ``"expire_behavior"`` \| ``"expire_grace_period"`` \| ``"user_limit"`` \| ``"privacy_level"`` \| ``"auto_archive_duration"`` \| ``"default_auto_archive_duration"`` \| ``"entity_type"`` \| ``"status"`` \| ``"communication_disabled_until"`` ; `new_value`: `number` ; `old_value`: `number` } \| { `key`: ``"$add"`` \| ``"$remove"`` ; `new_value`: `Partial`<[`DiscordRole`](../interfaces/DiscordRole.md)\>[] ; `old_value?`: `Partial`<[`DiscordRole`](../interfaces/DiscordRole.md)\>[] } \| { `key`: ``"widget_enabled"`` \| ``"nsfw"`` \| ``"hoist"`` \| ``"mentionable"`` \| ``"temporary"`` \| ``"deaf"`` \| ``"mute"`` \| ``"enable_emoticons"`` \| ``"archived"`` \| ``"locked"`` \| ``"invitable"`` ; `new_value`: `boolean` ; `old_value`: `boolean` } \| { `key`: ``"permission_overwrites"`` ; `new_value`: [`DiscordOverwrite`](../interfaces/DiscordOverwrite.md)[] ; `old_value`: [`DiscordOverwrite`](../interfaces/DiscordOverwrite.md)[] } \| { `key`: ``"type"`` ; `new_value`: `string` \| `number` ; `old_value`: `string` \| `number` } + +https://discord.com/developers/docs/resources/audit-log#audit-log-change-object-audit-log-change-structure + +#### Defined in + +packages/types/dist/discord.d.ts:1368 + +___ + +### DiscordMessageComponents + +Ƭ **DiscordMessageComponents**: [`DiscordActionRow`](../interfaces/DiscordActionRow.md)[] + +#### Defined in + +packages/types/dist/discord.d.ts:1014 + +___ + +### DiscordMessageReactionRemoveEmoji + +Ƭ **DiscordMessageReactionRemoveEmoji**: `Pick`<[`DiscordMessageReactionAdd`](../interfaces/DiscordMessageReactionAdd.md), ``"channel_id"`` \| ``"guild_id"`` \| ``"message_id"`` \| ``"emoji"``\> + +https://discord.com/developers/docs/topics/gateway#message-reaction-remove-emoji + +#### Defined in + +packages/types/dist/discord.d.ts:2000 + +___ + +### DiscordWebhook + +Ƭ **DiscordWebhook**: [`DiscordIncomingWebhook`](../interfaces/DiscordIncomingWebhook.md) \| [`DiscordApplicationWebhook`](../interfaces/DiscordApplicationWebhook.md) + +https://discord.com/developers/docs/resources/webhook#webhook-object-webhook-structure + +#### Defined in + +packages/types/dist/discord.d.ts:356 + +___ + +### EmbedTypes + +Ƭ **EmbedTypes**: ``"rich"`` \| ``"image"`` \| ``"video"`` \| ``"gifv"`` \| ``"article"`` \| ``"link"`` + +https://discord.com/developers/docs/resources/channel#embed-object-embed-types + +#### Defined in + +packages/types/dist/shared.d.ts:129 + +___ + +### GatewayDispatchEventNames + +Ƭ **GatewayDispatchEventNames**: ``"READY"`` \| ``"APPLICATION_COMMAND_PERMISSIONS_UPDATE"`` \| ``"AUTO_MODERATION_RULE_CREATE"`` \| ``"AUTO_MODERATION_RULE_UPDATE"`` \| ``"AUTO_MODERATION_RULE_DELETE"`` \| ``"AUTO_MODERATION_ACTION_EXECUTION"`` \| ``"CHANNEL_CREATE"`` \| ``"CHANNEL_UPDATE"`` \| ``"CHANNEL_DELETE"`` \| ``"CHANNEL_PINS_UPDATE"`` \| ``"THREAD_CREATE"`` \| ``"THREAD_UPDATE"`` \| ``"THREAD_DELETE"`` \| ``"THREAD_LIST_SYNC"`` \| ``"THREAD_MEMBER_UPDATE"`` \| ``"THREAD_MEMBERS_UPDATE"`` \| ``"GUILD_CREATE"`` \| ``"GUILD_UPDATE"`` \| ``"GUILD_DELETE"`` \| ``"GUILD_BAN_ADD"`` \| ``"GUILD_BAN_REMOVE"`` \| ``"GUILD_EMOJIS_UPDATE"`` \| ``"GUILD_STICKERS_UPDATE"`` \| ``"GUILD_INTEGRATIONS_UPDATE"`` \| ``"GUILD_MEMBER_ADD"`` \| ``"GUILD_MEMBER_REMOVE"`` \| ``"GUILD_MEMBER_UPDATE"`` \| ``"GUILD_MEMBERS_CHUNK"`` \| ``"GUILD_ROLE_CREATE"`` \| ``"GUILD_ROLE_UPDATE"`` \| ``"GUILD_ROLE_DELETE"`` \| ``"GUILD_SCHEDULED_EVENT_CREATE"`` \| ``"GUILD_SCHEDULED_EVENT_UPDATE"`` \| ``"GUILD_SCHEDULED_EVENT_DELETE"`` \| ``"GUILD_SCHEDULED_EVENT_USER_ADD"`` \| ``"GUILD_SCHEDULED_EVENT_USER_REMOVE"`` \| ``"INTEGRATION_CREATE"`` \| ``"INTEGRATION_UPDATE"`` \| ``"INTEGRATION_DELETE"`` \| ``"INTERACTION_CREATE"`` \| ``"INVITE_CREATE"`` \| ``"INVITE_DELETE"`` \| ``"MESSAGE_CREATE"`` \| ``"MESSAGE_UPDATE"`` \| ``"MESSAGE_DELETE"`` \| ``"MESSAGE_DELETE_BULK"`` \| ``"MESSAGE_REACTION_ADD"`` \| ``"MESSAGE_REACTION_REMOVE"`` \| ``"MESSAGE_REACTION_REMOVE_ALL"`` \| ``"MESSAGE_REACTION_REMOVE_EMOJI"`` \| ``"PRESENCE_UPDATE"`` \| ``"STAGE_INSTANCE_CREATE"`` \| ``"STAGE_INSTANCE_UPDATE"`` \| ``"STAGE_INSTANCE_DELETE"`` \| ``"TYPING_START"`` \| ``"USER_UPDATE"`` \| ``"VOICE_STATE_UPDATE"`` \| ``"VOICE_SERVER_UPDATE"`` \| ``"WEBHOOKS_UPDATE"`` + +#### Defined in + +packages/types/dist/shared.d.ts:643 + +___ + +### GatewayEventNames + +Ƭ **GatewayEventNames**: [`GatewayDispatchEventNames`](md#gatewaydispatcheventnames) \| ``"READY"`` \| ``"RESUMED"`` + +#### Defined in + +packages/types/dist/shared.d.ts:644 + +___ + +### GetMessagesOptions + +Ƭ **GetMessagesOptions**: [`GetMessagesAfter`](../interfaces/GetMessagesAfter.md) \| [`GetMessagesBefore`](../interfaces/GetMessagesBefore.md) \| [`GetMessagesAround`](../interfaces/GetMessagesAround.md) \| [`GetMessagesLimit`](../interfaces/GetMessagesLimit.md) + +#### Defined in + +packages/types/dist/discordeno.d.ts:242 + +___ + +### ImageFormat + +Ƭ **ImageFormat**: ``"jpg"`` \| ``"jpeg"`` \| ``"png"`` \| ``"webp"`` \| ``"gif"`` \| ``"json"`` + +https://discord.com/developers/docs/reference#image-formatting +json is only for stickers + +#### Defined in + +packages/types/dist/shared.d.ts:795 + +___ + +### ImageSize + +Ƭ **ImageSize**: ``16`` \| ``32`` \| ``64`` \| ``128`` \| ``256`` \| ``512`` \| ``1024`` \| ``2048`` \| ``4096`` + +https://discord.com/developers/docs/reference#image-formatting + +#### Defined in + +packages/types/dist/shared.d.ts:797 + +___ + +### Localization + +Ƭ **Localization**: `Partial`<`Record`<[`Locales`](../enums/Locales.md), `string`\>\> + +#### Defined in + +packages/types/dist/shared.d.ts:830 + +___ + +### MessageComponents + +Ƭ **MessageComponents**: [`ActionRow`](../interfaces/ActionRow.md)[] + +#### Defined in + +packages/types/dist/discordeno.d.ts:35 + +___ + +### PermissionStrings + +Ƭ **PermissionStrings**: keyof typeof [`BitwisePermissionFlags`](../enums/BitwisePermissionFlags.md) + +#### Defined in + +packages/types/dist/shared.d.ts:584 + +___ + +### PickPartial + +Ƭ **PickPartial**<`T`, `K`\>: { [P in keyof T]?: T[P] } & { [P in K]: T[P] } + +#### Type parameters + +| Name | Type | +| :------ | :------ | +| `T` | `T` | +| `K` | extends keyof `T` | + +#### Defined in + +packages/types/dist/shared.d.ts:842 + +___ + +### RequestMethods + +Ƭ **RequestMethods**: ``"GET"`` \| ``"POST"`` \| ``"DELETE"`` \| ``"PATCH"`` \| ``"PUT"`` + +#### Defined in + +packages/rest/dist/types.d.ts:2324 + +___ + +### SnakeCase + +Ƭ **SnakeCase**<`S`\>: `S` extends \`${infer T}${infer U}\` ? \`${T extends Capitalize ? "\_" : ""}${Lowercase}${SnakeCase}\` : `S` + +#### Type parameters + +| Name | Type | +| :------ | :------ | +| `S` | extends `string` | + +#### Defined in + +packages/types/dist/shared.d.ts:835 + +___ + +### Snakelize + +Ƭ **Snakelize**<`T`\>: `T` extends `any`[] ? `T` extends `Record`<`any`, `any`\>[] ? [`Snakelize`](md#snakelize)<`T`[`number`]\>[] : `T` : `T` extends `Record`<`any`, `any`\> ? { [K in keyof T as SnakeCase]: Snakelize } : `T` + +#### Type parameters + +| Name | +| :------ | +| `T` | + +#### Defined in + +packages/types/dist/shared.d.ts:839 + +## Variables + +### Intents + +• `Const` **Intents**: typeof [`GatewayIntents`](../enums/GatewayIntents.md) + +https://discord.com/developers/docs/topics/gateway#list-of-intents + +#### Defined in + +packages/types/dist/shared.d.ts:767 + +___ + +### logger + +• `Const` **logger**: `Object` + +#### Type declaration + +| Name | Type | +| :------ | :------ | +| `debug` | (...`args`: `any`[]) => `void` | +| `error` | (...`args`: `any`[]) => `void` | +| `fatal` | (...`args`: `any`[]) => `void` | +| `info` | (...`args`: `any`[]) => `void` | +| `log` | (`level`: [`LogLevels`](../enums/LogLevels.md), ...`args`: `any`[]) => `void` | +| `setDepth` | (`level`: [`LogDepth`](../enums/LogDepth.md)) => `void` | +| `setLevel` | (`level`: [`LogLevels`](../enums/LogLevels.md)) => `void` | +| `warn` | (...`args`: `any`[]) => `void` | + +#### Defined in + +packages/utils/dist/logger.d.ts:25 + +## Functions + +### acquire + +▸ **acquire**(`bucket`, `amount`, `highPriority?`): `Promise`<`void`\> + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `bucket` | [`LeakyBucket`](../interfaces/LeakyBucket.md) | +| `amount` | `number` | +| `highPriority?` | `boolean` | + +#### Returns + +`Promise`<`void`\> + +#### Defined in + +packages/utils/dist/bucket.d.ts:54 + +___ + +### avatarUrl + +▸ **avatarUrl**(`userId`, `discriminator`, `options?`): `string` + +Builds a URL to a user's avatar stored in the Discord CDN. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `userId` | [`BigString`](md#bigstring) | The ID of the user to get the avatar of. | +| `discriminator` | `string` | The user's discriminator. (4-digit tag after the hashtag.) | +| `options?` | `Object` | The parameters for the building of the URL. | +| `options.avatar` | `undefined` \| [`BigString`](md#bigstring) | - | +| `options.format?` | [`ImageFormat`](md#imageformat) | - | +| `options.size?` | [`ImageSize`](md#imagesize) | - | + +#### Returns + +`string` + +The link to the resource. + +#### Defined in + +packages/utils/dist/images.d.ts:20 + +___ + +### bgBlack + +▸ **bgBlack**(`str`): `string` + +Set background color to black. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make its background black | + +#### Returns + +`string` + +#### Defined in + +packages/utils/dist/colors.d.ts:148 + +___ + +### bgBlue + +▸ **bgBlue**(`str`): `string` + +Set background color to blue. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make its background blue | + +#### Returns + +`string` + +#### Defined in + +packages/utils/dist/colors.d.ts:168 + +___ + +### bgBrightBlack + +▸ **bgBrightBlack**(`str`): `string` + +Set background color to bright black. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make its background bright-black | + +#### Returns + +`string` + +#### Defined in + +packages/utils/dist/colors.d.ts:188 + +___ + +### bgBrightBlue + +▸ **bgBrightBlue**(`str`): `string` + +Set background color to bright blue. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make its background bright-blue | + +#### Returns + +`string` + +#### Defined in + +packages/utils/dist/colors.d.ts:208 + +___ + +### bgBrightCyan + +▸ **bgBrightCyan**(`str`): `string` + +Set background color to bright cyan. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make its background bright-cyan | + +#### Returns + +`string` + +#### Defined in + +packages/utils/dist/colors.d.ts:218 + +___ + +### bgBrightGreen + +▸ **bgBrightGreen**(`str`): `string` + +Set background color to bright green. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make its background bright-green | + +#### Returns + +`string` + +#### Defined in + +packages/utils/dist/colors.d.ts:198 + +___ + +### bgBrightMagenta + +▸ **bgBrightMagenta**(`str`): `string` + +Set background color to bright magenta. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make its background bright-magenta | + +#### Returns + +`string` + +#### Defined in + +packages/utils/dist/colors.d.ts:213 + +___ + +### bgBrightRed + +▸ **bgBrightRed**(`str`): `string` + +Set background color to bright red. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make its background bright-red | + +#### Returns + +`string` + +#### Defined in + +packages/utils/dist/colors.d.ts:193 + +___ + +### bgBrightWhite + +▸ **bgBrightWhite**(`str`): `string` + +Set background color to bright white. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make its background bright-white | + +#### Returns + +`string` + +#### Defined in + +packages/utils/dist/colors.d.ts:223 + +___ + +### bgBrightYellow + +▸ **bgBrightYellow**(`str`): `string` + +Set background color to bright yellow. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make its background bright-yellow | + +#### Returns + +`string` + +#### Defined in + +packages/utils/dist/colors.d.ts:203 + +___ + +### bgCyan + +▸ **bgCyan**(`str`): `string` + +Set background color to cyan. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make its background cyan | + +#### Returns + +`string` + +#### Defined in + +packages/utils/dist/colors.d.ts:178 + +___ + +### bgGreen + +▸ **bgGreen**(`str`): `string` + +Set background color to green. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make its background green | + +#### Returns + +`string` + +#### Defined in + +packages/utils/dist/colors.d.ts:158 + +___ + +### bgMagenta + +▸ **bgMagenta**(`str`): `string` + +Set background color to magenta. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make its background magenta | + +#### Returns + +`string` + +#### Defined in + +packages/utils/dist/colors.d.ts:173 + +___ + +### bgRed + +▸ **bgRed**(`str`): `string` + +Set background color to red. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make its background red | + +#### Returns + +`string` + +#### Defined in + +packages/utils/dist/colors.d.ts:153 + +___ + +### bgRgb24 + +▸ **bgRgb24**(`str`, `color`): `string` + +Set background color using 24bit rgb. +`color` can be a number in range `0x000000` to `0xffffff` or +an `Rgb`. + +To produce the color magenta: + +```ts + import { bgRgb24 } from "./colors.ts"; + bgRgb24("foo", 0xff00ff); + bgRgb24("foo", {r: 255, g: 0, b: 255}); +``` + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text color to apply 24bit rgb to | +| `color` | `number` \| [`Rgb`](../interfaces/Rgb.md) | code | + +#### Returns + +`string` + +#### Defined in + +packages/utils/dist/colors.d.ts:269 + +___ + +### bgRgb8 + +▸ **bgRgb8**(`str`, `color`): `string` + +Set background color using paletted 8bit colors. +https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text color to apply paletted 8bit background colors to | +| `color` | `number` | code | + +#### Returns + +`string` + +#### Defined in + +packages/utils/dist/colors.d.ts:237 + +___ + +### bgWhite + +▸ **bgWhite**(`str`): `string` + +Set background color to white. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make its background white | + +#### Returns + +`string` + +#### Defined in + +packages/utils/dist/colors.d.ts:183 + +___ + +### bgYellow + +▸ **bgYellow**(`str`): `string` + +Set background color to yellow. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make its background yellow | + +#### Returns + +`string` + +#### Defined in + +packages/utils/dist/colors.d.ts:163 + +___ + +### black + +▸ **black**(`str`): `string` + +Set text color to black. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make black | + +#### Returns + +`string` + +#### Defined in + +packages/utils/dist/colors.d.ts:63 + +___ + +### blue + +▸ **blue**(`str`): `string` + +Set text color to blue. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make blue | + +#### Returns + +`string` + +#### Defined in + +packages/utils/dist/colors.d.ts:83 + +___ + +### bold + +▸ **bold**(`str`): `string` + +Make the text bold. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make bold | + +#### Returns + +`string` + +#### Defined in + +packages/utils/dist/colors.d.ts:28 + +___ + +### brightBlack + +▸ **brightBlack**(`str`): `string` + +Set text color to bright black. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make bright-black | + +#### Returns + +`string` + +#### Defined in + +packages/utils/dist/colors.d.ts:108 + +___ + +### brightBlue + +▸ **brightBlue**(`str`): `string` + +Set text color to bright blue. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make bright-blue | + +#### Returns + +`string` + +#### Defined in + +packages/utils/dist/colors.d.ts:128 + +___ + +### brightCyan + +▸ **brightCyan**(`str`): `string` + +Set text color to bright cyan. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make bright-cyan | + +#### Returns + +`string` + +#### Defined in + +packages/utils/dist/colors.d.ts:138 + +___ + +### brightGreen + +▸ **brightGreen**(`str`): `string` + +Set text color to bright green. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make bright-green | + +#### Returns + +`string` + +#### Defined in + +packages/utils/dist/colors.d.ts:118 + +___ + +### brightMagenta + +▸ **brightMagenta**(`str`): `string` + +Set text color to bright magenta. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make bright-magenta | + +#### Returns + +`string` + +#### Defined in + +packages/utils/dist/colors.d.ts:133 + +___ + +### brightRed + +▸ **brightRed**(`str`): `string` + +Set text color to bright red. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make bright-red | + +#### Returns + +`string` + +#### Defined in + +packages/utils/dist/colors.d.ts:113 + +___ + +### brightWhite + +▸ **brightWhite**(`str`): `string` + +Set text color to bright white. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make bright-white | + +#### Returns + +`string` + +#### Defined in + +packages/utils/dist/colors.d.ts:143 + +___ + +### brightYellow + +▸ **brightYellow**(`str`): `string` + +Set text color to bright yellow. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make bright-yellow | + +#### Returns + +`string` + +#### Defined in + +packages/utils/dist/colors.d.ts:123 + +___ + +### calculateBits + +▸ **calculateBits**(`permissions`): `string` + +This function converts an array of permissions into the bitwise string. + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `permissions` | (``"CREATE_INSTANT_INVITE"`` \| ``"KICK_MEMBERS"`` \| ``"BAN_MEMBERS"`` \| ``"ADMINISTRATOR"`` \| ``"MANAGE_CHANNELS"`` \| ``"MANAGE_GUILD"`` \| ``"ADD_REACTIONS"`` \| ``"VIEW_AUDIT_LOG"`` \| ``"PRIORITY_SPEAKER"`` \| ``"STREAM"`` \| ``"VIEW_CHANNEL"`` \| ``"SEND_MESSAGES"`` \| ``"SEND_TTS_MESSAGES"`` \| ``"MANAGE_MESSAGES"`` \| ``"EMBED_LINKS"`` \| ``"ATTACH_FILES"`` \| ``"READ_MESSAGE_HISTORY"`` \| ``"MENTION_EVERYONE"`` \| ``"USE_EXTERNAL_EMOJIS"`` \| ``"VIEW_GUILD_INSIGHTS"`` \| ``"CONNECT"`` \| ``"SPEAK"`` \| ``"MUTE_MEMBERS"`` \| ``"DEAFEN_MEMBERS"`` \| ``"MOVE_MEMBERS"`` \| ``"USE_VAD"`` \| ``"CHANGE_NICKNAME"`` \| ``"MANAGE_NICKNAMES"`` \| ``"MANAGE_ROLES"`` \| ``"MANAGE_WEBHOOKS"`` \| ``"MANAGE_EMOJIS_AND_STICKERS"`` \| ``"USE_SLASH_COMMANDS"`` \| ``"REQUEST_TO_SPEAK"`` \| ``"MANAGE_EVENTS"`` \| ``"MANAGE_THREADS"`` \| ``"CREATE_PUBLIC_THREADS"`` \| ``"CREATE_PRIVATE_THREADS"`` \| ``"USE_EXTERNAL_STICKERS"`` \| ``"SEND_MESSAGES_IN_THREADS"`` \| ``"USE_EMBEDDED_ACTIVITIES"`` \| ``"MODERATE_MEMBERS"``)[] | + +#### Returns + +`string` + +#### Defined in + +packages/utils/dist/permissions.d.ts:5 + +___ + +### calculatePermissions + +▸ **calculatePermissions**(`permissionBits`): [`PermissionStrings`](md#permissionstrings)[] + +This function converts a bitwise string to permission strings + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `permissionBits` | `bigint` | + +#### Returns + +[`PermissionStrings`](md#permissionstrings)[] + +#### Defined in + +packages/utils/dist/permissions.d.ts:3 + +___ + +### camelToSnakeCase + +▸ **camelToSnakeCase**(`str`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `str` | `string` | + +#### Returns + +`string` + +#### Defined in + +packages/utils/dist/casing.d.ts:5 + +___ + +### camelize + +▸ **camelize**<`T`\>(`object`): [`Camelize`](md#camelize)<`T`\> + +#### Type parameters + +| Name | +| :------ | +| `T` | + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `object` | `T` | + +#### Returns + +[`Camelize`](md#camelize)<`T`\> + +#### Defined in + +packages/utils/dist/casing.d.ts:2 + +___ + +### coerceToFileContent + +▸ **coerceToFileContent**(`value`): value is FileContent + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `value` | `unknown` | + +#### Returns + +value is FileContent + +#### Defined in + +packages/utils/dist/files.d.ts:3 + +___ + +### createBot + +▸ **createBot**(`options`): [`Bot`](../interfaces/Bot.md) + +Create a bot object that will maintain the rest and gateway connection. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `options` | [`CreateBotOptions`](../interfaces/CreateBotOptions.md) | Configurations options used to manage this bot. | + +#### Returns + +[`Bot`](../interfaces/Bot.md) + +Bot + +#### Defined in + +[packages/bot/src/bot.ts:62](https://github.com/discordeno/discordeno/blob/b8c25357/packages/bot/src/bot.ts#L62) + +___ + +### createGatewayManager + +▸ **createGatewayManager**(`options`): [`GatewayManager`](../interfaces/GatewayManager.md) + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `options` | [`CreateGatewayManagerOptions`](../interfaces/CreateGatewayManagerOptions.md) | + +#### Returns + +[`GatewayManager`](../interfaces/GatewayManager.md) + +#### Defined in + +packages/gateway/dist/manager.d.ts:6 + +___ + +### createInvalidRequestBucket + +▸ **createInvalidRequestBucket**(`options`): [`InvalidRequestBucket`](../interfaces/InvalidRequestBucket.md) + +A invalid request bucket is used in a similar manner as a leaky bucket but a invalid request bucket can be refilled as needed. +It's purpose is to make sure the bot does not hit the limit to getting a 1 hr ban. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `options` | [`InvalidRequestBucketOptions`](../interfaces/InvalidRequestBucketOptions.md) | The options used to configure this bucket. | + +#### Returns + +[`InvalidRequestBucket`](../interfaces/InvalidRequestBucket.md) + +RefillingBucket + +#### Defined in + +packages/rest/dist/invalidBucket.d.ts:9 + +___ + +### createLeakyBucket + +▸ **createLeakyBucket**(`«destructured»`): [`LeakyBucket`](../interfaces/LeakyBucket.md) + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `«destructured»` | `Omit`<[`PickPartial`](md#pickpartial)<[`LeakyBucket`](../interfaces/LeakyBucket.md), ``"max"`` \| ``"refillInterval"`` \| ``"refillAmount"``\>, ``"tokens"``\> & { `tokens?`: `number` } | + +#### Returns + +[`LeakyBucket`](../interfaces/LeakyBucket.md) + +#### Defined in + +packages/utils/dist/bucket.d.ts:43 + +___ + +### createLogger + +▸ **createLogger**(`«destructured»?`): `Object` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `«destructured»` | `Object` | +| › `logLevel?` | [`LogLevels`](../enums/LogLevels.md) | +| › `name?` | `string` | + +#### Returns + +`Object` + +| Name | Type | +| :------ | :------ | +| `debug` | (...`args`: `any`[]) => `void` | +| `error` | (...`args`: `any`[]) => `void` | +| `fatal` | (...`args`: `any`[]) => `void` | +| `info` | (...`args`: `any`[]) => `void` | +| `log` | (`level`: [`LogLevels`](../enums/LogLevels.md), ...`args`: `any`[]) => `void` | +| `setDepth` | (`level`: [`LogDepth`](../enums/LogDepth.md)) => `void` | +| `setLevel` | (`level`: [`LogLevels`](../enums/LogLevels.md)) => `void` | +| `warn` | (...`args`: `any`[]) => `void` | + +#### Defined in + +packages/utils/dist/logger.d.ts:12 + +___ + +### createRestManager + +▸ **createRestManager**(`options`): [`RestManager`](../interfaces/RestManager.md) + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `options` | [`CreateRestManagerOptions`](../interfaces/CreateRestManagerOptions.md) | + +#### Returns + +[`RestManager`](../interfaces/RestManager.md) + +#### Defined in + +packages/rest/dist/manager.d.ts:2 + +___ + +### cyan + +▸ **cyan**(`str`): `string` + +Set text color to cyan. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make cyan | + +#### Returns + +`string` + +#### Defined in + +packages/utils/dist/colors.d.ts:93 + +___ + +### decode + +▸ **decode**(`data`): `Uint8Array` + +CREDIT: https://gist.github.com/enepomnyaschih/72c423f727d395eeaa09697058238727 +Decodes RFC4648 base64 string into an Uint8Array + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `data` | `string` | + +#### Returns + +`Uint8Array` + +#### Defined in + +packages/utils/dist/base64.d.ts:12 + +___ + +### delay + +▸ **delay**(`ms`): `Promise`<`void`\> + +Pause the execution for a given amount of milliseconds. + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `ms` | `number` | + +#### Returns + +`Promise`<`void`\> + +#### Defined in + +packages/utils/dist/utils.d.ts:2 + +___ + +### dim + +▸ **dim**(`str`): `string` + +The text emits only a small amount of light. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to dim | + +#### Returns + +`string` + +#### Defined in + +packages/utils/dist/colors.d.ts:33 + +___ + +### emojiUrl + +▸ **emojiUrl**(`emojiId`, `animated?`): `string` + +Get the url for an emoji. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `emojiId` | [`BigString`](md#bigstring) | The id of the emoji | +| `animated?` | `boolean` | Whether or not the emoji is animated | + +#### Returns + +`string` + +string + +#### Defined in + +packages/utils/dist/images.d.ts:11 + +___ + +### encode + +▸ **encode**(`data`): `string` + +CREDIT: https://gist.github.com/enepomnyaschih/72c423f727d395eeaa09697058238727 +Encodes a given Uint8Array, ArrayBuffer or string into RFC4648 base64 representation + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `data` | `string` \| `ArrayBuffer` | + +#### Returns + +`string` + +#### Defined in + +packages/utils/dist/base64.d.ts:6 + +___ + +### findFiles + +▸ **findFiles**(`file`): [`FileContent`](../interfaces/FileContent.md)[] + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `file` | `unknown` | + +#### Returns + +[`FileContent`](../interfaces/FileContent.md)[] + +#### Defined in + +packages/utils/dist/files.d.ts:2 + +___ + +### formatImageUrl + +▸ **formatImageUrl**(`url`, `size?`, `format?`): `string` + +Help format an image url. + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `url` | `string` | +| `size?` | [`ImageSize`](md#imagesize) | +| `format?` | [`ImageFormat`](md#imageformat) | + +#### Returns + +`string` + +#### Defined in + +packages/utils/dist/images.d.ts:3 + +___ + +### getBotIdFromToken + +▸ **getBotIdFromToken**(`token`): `bigint` + +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. + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `token` | `string` | + +#### Returns + +`bigint` + +#### Defined in + +packages/utils/dist/token.d.ts:4 + +___ + +### getColorEnabled + +▸ **getColorEnabled**(): `boolean` + +Get whether text color change is enabled or disabled. + +#### Returns + +`boolean` + +#### Defined in + +packages/utils/dist/colors.d.ts:18 + +___ + +### getWidgetImageUrl + +▸ **getWidgetImageUrl**(`guildId`, `options?`): `string` + +Builds a URL to the guild widget image stored in the Discord CDN. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `guildId` | [`BigString`](md#bigstring) | The ID of the guild to get the link to the widget image for. | +| `options?` | [`GetGuildWidgetImageQuery`](../interfaces/GetGuildWidgetImageQuery.md) | The parameters for the building of the URL. | + +#### Returns + +`string` + +The link to the resource. + +#### Defined in + +packages/utils/dist/images.d.ts:67 + +___ + +### gray + +▸ **gray**(`str`): `string` + +Set text color to gray. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make gray | + +#### Returns + +`string` + +#### Defined in + +packages/utils/dist/colors.d.ts:103 + +___ + +### green + +▸ **green**(`str`): `string` + +Set text color to green. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make green | + +#### Returns + +`string` + +#### Defined in + +packages/utils/dist/colors.d.ts:73 + +___ + +### guildBannerUrl + +▸ **guildBannerUrl**(`guildId`, `options`): `string` \| `undefined` + +Builds a URL to the guild banner stored in the Discord CDN. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `guildId` | [`BigString`](md#bigstring) | The ID of the guild to get the link to the banner for. | +| `options` | `Object` | The parameters for the building of the URL. | +| `options.banner?` | `string` \| `bigint` | - | +| `options.format?` | [`ImageFormat`](md#imageformat) | - | +| `options.size?` | [`ImageSize`](md#imagesize) | - | + +#### Returns + +`string` \| `undefined` + +The link to the resource or `undefined` if no banner has been set. + +#### Defined in + +packages/utils/dist/images.d.ts:32 + +___ + +### guildIconUrl + +▸ **guildIconUrl**(`guildId`, `imageHash`, `options?`): `string` \| `undefined` + +Builds a URL to the guild icon stored in the Discord CDN. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `guildId` | [`BigString`](md#bigstring) | The ID of the guild to get the link to the banner for. | +| `imageHash` | `undefined` \| [`BigString`](md#bigstring) | - | +| `options?` | `Object` | The parameters for the building of the URL. | +| `options.format?` | [`ImageFormat`](md#imageformat) | - | +| `options.size?` | [`ImageSize`](md#imagesize) | - | + +#### Returns + +`string` \| `undefined` + +The link to the resource or `undefined` if no banner has been set. + +#### Defined in + +packages/utils/dist/images.d.ts:44 + +___ + +### guildSplashUrl + +▸ **guildSplashUrl**(`guildId`, `imageHash`, `options?`): `string` \| `undefined` + +Builds the URL to a guild splash stored in the Discord CDN. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `guildId` | [`BigString`](md#bigstring) | The ID of the guild to get the splash of. | +| `imageHash` | `undefined` \| [`BigString`](md#bigstring) | The hash identifying the splash image. | +| `options?` | `Object` | The parameters for the building of the URL. | +| `options.format?` | [`ImageFormat`](md#imageformat) | - | +| `options.size?` | [`ImageSize`](md#imagesize) | - | + +#### Returns + +`string` \| `undefined` + +The link to the resource or `undefined` if the guild does not have a splash image set. + +#### Defined in + +packages/utils/dist/images.d.ts:56 + +___ + +### hasProperty + +▸ **hasProperty**<`T`, `Y`\>(`obj`, `prop`): obj is T & Record + +TS save way to check if a property exists in an object + +#### Type parameters + +| Name | Type | +| :------ | :------ | +| `T` | extends `Object` | +| `Y` | extends `PropertyKey` = `string` | + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `obj` | `T` | +| `prop` | `Y` | + +#### Returns + +obj is T & Record + +#### Defined in + +packages/utils/dist/utils.d.ts:4 + +___ + +### hidden + +▸ **hidden**(`str`): `string` + +Make the text hidden. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to hide | + +#### Returns + +`string` + +#### Defined in + +packages/utils/dist/colors.d.ts:53 + +___ + +### iconBigintToHash + +▸ **iconBigintToHash**(`icon`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `icon` | `bigint` | + +#### Returns + +`string` + +#### Defined in + +packages/utils/dist/hash.d.ts:2 + +___ + +### iconHashToBigInt + +▸ **iconHashToBigInt**(`hash`): `bigint` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `hash` | `string` | + +#### Returns + +`bigint` + +#### Defined in + +packages/utils/dist/hash.d.ts:1 + +___ + +### inverse + +▸ **inverse**(`str`): `string` + +Invert background color and text color. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to invert its color | + +#### Returns + +`string` + +#### Defined in + +packages/utils/dist/colors.d.ts:48 + +___ + +### isGetMessagesAfter + +▸ **isGetMessagesAfter**(`options`): options is GetMessagesAfter + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `options` | [`GetMessagesOptions`](md#getmessagesoptions) | + +#### Returns + +options is GetMessagesAfter + +#### Defined in + +packages/utils/dist/typeguards.d.ts:2 + +___ + +### isGetMessagesAround + +▸ **isGetMessagesAround**(`options`): options is GetMessagesAround + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `options` | [`GetMessagesOptions`](md#getmessagesoptions) | + +#### Returns + +options is GetMessagesAround + +#### Defined in + +packages/utils/dist/typeguards.d.ts:4 + +___ + +### isGetMessagesBefore + +▸ **isGetMessagesBefore**(`options`): options is GetMessagesBefore + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `options` | [`GetMessagesOptions`](md#getmessagesoptions) | + +#### Returns + +options is GetMessagesBefore + +#### Defined in + +packages/utils/dist/typeguards.d.ts:3 + +___ + +### isGetMessagesLimit + +▸ **isGetMessagesLimit**(`options`): options is GetMessagesLimit + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `options` | [`GetMessagesOptions`](md#getmessagesoptions) | + +#### Returns + +options is GetMessagesLimit + +#### Defined in + +packages/utils/dist/typeguards.d.ts:5 + +___ + +### italic + +▸ **italic**(`str`): `string` + +Make the text italic. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make italic | + +#### Returns + +`string` + +#### Defined in + +packages/utils/dist/colors.d.ts:38 + +___ + +### magenta + +▸ **magenta**(`str`): `string` + +Set text color to magenta. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make magenta | + +#### Returns + +`string` + +#### Defined in + +packages/utils/dist/colors.d.ts:88 + +___ + +### nextRefill + +▸ **nextRefill**(`bucket`): `number` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `bucket` | [`LeakyBucket`](../interfaces/LeakyBucket.md) | + +#### Returns + +`number` + +#### Defined in + +packages/utils/dist/bucket.d.ts:53 + +___ + +### processReactionString + +▸ **processReactionString**(`reaction`): `string` + +Converts an reaction emoji unicode string to the discord required form of name:id + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `reaction` | `string` | + +#### Returns + +`string` + +#### Defined in + +packages/utils/dist/reactions.d.ts:2 + +___ + +### red + +▸ **red**(`str`): `string` + +Set text color to red. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make red | + +#### Returns + +`string` + +#### Defined in + +packages/utils/dist/colors.d.ts:68 + +___ + +### removeTokenPrefix + +▸ **removeTokenPrefix**(`token?`, `type?`): `string` + +Removes the Bot before the token. + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `token?` | `string` | +| `type?` | ``"GATEWAY"`` \| ``"REST"`` | + +#### Returns + +`string` + +#### Defined in + +packages/utils/dist/token.d.ts:2 + +___ + +### reset + +▸ **reset**(`str`): `string` + +Reset the text modified + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to reset | + +#### Returns + +`string` + +#### Defined in + +packages/utils/dist/colors.d.ts:23 + +___ + +### rgb24 + +▸ **rgb24**(`str`, `color`): `string` + +Set text color using 24bit rgb. +`color` can be a number in range `0x000000` to `0xffffff` or +an `Rgb`. + +To produce the color magenta: + +```ts + import { rgb24 } from "./colors.ts"; + rgb24("foo", 0xff00ff); + rgb24("foo", {r: 255, g: 0, b: 255}); +``` + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text color to apply 24bit rgb to | +| `color` | `number` \| [`Rgb`](../interfaces/Rgb.md) | code | + +#### Returns + +`string` + +#### Defined in + +packages/utils/dist/colors.d.ts:253 + +___ + +### rgb8 + +▸ **rgb8**(`str`, `color`): `string` + +Set text color using paletted 8bit colors. +https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text color to apply paletted 8bit colors to | +| `color` | `number` | code | + +#### Returns + +`string` + +#### Defined in + +packages/utils/dist/colors.d.ts:230 + +___ + +### setColorEnabled + +▸ **setColorEnabled**(`value`): `void` + +Set changing text color to enabled or disabled + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `value` | `boolean` | + +#### Returns + +`void` + +#### Defined in + +packages/utils/dist/colors.d.ts:16 + +___ + +### snakeToCamelCase + +▸ **snakeToCamelCase**(`str`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `str` | `string` | + +#### Returns + +`string` + +#### Defined in + +packages/utils/dist/casing.d.ts:4 + +___ + +### snakelize + +▸ **snakelize**<`T`\>(`object`): [`Snakelize`](md#snakelize)<`T`\> + +#### Type parameters + +| Name | +| :------ | +| `T` | + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `object` | `T` | + +#### Returns + +[`Snakelize`](md#snakelize)<`T`\> + +#### Defined in + +packages/utils/dist/casing.d.ts:3 + +___ + +### strikethrough + +▸ **strikethrough**(`str`): `string` + +Put horizontal line through the center of the text. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to strike through | + +#### Returns + +`string` + +#### Defined in + +packages/utils/dist/colors.d.ts:58 + +___ + +### stripColor + +▸ **stripColor**(`string`): `string` + +Remove ANSI escape codes from the string. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `string` | `string` | to remove ANSI escape codes from | + +#### Returns + +`string` + +#### Defined in + +packages/utils/dist/colors.d.ts:274 + +___ + +### underline + +▸ **underline**(`str`): `string` + +Make the text underline. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to underline | + +#### Returns + +`string` + +#### Defined in + +packages/utils/dist/colors.d.ts:43 + +___ + +### updateTokens + +▸ **updateTokens**(`bucket`): `number` + +Update the tokens of that bucket. + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `bucket` | [`LeakyBucket`](../interfaces/LeakyBucket.md) | + +#### Returns + +`number` + +The amount of current available tokens. + +#### Defined in + +packages/utils/dist/bucket.d.ts:52 + +___ + +### urlToBase64 + +▸ **urlToBase64**(`url`): `Promise`<`string`\> + +Converts a url to base 64. Useful for example, uploading/creating server emojis. + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `url` | `string` | + +#### Returns + +`Promise`<`string`\> + +#### Defined in + +packages/utils/dist/urlToBase64.d.ts:2 + +___ + +### white + +▸ **white**(`str`): `string` + +Set text color to white. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make white | + +#### Returns + +`string` + +#### Defined in + +packages/utils/dist/colors.d.ts:98 + +___ + +### yellow + +▸ **yellow**(`str`): `string` + +Set text color to yellow. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make yellow | + +#### Returns + +`string` + +#### Defined in + +packages/utils/dist/colors.d.ts:78 diff --git a/website/docs/generated/modules_client.md b/website/docs/generated/modules_client.md new file mode 100644 index 000000000..d453bab72 --- /dev/null +++ b/website/docs/generated/modules_client.md @@ -0,0 +1,3289 @@ +[discordeno-monorepo](../README.md) / [Modules](../modules.md) / @discordeno/client + +# Module: @discordeno/client + +## Table of contents + +### References + +- [default](md#default) + +### Enumerations + +- [InviteTargetTypes](../enums/InviteTargetTypes.md) + +### Classes + +- [AutocompleteInteraction](../classes/AutocompleteInteraction.md) +- [Base](../classes/Base.md) +- [CategoryChannel](../classes/CategoryChannel.md) +- [Channel](../classes/Channel.md) +- [Client](../classes/Client.md) +- [Collection](../classes/Collection.md) +- [CommandInteraction](../classes/CommandInteraction.md) +- [ComponentInteraction](../classes/ComponentInteraction.md) +- [ExtendedUser](../classes/ExtendedUser.md) +- [Guild](../classes/Guild.md) +- [GuildAuditLogEntry](../classes/GuildAuditLogEntry.md) +- [GuildChannel](../classes/GuildChannel.md) +- [GuildIntegration](../classes/GuildIntegration.md) +- [GuildPreview](../classes/GuildPreview.md) +- [GuildTemplate](../classes/GuildTemplate.md) +- [Interaction](../classes/Interaction.md) +- [Invite](../classes/Invite.md) +- [Member](../classes/Member.md) +- [Message](../classes/Message.md) +- [NewsChannel](../classes/NewsChannel.md) +- [NewsThreadChannel](../classes/NewsThreadChannel.md) +- [Permission](../classes/Permission.md) +- [PermissionOverwrite](../classes/PermissionOverwrite.md) +- [PingInteraction](../classes/PingInteraction.md) +- [PrivateChannel](../classes/PrivateChannel.md) +- [PrivateThreadChannel](../classes/PrivateThreadChannel.md) +- [PublicThreadChannel](../classes/PublicThreadChannel.md) +- [Role](../classes/Role.md) +- [Shard](../classes/Shard.md) +- [ShardManager](../classes/ShardManager.md) +- [StageChannel](../classes/StageChannel.md) +- [StageInstance](../classes/StageInstance.md) +- [TextChannel](../classes/TextChannel.md) +- [TextVoiceChannel](../classes/TextVoiceChannel.md) +- [ThreadChannel](../classes/ThreadChannel.md) +- [ThreadMember](../classes/ThreadMember.md) +- [UnavailableGuild](../classes/UnavailableGuild.md) +- [UnknownInteraction](../classes/UnknownInteraction.md) +- [User](../classes/User.md) +- [VoiceChannel](../classes/VoiceChannel.md) +- [VoiceState](../classes/VoiceState.md) + +### Interfaces + +- [ActionRow](../interfaces/ActionRow.md) +- [Activity](../interfaces/Activity.md) +- [ActivityPartial](../interfaces/ActivityPartial.md) +- [AdvancedMessageContent](../interfaces/AdvancedMessageContent.md) +- [AdvancedMessageContentEdit](../interfaces/AdvancedMessageContentEdit.md) +- [AllowedMentions](../interfaces/AllowedMentions.md) +- [ApplicationCommand](../interfaces/ApplicationCommand.md) +- [ApplicationCommandOption](../interfaces/ApplicationCommandOption.md) +- [ApplicationCommandOptionChoice](../interfaces/ApplicationCommandOptionChoice.md) +- [ApplicationCommandOptionWithChoices](../interfaces/ApplicationCommandOptionWithChoices.md) +- [ApplicationCommandOptionsSubCommand](../interfaces/ApplicationCommandOptionsSubCommand.md) +- [ApplicationCommandOptionsSubCommandGroup](../interfaces/ApplicationCommandOptionsSubCommandGroup.md) +- [ApplicationCommandPermissions](../interfaces/ApplicationCommandPermissions.md) +- [AutocompleteDisabled](../interfaces/AutocompleteDisabled.md) +- [AutocompleteDisabledInteger](../interfaces/AutocompleteDisabledInteger.md) +- [AutocompleteDisabledIntegerMinMax](../interfaces/AutocompleteDisabledIntegerMinMax.md) +- [AutocompleteEnabled](../interfaces/AutocompleteEnabled.md) +- [ButtonBase](../interfaces/ButtonBase.md) +- [ChannelFollow](../interfaces/ChannelFollow.md) +- [ChannelPosition](../interfaces/ChannelPosition.md) +- [ClientOptions](../interfaces/ClientOptions.md) +- [ClientPresence](../interfaces/ClientPresence.md) +- [CreateChannelInviteOptions](../interfaces/CreateChannelInviteOptions.md) +- [CreateChannelOptions](../interfaces/CreateChannelOptions.md) +- [CreateGuildOptions](../interfaces/CreateGuildOptions.md) +- [CreateInviteOptions](../interfaces/CreateInviteOptions.md) +- [CreateStickerOptions](../interfaces/CreateStickerOptions.md) +- [CreateThreadOptions](../interfaces/CreateThreadOptions.md) +- [CreateThreadWithoutMessageOptions](../interfaces/CreateThreadWithoutMessageOptions.md) +- [DiscoveryCategory](../interfaces/DiscoveryCategory.md) +- [DiscoveryMetadata](../interfaces/DiscoveryMetadata.md) +- [DiscoveryOptions](../interfaces/DiscoveryOptions.md) +- [DiscoverySubcategoryResponse](../interfaces/DiscoverySubcategoryResponse.md) +- [EditChannelOptions](../interfaces/EditChannelOptions.md) +- [EditChannelPositionOptions](../interfaces/EditChannelPositionOptions.md) +- [EditStickerOptions](../interfaces/EditStickerOptions.md) +- [EmbedAuthorOptions](../interfaces/EmbedAuthorOptions.md) +- [EmbedField](../interfaces/EmbedField.md) +- [EmbedFooterOptions](../interfaces/EmbedFooterOptions.md) +- [EmbedImageOptions](../interfaces/EmbedImageOptions.md) +- [EmbedOptions](../interfaces/EmbedOptions.md) +- [Emoji](../interfaces/Emoji.md) +- [EmojiBase](../interfaces/EmojiBase.md) +- [EmojiOptions](../interfaces/EmojiOptions.md) +- [FetchMembersOptions](../interfaces/FetchMembersOptions.md) +- [FileContent](../interfaces/FileContent.md) +- [GetArchivedThreadsOptions](../interfaces/GetArchivedThreadsOptions.md) +- [GetGuildAuditLogOptions](../interfaces/GetGuildAuditLogOptions.md) +- [GetGuildBansOptions](../interfaces/GetGuildBansOptions.md) +- [GetMessageReactionOptions](../interfaces/GetMessageReactionOptions.md) +- [GetMessagesOptions](../interfaces/GetMessagesOptions.md) +- [GetPruneOptions](../interfaces/GetPruneOptions.md) +- [GetRESTGuildMembersOptions](../interfaces/GetRESTGuildMembersOptions.md) +- [GetRESTGuildsOptions](../interfaces/GetRESTGuildsOptions.md) +- [GuildApplicationCommandPermissions](../interfaces/GuildApplicationCommandPermissions.md) +- [GuildAuditLog](../interfaces/GuildAuditLog.md) +- [GuildBan](../interfaces/GuildBan.md) +- [GuildOptions](../interfaces/GuildOptions.md) +- [GuildTemplateOptions](../interfaces/GuildTemplateOptions.md) +- [GuildTextable](../interfaces/GuildTextable.md) +- [GuildVanity](../interfaces/GuildVanity.md) +- [IntegrationOptions](../interfaces/IntegrationOptions.md) +- [InteractionApplicationCommandCallbackData](../interfaces/InteractionApplicationCommandCallbackData.md) +- [InteractionButton](../interfaces/InteractionButton.md) +- [InteractionResponse](../interfaces/InteractionResponse.md) +- [JSONCache](../interfaces/JSONCache.md) +- [JoinVoiceChannelOptions](../interfaces/JoinVoiceChannelOptions.md) +- [ListedChannelThreads](../interfaces/ListedChannelThreads.md) +- [ListedGuildThreads](../interfaces/ListedGuildThreads.md) +- [MemberOptions](../interfaces/MemberOptions.md) +- [MessageReferenceBase](../interfaces/MessageReferenceBase.md) +- [MessageReferenceReply](../interfaces/MessageReferenceReply.md) +- [OAuthApplicationInfo](../interfaces/OAuthApplicationInfo.md) +- [OAuthTeamInfo](../interfaces/OAuthTeamInfo.md) +- [OAuthTeamMember](../interfaces/OAuthTeamMember.md) +- [Overwrite](../interfaces/Overwrite.md) +- [ParsedClientOptions](../interfaces/ParsedClientOptions.md) +- [PartialChannel](../interfaces/PartialChannel.md) +- [PartialEmoji](../interfaces/PartialEmoji.md) +- [PartialRole](../interfaces/PartialRole.md) +- [PartialUser](../interfaces/PartialUser.md) +- [Pinnable](../interfaces/Pinnable.md) +- [PruneMemberOptions](../interfaces/PruneMemberOptions.md) +- [PurgeChannelOptions](../interfaces/PurgeChannelOptions.md) +- [RequestData](../interfaces/RequestData.md) +- [RequestGuildMembersOptions](../interfaces/RequestGuildMembersOptions.md) +- [RequestHandlerOptions](../interfaces/RequestHandlerOptions.md) +- [RequestMembersPromise](../interfaces/RequestMembersPromise.md) +- [RoleOptions](../interfaces/RoleOptions.md) +- [SelectMenu](../interfaces/SelectMenu.md) +- [SelectMenuOptions](../interfaces/SelectMenuOptions.md) +- [ShardManagerOptions](../interfaces/ShardManagerOptions.md) +- [SimpleJSON](../interfaces/SimpleJSON.md) +- [StageInstanceOptions](../interfaces/StageInstanceOptions.md) +- [Sticker](../interfaces/Sticker.md) +- [StickerItems](../interfaces/StickerItems.md) +- [StickerPack](../interfaces/StickerPack.md) +- [Textable](../interfaces/Textable.md) +- [ThreadTextable](../interfaces/ThreadTextable.md) +- [URLButton](../interfaces/URLButton.md) +- [Uncached](../interfaces/Uncached.md) +- [VoiceRegion](../interfaces/VoiceRegion.md) +- [VoiceStateOptions](../interfaces/VoiceStateOptions.md) +- [Webhook](../interfaces/Webhook.md) +- [WebhookOptions](../interfaces/WebhookOptions.md) +- [WebhookPayload](../interfaces/WebhookPayload.md) +- [WelcomeChannel](../interfaces/WelcomeChannel.md) +- [WelcomeScreen](../interfaces/WelcomeScreen.md) +- [WelcomeScreenOptions](../interfaces/WelcomeScreenOptions.md) +- [Widget](../interfaces/Widget.md) +- [WidgetChannel](../interfaces/WidgetChannel.md) +- [WidgetData](../interfaces/WidgetData.md) +- [WidgetMember](../interfaces/WidgetMember.md) + +### Type Aliases + +- [ActionRowComponents](md#actionrowcomponents) +- [ActivityType](md#activitytype) +- [AnyChannel](md#anychannel) +- [AnyGuildChannel](md#anyguildchannel) +- [AnyThreadChannel](md#anythreadchannel) +- [AnyVoiceChannel](md#anyvoicechannel) +- [ApiVersions](md#apiversions) +- [ApplicationCommandOptions](md#applicationcommandoptions) +- [ApplicationCommandOptionsBoolean](md#applicationcommandoptionsboolean) +- [ApplicationCommandOptionsChannel](md#applicationcommandoptionschannel) +- [ApplicationCommandOptionsInteger](md#applicationcommandoptionsinteger) +- [ApplicationCommandOptionsIntegerWithAutocomplete](md#applicationcommandoptionsintegerwithautocomplete) +- [ApplicationCommandOptionsIntegerWithMinMax](md#applicationcommandoptionsintegerwithminmax) +- [ApplicationCommandOptionsIntegerWithoutAutocomplete](md#applicationcommandoptionsintegerwithoutautocomplete) +- [ApplicationCommandOptionsMentionable](md#applicationcommandoptionsmentionable) +- [ApplicationCommandOptionsNumber](md#applicationcommandoptionsnumber) +- [ApplicationCommandOptionsNumberWithAutocomplete](md#applicationcommandoptionsnumberwithautocomplete) +- [ApplicationCommandOptionsNumberWithMinMax](md#applicationcommandoptionsnumberwithminmax) +- [ApplicationCommandOptionsNumberWithoutAutocomplete](md#applicationcommandoptionsnumberwithoutautocomplete) +- [ApplicationCommandOptionsRole](md#applicationcommandoptionsrole) +- [ApplicationCommandOptionsString](md#applicationcommandoptionsstring) +- [ApplicationCommandOptionsStringWithAutocomplete](md#applicationcommandoptionsstringwithautocomplete) +- [ApplicationCommandOptionsStringWithoutAutocomplete](md#applicationcommandoptionsstringwithoutautocomplete) +- [ApplicationCommandOptionsUser](md#applicationcommandoptionsuser) +- [ApplicationCommandOptionsWithValue](md#applicationcommandoptionswithvalue) +- [ApplicationCommandStructure](md#applicationcommandstructure) +- [AutoArchiveDuration](md#autoarchiveduration) +- [BigString](md#bigstring) +- [BotActivityType](md#botactivitytype) +- [Button](md#button) +- [ChatInputApplicationCommand](md#chatinputapplicationcommand) +- [ChatInputApplicationCommandStructure](md#chatinputapplicationcommandstructure) +- [GuildTextableChannel](md#guildtextablechannel) +- [ImageFormat](md#imageformat) +- [ImageSize](md#imagesize) +- [InteractionContent](md#interactioncontent) +- [InteractionContentEdit](md#interactioncontentedit) +- [MessageApplicationCommand](md#messageapplicationcommand) +- [MessageApplicationCommandStructure](md#messageapplicationcommandstructure) +- [MessageContent](md#messagecontent) +- [MessageContentEdit](md#messagecontentedit) +- [MessageWebhookContent](md#messagewebhookcontent) +- [PossiblyUncachedTextable](md#possiblyuncachedtextable) +- [RequestMethod](md#requestmethod) +- [SelfStatus](md#selfstatus) +- [Status](md#status) +- [TextVoiceChannelTypes](md#textvoicechanneltypes) +- [TextableChannel](md#textablechannel) +- [UserApplicationCommand](md#userapplicationcommand) +- [UserApplicationCommandStructure](md#userapplicationcommandstructure) +- [VideoQualityMode](md#videoqualitymode) + +### Variables + +- [CHANNELS](md#channels) +- [DISCOVERY\_CATEGORIES](md#discovery_categories) +- [DISCOVERY\_VALIDATION](md#discovery_validation) +- [GATEWAY](md#gateway) +- [GATEWAY\_BOT](md#gateway_bot) +- [GUILDS](md#guilds) +- [MessageFlags](md#messageflags) +- [STAGE\_INSTANCES](md#stage_instances) +- [STICKER\_PACKS](md#sticker_packs) +- [USERS](md#users) +- [VOICE\_REGIONS](md#voice_regions) + +### Functions + +- [ACHIEVEMENT\_ICON](md#achievement_icon) +- [APPLICATION\_ASSET](md#application_asset) +- [APPLICATION\_ICON](md#application_icon) +- [BANNER](md#banner) +- [CHANNEL](md#channel) +- [CHANNEL\_BULK\_DELETE](md#channel_bulk_delete) +- [CHANNEL\_CALL\_RING](md#channel_call_ring) +- [CHANNEL\_CROSSPOST](md#channel_crosspost) +- [CHANNEL\_FOLLOW](md#channel_follow) +- [CHANNEL\_ICON](md#channel_icon) +- [CHANNEL\_INVITES](md#channel_invites) +- [CHANNEL\_MESSAGE](md#channel_message) +- [CHANNEL\_MESSAGES](md#channel_messages) +- [CHANNEL\_MESSAGES\_SEARCH](md#channel_messages_search) +- [CHANNEL\_MESSAGE\_REACTION](md#channel_message_reaction) +- [CHANNEL\_MESSAGE\_REACTIONS](md#channel_message_reactions) +- [CHANNEL\_MESSAGE\_REACTION\_USER](md#channel_message_reaction_user) +- [CHANNEL\_PERMISSION](md#channel_permission) +- [CHANNEL\_PERMISSIONS](md#channel_permissions) +- [CHANNEL\_PIN](md#channel_pin) +- [CHANNEL\_PINS](md#channel_pins) +- [CHANNEL\_RECIPIENT](md#channel_recipient) +- [CHANNEL\_TYPING](md#channel_typing) +- [CHANNEL\_WEBHOOKS](md#channel_webhooks) +- [COMMAND](md#command) +- [COMMANDS](md#commands) +- [COMMAND\_PERMISSIONS](md#command_permissions) +- [CUSTOM\_EMOJI](md#custom_emoji) +- [CUSTOM\_EMOJI\_GUILD](md#custom_emoji_guild) +- [DEFAULT\_USER\_AVATAR](md#default_user_avatar) +- [GUILD](md#guild) +- [GUILD\_AUDIT\_LOGS](md#guild_audit_logs) +- [GUILD\_AVATAR](md#guild_avatar) +- [GUILD\_BAN](md#guild_ban) +- [GUILD\_BANS](md#guild_bans) +- [GUILD\_CHANNELS](md#guild_channels) +- [GUILD\_COMMAND](md#guild_command) +- [GUILD\_COMMANDS](md#guild_commands) +- [GUILD\_COMMAND\_PERMISSIONS](md#guild_command_permissions) +- [GUILD\_DISCOVERY](md#guild_discovery) +- [GUILD\_DISCOVERY\_CATEGORY](md#guild_discovery_category) +- [GUILD\_DISCOVERY\_SPLASH](md#guild_discovery_splash) +- [GUILD\_EMOJI](md#guild_emoji) +- [GUILD\_EMOJIS](md#guild_emojis) +- [GUILD\_ICON](md#guild_icon) +- [GUILD\_INTEGRATION](md#guild_integration) +- [GUILD\_INTEGRATIONS](md#guild_integrations) +- [GUILD\_INTEGRATION\_SYNC](md#guild_integration_sync) +- [GUILD\_INVITES](md#guild_invites) +- [GUILD\_MEMBER](md#guild_member) +- [GUILD\_MEMBERS](md#guild_members) +- [GUILD\_MEMBERS\_SEARCH](md#guild_members_search) +- [GUILD\_MEMBER\_NICK](md#guild_member_nick) +- [GUILD\_MEMBER\_ROLE](md#guild_member_role) +- [GUILD\_MESSAGES\_SEARCH](md#guild_messages_search) +- [GUILD\_PREVIEW](md#guild_preview) +- [GUILD\_PRUNE](md#guild_prune) +- [GUILD\_ROLE](md#guild_role) +- [GUILD\_ROLES](md#guild_roles) +- [GUILD\_SPLASH](md#guild_splash) +- [GUILD\_STICKER](md#guild_sticker) +- [GUILD\_STICKERS](md#guild_stickers) +- [GUILD\_TEMPLATE](md#guild_template) +- [GUILD\_TEMPLATES](md#guild_templates) +- [GUILD\_TEMPLATE\_GUILD](md#guild_template_guild) +- [GUILD\_VANITY\_URL](md#guild_vanity_url) +- [GUILD\_VOICE\_REGIONS](md#guild_voice_regions) +- [GUILD\_VOICE\_STATE](md#guild_voice_state) +- [GUILD\_WEBHOOKS](md#guild_webhooks) +- [GUILD\_WELCOME\_SCREEN](md#guild_welcome_screen) +- [GUILD\_WIDGET](md#guild_widget) +- [GUILD\_WIDGET\_SETTINGS](md#guild_widget_settings) +- [INTERACTION\_RESPOND](md#interaction_respond) +- [INVITE](md#invite) +- [MESSAGE\_LINK](md#message_link) +- [OAUTH2\_APPLICATION](md#oauth2_application) +- [ORIGINAL\_INTERACTION\_RESPONSE](md#original_interaction_response) +- [ROLE\_ICON](md#role_icon) +- [STAGE\_INSTANCE](md#stage_instance) +- [STICKER](md#sticker) +- [TEAM\_ICON](md#team_icon) +- [THREADS\_ACTIVE](md#threads_active) +- [THREADS\_ARCHIVED](md#threads_archived) +- [THREADS\_ARCHIVED\_JOINED](md#threads_archived_joined) +- [THREADS\_GUILD\_ACTIVE](md#threads_guild_active) +- [THREAD\_MEMBER](md#thread_member) +- [THREAD\_MEMBERS](md#thread_members) +- [THREAD\_WITHOUT\_MESSAGE](md#thread_without_message) +- [THREAD\_WITH\_MESSAGE](md#thread_with_message) +- [USER](md#user) +- [USER\_AVATAR](md#user_avatar) +- [USER\_BILLING](md#user_billing) +- [USER\_BILLING\_PAYMENTS](md#user_billing_payments) +- [USER\_BILLING\_PREMIUM\_SUBSCRIPTION](md#user_billing_premium_subscription) +- [USER\_CHANNELS](md#user_channels) +- [USER\_CONNECTIONS](md#user_connections) +- [USER\_CONNECTION\_PLATFORM](md#user_connection_platform) +- [USER\_GUILD](md#user_guild) +- [USER\_GUILDS](md#user_guilds) +- [USER\_MFA\_CODES](md#user_mfa_codes) +- [USER\_MFA\_TOTP\_DISABLE](md#user_mfa_totp_disable) +- [USER\_MFA\_TOTP\_ENABLE](md#user_mfa_totp_enable) +- [USER\_NOTE](md#user_note) +- [USER\_PROFILE](md#user_profile) +- [USER\_RELATIONSHIP](md#user_relationship) +- [USER\_SETTINGS](md#user_settings) +- [WEBHOOK](md#webhook) +- [WEBHOOK\_MESSAGE](md#webhook_message) +- [WEBHOOK\_SLACK](md#webhook_slack) +- [WEBHOOK\_TOKEN](md#webhook_token) +- [WEBHOOK\_TOKEN\_SLACK](md#webhook_token_slack) + +## References + +### default + +Renames and re-exports [Client](../classes/Client.md) + +## Type Aliases + +### ActionRowComponents + +Ƭ **ActionRowComponents**: [`Button`](md#button) \| [`SelectMenu`](../interfaces/SelectMenu.md) + +#### Defined in + +[packages/client/src/typings.ts:131](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/typings.ts#L131) + +___ + +### ActivityType + +Ƭ **ActivityType**: `ActivityTypes` + +#### Defined in + +[packages/client/src/typings.ts:135](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/typings.ts#L135) + +___ + +### AnyChannel + +Ƭ **AnyChannel**: [`AnyGuildChannel`](md#anyguildchannel) \| [`PrivateChannel`](../classes/PrivateChannel.md) \| [`PossiblyUncachedTextable`](md#possiblyuncachedtextable) + +#### Defined in + +[packages/client/src/typings.ts:120](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/typings.ts#L120) + +___ + +### AnyGuildChannel + +Ƭ **AnyGuildChannel**: [`GuildTextableChannel`](md#guildtextablechannel) \| [`AnyVoiceChannel`](md#anyvoicechannel) \| [`CategoryChannel`](../classes/CategoryChannel.md) \| [`AnyThreadChannel`](md#anythreadchannel) + +#### Defined in + +[packages/client/src/typings.ts:121](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/typings.ts#L121) + +___ + +### AnyThreadChannel + +Ƭ **AnyThreadChannel**: [`NewsThreadChannel`](../classes/NewsThreadChannel.md) \| [`PrivateThreadChannel`](../classes/PrivateThreadChannel.md) \| [`PublicThreadChannel`](../classes/PublicThreadChannel.md) + +#### Defined in + +[packages/client/src/typings.ts:122](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/typings.ts#L122) + +___ + +### AnyVoiceChannel + +Ƭ **AnyVoiceChannel**: [`TextVoiceChannel`](../classes/TextVoiceChannel.md) \| [`StageChannel`](../classes/StageChannel.md) + +#### Defined in + +[packages/client/src/typings.ts:123](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/typings.ts#L123) + +___ + +### ApiVersions + +Ƭ **ApiVersions**: ``10`` + +The API versions that are supported. + +#### Defined in + +[packages/client/src/Client.ts:2439](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Client.ts#L2439) + +___ + +### ApplicationCommandOptions + +Ƭ **ApplicationCommandOptions**: [`ApplicationCommandOptionsSubCommand`](../interfaces/ApplicationCommandOptionsSubCommand.md) \| [`ApplicationCommandOptionsSubCommandGroup`](../interfaces/ApplicationCommandOptionsSubCommandGroup.md) \| [`ApplicationCommandOptionsWithValue`](md#applicationcommandoptionswithvalue) + +#### Defined in + +[packages/client/src/typings.ts:48](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/typings.ts#L48) + +___ + +### ApplicationCommandOptionsBoolean + +Ƭ **ApplicationCommandOptionsBoolean**: [`ApplicationCommandOption`](../interfaces/ApplicationCommandOption.md)<`ApplicationCommandOptionTypes.Boolean`\> + +#### Defined in + +[packages/client/src/typings.ts:52](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/typings.ts#L52) + +___ + +### ApplicationCommandOptionsChannel + +Ƭ **ApplicationCommandOptionsChannel**: [`ApplicationCommandOption`](../interfaces/ApplicationCommandOption.md)<`ApplicationCommandOptionTypes.Channel`\> + +#### Defined in + +[packages/client/src/typings.ts:53](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/typings.ts#L53) + +___ + +### ApplicationCommandOptionsInteger + +Ƭ **ApplicationCommandOptionsInteger**: [`ApplicationCommandOptionsIntegerWithAutocomplete`](md#applicationcommandoptionsintegerwithautocomplete) \| [`ApplicationCommandOptionsIntegerWithoutAutocomplete`](md#applicationcommandoptionsintegerwithoutautocomplete) \| [`ApplicationCommandOptionsIntegerWithMinMax`](md#applicationcommandoptionsintegerwithminmax) + +#### Defined in + +[packages/client/src/typings.ts:54](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/typings.ts#L54) + +___ + +### ApplicationCommandOptionsIntegerWithAutocomplete + +Ƭ **ApplicationCommandOptionsIntegerWithAutocomplete**: `Omit`<[`ApplicationCommandOptionWithChoices`](../interfaces/ApplicationCommandOptionWithChoices.md)<`ApplicationCommandOptionTypes.Integer`\>, ``"choices"`` \| ``"min_value"`` \| ``"max_value"``\> & [`AutocompleteEnabled`](../interfaces/AutocompleteEnabled.md) + +#### Defined in + +[packages/client/src/typings.ts:58](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/typings.ts#L58) + +___ + +### ApplicationCommandOptionsIntegerWithMinMax + +Ƭ **ApplicationCommandOptionsIntegerWithMinMax**: `Omit`<[`ApplicationCommandOptionWithChoices`](../interfaces/ApplicationCommandOptionWithChoices.md)<`ApplicationCommandOptionTypes.Integer`\>, ``"choices"`` \| ``"autocomplete"``\> & [`AutocompleteDisabledIntegerMinMax`](../interfaces/AutocompleteDisabledIntegerMinMax.md) + +#### Defined in + +[packages/client/src/typings.ts:68](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/typings.ts#L68) + +___ + +### ApplicationCommandOptionsIntegerWithoutAutocomplete + +Ƭ **ApplicationCommandOptionsIntegerWithoutAutocomplete**: `Omit`<[`ApplicationCommandOptionWithChoices`](../interfaces/ApplicationCommandOptionWithChoices.md)<`ApplicationCommandOptionTypes.Integer`\>, ``"autocomplete"`` \| ``"min_value"`` \| ``"max_value"``\> & [`AutocompleteDisabledInteger`](../interfaces/AutocompleteDisabledInteger.md) + +#### Defined in + +[packages/client/src/typings.ts:63](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/typings.ts#L63) + +___ + +### ApplicationCommandOptionsMentionable + +Ƭ **ApplicationCommandOptionsMentionable**: [`ApplicationCommandOption`](../interfaces/ApplicationCommandOption.md)<`ApplicationCommandOptionTypes.Mentionable`\> + +#### Defined in + +[packages/client/src/typings.ts:73](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/typings.ts#L73) + +___ + +### ApplicationCommandOptionsNumber + +Ƭ **ApplicationCommandOptionsNumber**: [`ApplicationCommandOptionsNumberWithAutocomplete`](md#applicationcommandoptionsnumberwithautocomplete) \| [`ApplicationCommandOptionsNumberWithoutAutocomplete`](md#applicationcommandoptionsnumberwithoutautocomplete) \| [`ApplicationCommandOptionsNumberWithMinMax`](md#applicationcommandoptionsnumberwithminmax) + +#### Defined in + +[packages/client/src/typings.ts:74](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/typings.ts#L74) + +___ + +### ApplicationCommandOptionsNumberWithAutocomplete + +Ƭ **ApplicationCommandOptionsNumberWithAutocomplete**: `Omit`<[`ApplicationCommandOptionWithChoices`](../interfaces/ApplicationCommandOptionWithChoices.md)<`ApplicationCommandOptionTypes.Number`\>, ``"choices"`` \| ``"min_value"`` \| ``"max_value"``\> & [`AutocompleteEnabled`](../interfaces/AutocompleteEnabled.md) + +#### Defined in + +[packages/client/src/typings.ts:78](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/typings.ts#L78) + +___ + +### ApplicationCommandOptionsNumberWithMinMax + +Ƭ **ApplicationCommandOptionsNumberWithMinMax**: `Omit`<[`ApplicationCommandOptionWithChoices`](../interfaces/ApplicationCommandOptionWithChoices.md)<`ApplicationCommandOptionTypes.Number`\>, ``"choices"`` \| ``"autocomplete"``\> & [`AutocompleteDisabledIntegerMinMax`](../interfaces/AutocompleteDisabledIntegerMinMax.md) + +#### Defined in + +[packages/client/src/typings.ts:88](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/typings.ts#L88) + +___ + +### ApplicationCommandOptionsNumberWithoutAutocomplete + +Ƭ **ApplicationCommandOptionsNumberWithoutAutocomplete**: `Omit`<[`ApplicationCommandOptionWithChoices`](../interfaces/ApplicationCommandOptionWithChoices.md)<`ApplicationCommandOptionTypes.Number`\>, ``"autocomplete"`` \| ``"min_value"`` \| ``"max_value"``\> & [`AutocompleteDisabledInteger`](../interfaces/AutocompleteDisabledInteger.md) + +#### Defined in + +[packages/client/src/typings.ts:83](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/typings.ts#L83) + +___ + +### ApplicationCommandOptionsRole + +Ƭ **ApplicationCommandOptionsRole**: [`ApplicationCommandOption`](../interfaces/ApplicationCommandOption.md)<`ApplicationCommandOptionTypes.Role`\> + +#### Defined in + +[packages/client/src/typings.ts:93](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/typings.ts#L93) + +___ + +### ApplicationCommandOptionsString + +Ƭ **ApplicationCommandOptionsString**: [`ApplicationCommandOptionsStringWithAutocomplete`](md#applicationcommandoptionsstringwithautocomplete) \| [`ApplicationCommandOptionsStringWithoutAutocomplete`](md#applicationcommandoptionsstringwithoutautocomplete) + +#### Defined in + +[packages/client/src/typings.ts:94](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/typings.ts#L94) + +___ + +### ApplicationCommandOptionsStringWithAutocomplete + +Ƭ **ApplicationCommandOptionsStringWithAutocomplete**: `Omit`<[`ApplicationCommandOptionWithChoices`](../interfaces/ApplicationCommandOptionWithChoices.md)<`ApplicationCommandOptionTypes.String`\>, ``"choices"``\> & [`AutocompleteEnabled`](../interfaces/AutocompleteEnabled.md) + +#### Defined in + +[packages/client/src/typings.ts:95](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/typings.ts#L95) + +___ + +### ApplicationCommandOptionsStringWithoutAutocomplete + +Ƭ **ApplicationCommandOptionsStringWithoutAutocomplete**: `Omit`<[`ApplicationCommandOptionWithChoices`](../interfaces/ApplicationCommandOptionWithChoices.md)<`ApplicationCommandOptionTypes.String`\>, ``"autocomplete"``\> & [`AutocompleteDisabled`](../interfaces/AutocompleteDisabled.md) + +#### Defined in + +[packages/client/src/typings.ts:100](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/typings.ts#L100) + +___ + +### ApplicationCommandOptionsUser + +Ƭ **ApplicationCommandOptionsUser**: [`ApplicationCommandOption`](../interfaces/ApplicationCommandOption.md)<`ApplicationCommandOptionTypes.User`\> + +#### Defined in + +[packages/client/src/typings.ts:105](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/typings.ts#L105) + +___ + +### ApplicationCommandOptionsWithValue + +Ƭ **ApplicationCommandOptionsWithValue**: [`ApplicationCommandOptionsString`](md#applicationcommandoptionsstring) \| [`ApplicationCommandOptionsInteger`](md#applicationcommandoptionsinteger) \| [`ApplicationCommandOptionsBoolean`](md#applicationcommandoptionsboolean) \| [`ApplicationCommandOptionsUser`](md#applicationcommandoptionsuser) \| [`ApplicationCommandOptionsChannel`](md#applicationcommandoptionschannel) \| [`ApplicationCommandOptionsRole`](md#applicationcommandoptionsrole) \| [`ApplicationCommandOptionsMentionable`](md#applicationcommandoptionsmentionable) \| [`ApplicationCommandOptionsNumber`](md#applicationcommandoptionsnumber) + +#### Defined in + +[packages/client/src/typings.ts:106](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/typings.ts#L106) + +___ + +### ApplicationCommandStructure + +Ƭ **ApplicationCommandStructure**: [`ChatInputApplicationCommandStructure`](md#chatinputapplicationcommandstructure) \| [`MessageApplicationCommandStructure`](md#messageapplicationcommandstructure) \| [`UserApplicationCommandStructure`](md#userapplicationcommandstructure) + +#### Defined in + +[packages/client/src/typings.ts:41](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/typings.ts#L41) + +___ + +### AutoArchiveDuration + +Ƭ **AutoArchiveDuration**: ``60`` \| ``1440`` \| ``4320`` \| ``10080`` + +#### Defined in + +[packages/client/src/typings.ts:139](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/typings.ts#L139) + +___ + +### BigString + +Ƭ **BigString**: `bigint` \| `string` + +A union type of string or bigint to help make it easier for users to switch between one another. + +#### Defined in + +[packages/client/src/Client.ts:2437](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Client.ts#L2437) + +___ + +### BotActivityType + +Ƭ **BotActivityType**: `Exclude`<`ActivityTypes`, `ActivityTypes.Custom`\> + +#### Defined in + +[packages/client/src/typings.ts:136](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/typings.ts#L136) + +___ + +### Button + +Ƭ **Button**: [`InteractionButton`](../interfaces/InteractionButton.md) \| [`URLButton`](../interfaces/URLButton.md) + +#### Defined in + +[packages/client/src/typings.ts:132](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/typings.ts#L132) + +___ + +### ChatInputApplicationCommand + +Ƭ **ChatInputApplicationCommand**: [`ApplicationCommand`](../interfaces/ApplicationCommand.md)<`ApplicationCommandTypes.ChatInput`\> + +#### Defined in + +[packages/client/src/typings.ts:42](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/typings.ts#L42) + +___ + +### ChatInputApplicationCommandStructure + +Ƭ **ChatInputApplicationCommandStructure**: `Omit`<[`ChatInputApplicationCommand`](md#chatinputapplicationcommand), ``"id"`` \| ``"application_id"`` \| ``"guild_id"``\> + +#### Defined in + +[packages/client/src/typings.ts:43](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/typings.ts#L43) + +___ + +### GuildTextableChannel + +Ƭ **GuildTextableChannel**: [`TextChannel`](../classes/TextChannel.md) \| [`TextVoiceChannel`](../classes/TextVoiceChannel.md) \| [`NewsChannel`](../classes/NewsChannel.md) + +#### Defined in + +[packages/client/src/typings.ts:124](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/typings.ts#L124) + +___ + +### ImageFormat + +Ƭ **ImageFormat**: ``"jpg"`` \| ``"jpeg"`` \| ``"png"`` \| ``"webp"`` \| ``"gif"`` + +The formats for images that are supported. + +#### Defined in + +[packages/client/src/Client.ts:2443](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Client.ts#L2443) + +___ + +### ImageSize + +Ƭ **ImageSize**: ``16`` \| ``32`` \| ``64`` \| ``128`` \| ``256`` \| ``512`` \| ``1024`` \| ``2048`` \| ``4096`` + +The sizes for images that are supported. + +#### Defined in + +[packages/client/src/Client.ts:2441](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Client.ts#L2441) + +___ + +### InteractionContent + +Ƭ **InteractionContent**: `Pick`<[`WebhookPayload`](../interfaces/WebhookPayload.md), ``"content"`` \| ``"embeds"`` \| ``"allowedMentions"`` \| ``"tts"`` \| ``"flags"`` \| ``"components"`` \| ``"file"``\> + +#### Defined in + +[packages/client/src/typings.ts:129](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/typings.ts#L129) + +___ + +### InteractionContentEdit + +Ƭ **InteractionContentEdit**: `Pick`<[`WebhookPayload`](../interfaces/WebhookPayload.md), ``"content"`` \| ``"embeds"`` \| ``"allowedMentions"`` \| ``"components"`` \| ``"file"``\> + +#### Defined in + +[packages/client/src/typings.ts:130](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/typings.ts#L130) + +___ + +### MessageApplicationCommand + +Ƭ **MessageApplicationCommand**: `Omit`<[`ApplicationCommand`](../interfaces/ApplicationCommand.md)<`ApplicationCommandTypes.Message`\>, ``"description"`` \| ``"options"``\> + +#### Defined in + +[packages/client/src/typings.ts:44](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/typings.ts#L44) + +___ + +### MessageApplicationCommandStructure + +Ƭ **MessageApplicationCommandStructure**: `Omit`<[`MessageApplicationCommand`](md#messageapplicationcommand), ``"id"`` \| ``"application_id"`` \| ``"guild_id"``\> + +#### Defined in + +[packages/client/src/typings.ts:45](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/typings.ts#L45) + +___ + +### MessageContent + +Ƭ **MessageContent**: `string` \| [`AdvancedMessageContent`](../interfaces/AdvancedMessageContent.md) + +#### Defined in + +[packages/client/src/typings.ts:133](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/typings.ts#L133) + +___ + +### MessageContentEdit + +Ƭ **MessageContentEdit**: `string` \| [`AdvancedMessageContentEdit`](../interfaces/AdvancedMessageContentEdit.md) + +#### Defined in + +[packages/client/src/typings.ts:134](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/typings.ts#L134) + +___ + +### MessageWebhookContent + +Ƭ **MessageWebhookContent**: `Pick`<[`WebhookPayload`](../interfaces/WebhookPayload.md), ``"content"`` \| ``"embeds"`` \| ``"file"`` \| ``"allowedMentions"`` \| ``"components"``\> + +#### Defined in + +[packages/client/src/typings.ts:140](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/typings.ts#L140) + +___ + +### PossiblyUncachedTextable + +Ƭ **PossiblyUncachedTextable**: [`Textable`](../interfaces/Textable.md) \| [`Uncached`](../interfaces/Uncached.md) + +#### Defined in + +[packages/client/src/typings.ts:125](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/typings.ts#L125) + +___ + +### RequestMethod + +Ƭ **RequestMethod**: ``"GET"`` \| ``"POST"`` \| ``"PUT"`` \| ``"DELETE"`` \| ``"PATCH"`` + +The methods that are acceptable for REST. + +#### Defined in + +[packages/client/src/Client.ts:2445](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Client.ts#L2445) + +___ + +### SelfStatus + +Ƭ **SelfStatus**: [`Status`](md#status) \| ``"invisible"`` + +#### Defined in + +[packages/client/src/typings.ts:138](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/typings.ts#L138) + +___ + +### Status + +Ƭ **Status**: ``"online"`` \| ``"idle"`` \| ``"dnd"`` + +#### Defined in + +[packages/client/src/typings.ts:137](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/typings.ts#L137) + +___ + +### TextVoiceChannelTypes + +Ƭ **TextVoiceChannelTypes**: `ChannelTypes.GuildVoice` \| `ChannelTypes.GuildStageVoice` + +#### Defined in + +[packages/client/src/typings.ts:128](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/typings.ts#L128) + +___ + +### TextableChannel + +Ƭ **TextableChannel**: [`GuildTextable`](../interfaces/GuildTextable.md) & [`GuildTextableChannel`](md#guildtextablechannel) \| [`ThreadTextable`](../interfaces/ThreadTextable.md) & [`AnyThreadChannel`](md#anythreadchannel) \| [`Textable`](../interfaces/Textable.md) & [`PrivateChannel`](../classes/PrivateChannel.md) + +#### Defined in + +[packages/client/src/typings.ts:126](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/typings.ts#L126) + +___ + +### UserApplicationCommand + +Ƭ **UserApplicationCommand**: `Omit`<[`ApplicationCommand`](../interfaces/ApplicationCommand.md)<`ApplicationCommandTypes.User`\>, ``"description"`` \| ``"options"``\> + +#### Defined in + +[packages/client/src/typings.ts:46](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/typings.ts#L46) + +___ + +### UserApplicationCommandStructure + +Ƭ **UserApplicationCommandStructure**: `Omit`<[`UserApplicationCommand`](md#userapplicationcommand), ``"id"`` \| ``"application_id"`` \| ``"guild_id"``\> + +#### Defined in + +[packages/client/src/typings.ts:47](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/typings.ts#L47) + +___ + +### VideoQualityMode + +Ƭ **VideoQualityMode**: `VideoQualityModes.Auto` \| `VideoQualityModes.Full` + +#### Defined in + +[packages/client/src/typings.ts:127](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/typings.ts#L127) + +## Variables + +### CHANNELS + +• `Const` **CHANNELS**: ``"/channels"`` + +#### Defined in + +[packages/client/src/Endpoints.ts:30](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L30) + +___ + +### DISCOVERY\_CATEGORIES + +• `Const` **DISCOVERY\_CATEGORIES**: ``"/discovery/categories"`` + +#### Defined in + +[packages/client/src/Endpoints.ts:32](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L32) + +___ + +### DISCOVERY\_VALIDATION + +• `Const` **DISCOVERY\_VALIDATION**: ``"/discovery/valid-term"`` + +#### Defined in + +[packages/client/src/Endpoints.ts:33](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L33) + +___ + +### GATEWAY + +• `Const` **GATEWAY**: ``"/gateway"`` + +#### Defined in + +[packages/client/src/Endpoints.ts:34](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L34) + +___ + +### GATEWAY\_BOT + +• `Const` **GATEWAY\_BOT**: ``"/gateway/bot"`` + +#### Defined in + +[packages/client/src/Endpoints.ts:35](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L35) + +___ + +### GUILDS + +• `Const` **GUILDS**: ``"/guilds"`` + +#### Defined in + +[packages/client/src/Endpoints.ts:77](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L77) + +___ + +### MessageFlags + +• `Const` **MessageFlags**: `Object` + +#### Type declaration + +| Name | Type | +| :------ | :------ | +| `CROSSPOSTED` | `number` | +| `EPHEMERAL` | `number` | +| `HAS_THREAD` | `number` | +| `IS_CROSSPOST` | `number` | +| `LOADING` | `number` | +| `SOURCE_MESSAGE_DELETED` | `number` | +| `SUPPRESS_EMBEDS` | `number` | +| `URGENT` | `number` | + +#### Defined in + +[packages/client/src/typings.ts:878](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/typings.ts#L878) + +___ + +### STAGE\_INSTANCES + +• `Const` **STAGE\_INSTANCES**: ``"/stage-instances"`` + +#### Defined in + +[packages/client/src/Endpoints.ts:82](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L82) + +___ + +### STICKER\_PACKS + +• `Const` **STICKER\_PACKS**: ``"/sticker-packs"`` + +#### Defined in + +[packages/client/src/Endpoints.ts:84](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L84) + +___ + +### USERS + +• `Const` **USERS**: ``"/users"`` + +#### Defined in + +[packages/client/src/Endpoints.ts:109](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L109) + +___ + +### VOICE\_REGIONS + +• `Const` **VOICE\_REGIONS**: ``"/voice/regions"`` + +#### Defined in + +[packages/client/src/Endpoints.ts:110](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L110) + +## Functions + +### ACHIEVEMENT\_ICON + +▸ **ACHIEVEMENT_ICON**(`applicationID`, `achievementID`, `icon`): `string` + +CDN Endpoints + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `applicationID` | [`BigString`](md#bigstring) | +| `achievementID` | [`BigString`](md#bigstring) | +| `icon` | `string` | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:118](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L118) + +___ + +### APPLICATION\_ASSET + +▸ **APPLICATION_ASSET**(`applicationID`, `asset`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `applicationID` | [`BigString`](md#bigstring) | +| `asset` | `string` | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:120](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L120) + +___ + +### APPLICATION\_ICON + +▸ **APPLICATION_ICON**(`applicationID`, `icon`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `applicationID` | [`BigString`](md#bigstring) | +| `icon` | `string` | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:121](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L121) + +___ + +### BANNER + +▸ **BANNER**(`guildOrUserID`, `hash`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `guildOrUserID` | [`BigString`](md#bigstring) | +| `hash` | `string` | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:122](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L122) + +___ + +### CHANNEL + +▸ **CHANNEL**(`chanID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `chanID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:9](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L9) + +___ + +### CHANNEL\_BULK\_DELETE + +▸ **CHANNEL_BULK_DELETE**(`chanID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `chanID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:10](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L10) + +___ + +### CHANNEL\_CALL\_RING + +▸ **CHANNEL_CALL_RING**(`chanID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `chanID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:11](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L11) + +___ + +### CHANNEL\_CROSSPOST + +▸ **CHANNEL_CROSSPOST**(`chanID`, `msgID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `chanID` | [`BigString`](md#bigstring) | +| `msgID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:12](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L12) + +___ + +### CHANNEL\_FOLLOW + +▸ **CHANNEL_FOLLOW**(`chanID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `chanID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:13](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L13) + +___ + +### CHANNEL\_ICON + +▸ **CHANNEL_ICON**(`chanID`, `chanIcon`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `chanID` | [`BigString`](md#bigstring) | +| `chanIcon` | `string` | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:123](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L123) + +___ + +### CHANNEL\_INVITES + +▸ **CHANNEL_INVITES**(`chanID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `chanID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:14](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L14) + +___ + +### CHANNEL\_MESSAGE + +▸ **CHANNEL_MESSAGE**(`chanID`, `msgID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `chanID` | [`BigString`](md#bigstring) | +| `msgID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:20](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L20) + +___ + +### CHANNEL\_MESSAGES + +▸ **CHANNEL_MESSAGES**(`chanID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `chanID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:21](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L21) + +___ + +### CHANNEL\_MESSAGES\_SEARCH + +▸ **CHANNEL_MESSAGES_SEARCH**(`chanID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `chanID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:22](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L22) + +___ + +### CHANNEL\_MESSAGE\_REACTION + +▸ **CHANNEL_MESSAGE_REACTION**(`chanID`, `msgID`, `reaction`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `chanID` | [`BigString`](md#bigstring) | +| `msgID` | [`BigString`](md#bigstring) | +| `reaction` | `string` | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:15](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L15) + +___ + +### CHANNEL\_MESSAGE\_REACTIONS + +▸ **CHANNEL_MESSAGE_REACTIONS**(`chanID`, `msgID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `chanID` | [`BigString`](md#bigstring) | +| `msgID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:19](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L19) + +___ + +### CHANNEL\_MESSAGE\_REACTION\_USER + +▸ **CHANNEL_MESSAGE_REACTION_USER**(`chanID`, `msgID`, `reaction`, `userID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `chanID` | [`BigString`](md#bigstring) | +| `msgID` | [`BigString`](md#bigstring) | +| `reaction` | `string` | +| `userID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:17](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L17) + +___ + +### CHANNEL\_PERMISSION + +▸ **CHANNEL_PERMISSION**(`chanID`, `overID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `chanID` | [`BigString`](md#bigstring) | +| `overID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:23](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L23) + +___ + +### CHANNEL\_PERMISSIONS + +▸ **CHANNEL_PERMISSIONS**(`chanID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `chanID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:24](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L24) + +___ + +### CHANNEL\_PIN + +▸ **CHANNEL_PIN**(`chanID`, `msgID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `chanID` | [`BigString`](md#bigstring) | +| `msgID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:25](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L25) + +___ + +### CHANNEL\_PINS + +▸ **CHANNEL_PINS**(`chanID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `chanID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:26](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L26) + +___ + +### CHANNEL\_RECIPIENT + +▸ **CHANNEL_RECIPIENT**(`groupID`, `userID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `groupID` | [`BigString`](md#bigstring) | +| `userID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:27](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L27) + +___ + +### CHANNEL\_TYPING + +▸ **CHANNEL_TYPING**(`chanID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `chanID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:28](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L28) + +___ + +### CHANNEL\_WEBHOOKS + +▸ **CHANNEL_WEBHOOKS**(`chanID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `chanID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:29](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L29) + +___ + +### COMMAND + +▸ **COMMAND**(`applicationID`, `commandID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `applicationID` | [`BigString`](md#bigstring) | +| `commandID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:5](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L5) + +___ + +### COMMANDS + +▸ **COMMANDS**(`applicationID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `applicationID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:6](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L6) + +___ + +### COMMAND\_PERMISSIONS + +▸ **COMMAND_PERMISSIONS**(`applicationID`, `guildID`, `commandID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `applicationID` | [`BigString`](md#bigstring) | +| `guildID` | [`BigString`](md#bigstring) | +| `commandID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:7](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L7) + +___ + +### CUSTOM\_EMOJI + +▸ **CUSTOM_EMOJI**(`emojiID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `emojiID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:124](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L124) + +___ + +### CUSTOM\_EMOJI\_GUILD + +▸ **CUSTOM_EMOJI_GUILD**(`emojiID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `emojiID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:31](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L31) + +___ + +### DEFAULT\_USER\_AVATAR + +▸ **DEFAULT_USER_AVATAR**(`userDiscriminator`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `userDiscriminator` | `string` | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:125](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L125) + +___ + +### GUILD + +▸ **GUILD**(`guildID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `guildID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:36](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L36) + +___ + +### GUILD\_AUDIT\_LOGS + +▸ **GUILD_AUDIT_LOGS**(`guildID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `guildID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:37](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L37) + +___ + +### GUILD\_AVATAR + +▸ **GUILD_AVATAR**(`guildID`, `userID`, `guildAvatar`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `guildID` | [`BigString`](md#bigstring) | +| `userID` | [`BigString`](md#bigstring) | +| `guildAvatar` | `string` | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:126](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L126) + +___ + +### GUILD\_BAN + +▸ **GUILD_BAN**(`guildID`, `memberID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `guildID` | [`BigString`](md#bigstring) | +| `memberID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:38](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L38) + +___ + +### GUILD\_BANS + +▸ **GUILD_BANS**(`guildID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `guildID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:39](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L39) + +___ + +### GUILD\_CHANNELS + +▸ **GUILD_CHANNELS**(`guildID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `guildID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:40](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L40) + +___ + +### GUILD\_COMMAND + +▸ **GUILD_COMMAND**(`applicationID`, `guildID`, `commandID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `applicationID` | [`BigString`](md#bigstring) | +| `guildID` | [`BigString`](md#bigstring) | +| `commandID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:41](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L41) + +___ + +### GUILD\_COMMANDS + +▸ **GUILD_COMMANDS**(`applicationID`, `guildID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `applicationID` | [`BigString`](md#bigstring) | +| `guildID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:45](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L45) + +___ + +### GUILD\_COMMAND\_PERMISSIONS + +▸ **GUILD_COMMAND_PERMISSIONS**(`applicationID`, `guildID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `applicationID` | [`BigString`](md#bigstring) | +| `guildID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:43](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L43) + +___ + +### GUILD\_DISCOVERY + +▸ **GUILD_DISCOVERY**(`guildID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `guildID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:46](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L46) + +___ + +### GUILD\_DISCOVERY\_CATEGORY + +▸ **GUILD_DISCOVERY_CATEGORY**(`guildID`, `categoryID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `guildID` | [`BigString`](md#bigstring) | +| `categoryID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:47](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L47) + +___ + +### GUILD\_DISCOVERY\_SPLASH + +▸ **GUILD_DISCOVERY_SPLASH**(`guildID`, `guildDiscoverySplash`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `guildID` | [`BigString`](md#bigstring) | +| `guildDiscoverySplash` | `string` | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:128](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L128) + +___ + +### GUILD\_EMOJI + +▸ **GUILD_EMOJI**(`guildID`, `emojiID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `guildID` | [`BigString`](md#bigstring) | +| `emojiID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:48](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L48) + +___ + +### GUILD\_EMOJIS + +▸ **GUILD_EMOJIS**(`guildID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `guildID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:49](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L49) + +___ + +### GUILD\_ICON + +▸ **GUILD_ICON**(`guildID`, `guildIcon`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `guildID` | [`BigString`](md#bigstring) | +| `guildIcon` | `string` | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:129](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L129) + +___ + +### GUILD\_INTEGRATION + +▸ **GUILD_INTEGRATION**(`guildID`, `inteID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `guildID` | [`BigString`](md#bigstring) | +| `inteID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:50](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L50) + +___ + +### GUILD\_INTEGRATIONS + +▸ **GUILD_INTEGRATIONS**(`guildID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `guildID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:52](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L52) + +___ + +### GUILD\_INTEGRATION\_SYNC + +▸ **GUILD_INTEGRATION_SYNC**(`guildID`, `inteID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `guildID` | [`BigString`](md#bigstring) | +| `inteID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:51](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L51) + +___ + +### GUILD\_INVITES + +▸ **GUILD_INVITES**(`guildID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `guildID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:53](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L53) + +___ + +### GUILD\_MEMBER + +▸ **GUILD_MEMBER**(`guildID`, `memberID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `guildID` | [`BigString`](md#bigstring) | +| `memberID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:55](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L55) + +___ + +### GUILD\_MEMBERS + +▸ **GUILD_MEMBERS**(`guildID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `guildID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:59](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L59) + +___ + +### GUILD\_MEMBERS\_SEARCH + +▸ **GUILD_MEMBERS_SEARCH**(`guildID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `guildID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:60](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L60) + +___ + +### GUILD\_MEMBER\_NICK + +▸ **GUILD_MEMBER_NICK**(`guildID`, `memberID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `guildID` | [`BigString`](md#bigstring) | +| `memberID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:56](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L56) + +___ + +### GUILD\_MEMBER\_ROLE + +▸ **GUILD_MEMBER_ROLE**(`guildID`, `memberID`, `roleID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `guildID` | [`BigString`](md#bigstring) | +| `memberID` | [`BigString`](md#bigstring) | +| `roleID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:57](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L57) + +___ + +### GUILD\_MESSAGES\_SEARCH + +▸ **GUILD_MESSAGES_SEARCH**(`guildID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `guildID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:61](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L61) + +___ + +### GUILD\_PREVIEW + +▸ **GUILD_PREVIEW**(`guildID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `guildID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:62](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L62) + +___ + +### GUILD\_PRUNE + +▸ **GUILD_PRUNE**(`guildID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `guildID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:63](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L63) + +___ + +### GUILD\_ROLE + +▸ **GUILD_ROLE**(`guildID`, `roleID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `guildID` | [`BigString`](md#bigstring) | +| `roleID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:64](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L64) + +___ + +### GUILD\_ROLES + +▸ **GUILD_ROLES**(`guildID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `guildID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:65](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L65) + +___ + +### GUILD\_SPLASH + +▸ **GUILD_SPLASH**(`guildID`, `guildSplash`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `guildID` | [`BigString`](md#bigstring) | +| `guildSplash` | `string` | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:130](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L130) + +___ + +### GUILD\_STICKER + +▸ **GUILD_STICKER**(`guildID`, `stickerID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `guildID` | [`BigString`](md#bigstring) | +| `stickerID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:66](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L66) + +___ + +### GUILD\_STICKERS + +▸ **GUILD_STICKERS**(`guildID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `guildID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:67](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L67) + +___ + +### GUILD\_TEMPLATE + +▸ **GUILD_TEMPLATE**(`code`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `code` | `string` | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:68](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L68) + +___ + +### GUILD\_TEMPLATES + +▸ **GUILD_TEMPLATES**(`guildID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `guildID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:69](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L69) + +___ + +### GUILD\_TEMPLATE\_GUILD + +▸ **GUILD_TEMPLATE_GUILD**(`guildID`, `code`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `guildID` | [`BigString`](md#bigstring) | +| `code` | `string` | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:70](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L70) + +___ + +### GUILD\_VANITY\_URL + +▸ **GUILD_VANITY_URL**(`guildID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `guildID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:54](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L54) + +___ + +### GUILD\_VOICE\_REGIONS + +▸ **GUILD_VOICE_REGIONS**(`guildID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `guildID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:71](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L71) + +___ + +### GUILD\_VOICE\_STATE + +▸ **GUILD_VOICE_STATE**(`guildID`, `user`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `guildID` | [`BigString`](md#bigstring) | +| `user` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:76](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L76) + +___ + +### GUILD\_WEBHOOKS + +▸ **GUILD_WEBHOOKS**(`guildID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `guildID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:72](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L72) + +___ + +### GUILD\_WELCOME\_SCREEN + +▸ **GUILD_WELCOME_SCREEN**(`guildID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `guildID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:73](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L73) + +___ + +### GUILD\_WIDGET + +▸ **GUILD_WIDGET**(`guildID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `guildID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:74](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L74) + +___ + +### GUILD\_WIDGET\_SETTINGS + +▸ **GUILD_WIDGET_SETTINGS**(`guildID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `guildID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:75](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L75) + +___ + +### INTERACTION\_RESPOND + +▸ **INTERACTION_RESPOND**(`interactID`, `interactToken`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `interactID` | [`BigString`](md#bigstring) | +| `interactToken` | `string` | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:78](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L78) + +___ + +### INVITE + +▸ **INVITE**(`inviteID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `inviteID` | `string` | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:79](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L79) + +___ + +### MESSAGE\_LINK + +▸ **MESSAGE_LINK**(`guildID`, `channelID`, `messageID`): `string` + +Client Endpoints + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `guildID` | [`BigString`](md#bigstring) | +| `channelID` | [`BigString`](md#bigstring) | +| `messageID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:136](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L136) + +___ + +### OAUTH2\_APPLICATION + +▸ **OAUTH2_APPLICATION**(`appID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `appID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:80](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L80) + +___ + +### ORIGINAL\_INTERACTION\_RESPONSE + +▸ **ORIGINAL_INTERACTION_RESPONSE**(`appID`, `interactToken`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `appID` | [`BigString`](md#bigstring) | +| `interactToken` | `string` | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:4](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L4) + +___ + +### ROLE\_ICON + +▸ **ROLE_ICON**(`roleID`, `roleIcon`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `roleID` | [`BigString`](md#bigstring) | +| `roleIcon` | `string` | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:131](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L131) + +___ + +### STAGE\_INSTANCE + +▸ **STAGE_INSTANCE**(`channelID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `channelID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:81](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L81) + +___ + +### STICKER + +▸ **STICKER**(`stickerID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `stickerID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:83](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L83) + +___ + +### TEAM\_ICON + +▸ **TEAM_ICON**(`teamID`, `teamIcon`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `teamID` | [`BigString`](md#bigstring) | +| `teamIcon` | `string` | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:132](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L132) + +___ + +### THREADS\_ACTIVE + +▸ **THREADS_ACTIVE**(`channelID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `channelID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:89](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L89) + +___ + +### THREADS\_ARCHIVED + +▸ **THREADS_ARCHIVED**(`channelID`, `type`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `channelID` | [`BigString`](md#bigstring) | +| `type` | `string` | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:90](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L90) + +___ + +### THREADS\_ARCHIVED\_JOINED + +▸ **THREADS_ARCHIVED_JOINED**(`channelID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `channelID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:91](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L91) + +___ + +### THREADS\_GUILD\_ACTIVE + +▸ **THREADS_GUILD_ACTIVE**(`guildID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `guildID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:92](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L92) + +___ + +### THREAD\_MEMBER + +▸ **THREAD_MEMBER**(`channelID`, `userID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `channelID` | [`BigString`](md#bigstring) | +| `userID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:85](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L85) + +___ + +### THREAD\_MEMBERS + +▸ **THREAD_MEMBERS**(`channelID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `channelID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:86](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L86) + +___ + +### THREAD\_WITHOUT\_MESSAGE + +▸ **THREAD_WITHOUT_MESSAGE**(`channelID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `channelID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:88](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L88) + +___ + +### THREAD\_WITH\_MESSAGE + +▸ **THREAD_WITH_MESSAGE**(`channelID`, `msgID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `channelID` | [`BigString`](md#bigstring) | +| `msgID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:87](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L87) + +___ + +### USER + +▸ **USER**(`userID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `userID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:93](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L93) + +___ + +### USER\_AVATAR + +▸ **USER_AVATAR**(`userID`, `userAvatar`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `userID` | [`BigString`](md#bigstring) | +| `userAvatar` | `string` | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:133](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L133) + +___ + +### USER\_BILLING + +▸ **USER_BILLING**(`userID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `userID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:94](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L94) + +___ + +### USER\_BILLING\_PAYMENTS + +▸ **USER_BILLING_PAYMENTS**(`userID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `userID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:95](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L95) + +___ + +### USER\_BILLING\_PREMIUM\_SUBSCRIPTION + +▸ **USER_BILLING_PREMIUM_SUBSCRIPTION**(`userID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `userID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:96](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L96) + +___ + +### USER\_CHANNELS + +▸ **USER_CHANNELS**(`userID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `userID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:97](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L97) + +___ + +### USER\_CONNECTIONS + +▸ **USER_CONNECTIONS**(`userID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `userID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:98](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L98) + +___ + +### USER\_CONNECTION\_PLATFORM + +▸ **USER_CONNECTION_PLATFORM**(`userID`, `platform`, `id`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `userID` | [`BigString`](md#bigstring) | +| `platform` | `string` | +| `id` | `string` | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:99](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L99) + +___ + +### USER\_GUILD + +▸ **USER_GUILD**(`userID`, `guildID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `userID` | [`BigString`](md#bigstring) | +| `guildID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:100](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L100) + +___ + +### USER\_GUILDS + +▸ **USER_GUILDS**(`userID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `userID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:101](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L101) + +___ + +### USER\_MFA\_CODES + +▸ **USER_MFA_CODES**(`userID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `userID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:102](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L102) + +___ + +### USER\_MFA\_TOTP\_DISABLE + +▸ **USER_MFA_TOTP_DISABLE**(`userID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `userID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:103](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L103) + +___ + +### USER\_MFA\_TOTP\_ENABLE + +▸ **USER_MFA_TOTP_ENABLE**(`userID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `userID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:104](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L104) + +___ + +### USER\_NOTE + +▸ **USER_NOTE**(`userID`, `targetID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `userID` | [`BigString`](md#bigstring) | +| `targetID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:105](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L105) + +___ + +### USER\_PROFILE + +▸ **USER_PROFILE**(`userID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `userID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:106](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L106) + +___ + +### USER\_RELATIONSHIP + +▸ **USER_RELATIONSHIP**(`userID`, `relID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `userID` | [`BigString`](md#bigstring) | +| `relID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:107](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L107) + +___ + +### USER\_SETTINGS + +▸ **USER_SETTINGS**(`userID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `userID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:108](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L108) + +___ + +### WEBHOOK + +▸ **WEBHOOK**(`hookID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `hookID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:111](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L111) + +___ + +### WEBHOOK\_MESSAGE + +▸ **WEBHOOK_MESSAGE**(`hookID`, `token`, `msgID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `hookID` | [`BigString`](md#bigstring) | +| `token` | `string` | +| `msgID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:112](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L112) + +___ + +### WEBHOOK\_SLACK + +▸ **WEBHOOK_SLACK**(`hookID`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `hookID` | [`BigString`](md#bigstring) | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:113](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L113) + +___ + +### WEBHOOK\_TOKEN + +▸ **WEBHOOK_TOKEN**(`hookID`, `token`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `hookID` | [`BigString`](md#bigstring) | +| `token` | `string` | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:114](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L114) + +___ + +### WEBHOOK\_TOKEN\_SLACK + +▸ **WEBHOOK_TOKEN_SLACK**(`hookID`, `token`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `hookID` | [`BigString`](md#bigstring) | +| `token` | `string` | + +#### Returns + +`string` + +#### Defined in + +[packages/client/src/Endpoints.ts:115](https://github.com/discordeno/discordeno/blob/b8c25357/packages/client/src/Endpoints.ts#L115) diff --git a/website/docs/generated/modules_gateway.md b/website/docs/generated/modules_gateway.md new file mode 100644 index 000000000..589d39ff4 --- /dev/null +++ b/website/docs/generated/modules_gateway.md @@ -0,0 +1,53 @@ +[discordeno-monorepo](../README.md) / [Modules](../modules.md) / @discordeno/gateway + +# Module: @discordeno/gateway + +## Table of contents + +### Enumerations + +- [ShardSocketCloseCodes](../enums/ShardSocketCloseCodes.md) +- [ShardState](../enums/ShardState.md) + +### Classes + +- [DiscordenoShard](../classes/DiscordenoShard.md) + +### Interfaces + +- [BotActivity](../interfaces/BotActivity.md) +- [BotStatusUpdate](../interfaces/BotStatusUpdate.md) +- [CreateGatewayManagerOptions](../interfaces/CreateGatewayManagerOptions.md) +- [GatewayManager](../interfaces/GatewayManager.md) +- [RequestMemberRequest](../interfaces/RequestMemberRequest.md) +- [ShardCreateOptions](../interfaces/ShardCreateOptions.md) +- [ShardEvents](../interfaces/ShardEvents.md) +- [ShardGatewayConfig](../interfaces/ShardGatewayConfig.md) +- [ShardHeart](../interfaces/ShardHeart.md) +- [ShardSocketRequest](../interfaces/ShardSocketRequest.md) +- [StatusUpdate](../interfaces/StatusUpdate.md) +- [UpdateVoiceState](../interfaces/UpdateVoiceState.md) + +### Functions + +- [createGatewayManager](md#creategatewaymanager) + +## Functions + +### createGatewayManager + +▸ **createGatewayManager**(`options`): [`GatewayManager`](../interfaces/GatewayManager.md) + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `options` | [`CreateGatewayManagerOptions`](../interfaces/CreateGatewayManagerOptions.md) | + +#### Returns + +[`GatewayManager`](../interfaces/GatewayManager.md) + +#### Defined in + +[packages/gateway/src/manager.ts:7](https://github.com/discordeno/discordeno/blob/b8c25357/packages/gateway/src/manager.ts#L7) diff --git a/website/docs/generated/modules_rest.md b/website/docs/generated/modules_rest.md new file mode 100644 index 000000000..27b3effc8 --- /dev/null +++ b/website/docs/generated/modules_rest.md @@ -0,0 +1,101 @@ +[discordeno-monorepo](../README.md) / [Modules](../modules.md) / @discordeno/rest + +# Module: @discordeno/rest + +## Table of contents + +### Classes + +- [Queue](../classes/Queue.md) + +### Interfaces + +- [CreateRequestBodyOptions](../interfaces/CreateRequestBodyOptions.md) +- [CreateRestManagerOptions](../interfaces/CreateRestManagerOptions.md) +- [CreateWebhook](../interfaces/CreateWebhook.md) +- [InvalidRequestBucket](../interfaces/InvalidRequestBucket.md) +- [InvalidRequestBucketOptions](../interfaces/InvalidRequestBucketOptions.md) +- [QueueOptions](../interfaces/QueueOptions.md) +- [RequestBody](../interfaces/RequestBody.md) +- [RestManager](../interfaces/RestManager.md) +- [RestRateLimitedPath](../interfaces/RestRateLimitedPath.md) +- [RestRequestRejection](../interfaces/RestRequestRejection.md) +- [RestRequestResponse](../interfaces/RestRequestResponse.md) +- [RestRoutes](../interfaces/RestRoutes.md) +- [SendRequestOptions](../interfaces/SendRequestOptions.md) +- [WebhookMessageEditor](../interfaces/WebhookMessageEditor.md) + +### Type Aliases + +- [ApiVersions](md#apiversions) +- [RequestMethods](md#requestmethods) + +### Functions + +- [createInvalidRequestBucket](md#createinvalidrequestbucket) +- [createRestManager](md#createrestmanager) + +## Type Aliases + +### ApiVersions + +Ƭ **ApiVersions**: ``9`` \| ``10`` + +#### Defined in + +[packages/rest/src/types.ts:2439](https://github.com/discordeno/discordeno/blob/b8c25357/packages/rest/src/types.ts#L2439) + +___ + +### RequestMethods + +Ƭ **RequestMethods**: ``"GET"`` \| ``"POST"`` \| ``"DELETE"`` \| ``"PATCH"`` \| ``"PUT"`` + +#### Defined in + +[packages/rest/src/types.ts:2438](https://github.com/discordeno/discordeno/blob/b8c25357/packages/rest/src/types.ts#L2438) + +## Functions + +### createInvalidRequestBucket + +▸ **createInvalidRequestBucket**(`options`): [`InvalidRequestBucket`](../interfaces/InvalidRequestBucket.md) + +A invalid request bucket is used in a similar manner as a leaky bucket but a invalid request bucket can be refilled as needed. +It's purpose is to make sure the bot does not hit the limit to getting a 1 hr ban. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `options` | [`InvalidRequestBucketOptions`](../interfaces/InvalidRequestBucketOptions.md) | The options used to configure this bucket. | + +#### Returns + +[`InvalidRequestBucket`](../interfaces/InvalidRequestBucket.md) + +RefillingBucket + +#### Defined in + +[packages/rest/src/invalidBucket.ts:10](https://github.com/discordeno/discordeno/blob/b8c25357/packages/rest/src/invalidBucket.ts#L10) + +___ + +### createRestManager + +▸ **createRestManager**(`options`): [`RestManager`](../interfaces/RestManager.md) + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `options` | [`CreateRestManagerOptions`](../interfaces/CreateRestManagerOptions.md) | + +#### Returns + +[`RestManager`](../interfaces/RestManager.md) + +#### Defined in + +[packages/rest/src/manager.ts:72](https://github.com/discordeno/discordeno/blob/b8c25357/packages/rest/src/manager.ts#L72) diff --git a/website/docs/generated/modules_types.md b/website/docs/generated/modules_types.md new file mode 100644 index 000000000..5216c4bf0 --- /dev/null +++ b/website/docs/generated/modules_types.md @@ -0,0 +1,585 @@ +[discordeno-monorepo](../README.md) / [Modules](../modules.md) / @discordeno/types + +# Module: @discordeno/types + +## Table of contents + +### Enumerations + +- [ActivityTypes](../enums/ActivityTypes.md) +- [AllowedMentionsTypes](../enums/AllowedMentionsTypes.md) +- [ApplicationCommandOptionTypes](../enums/ApplicationCommandOptionTypes.md) +- [ApplicationCommandPermissionTypes](../enums/ApplicationCommandPermissionTypes.md) +- [ApplicationCommandTypes](../enums/ApplicationCommandTypes.md) +- [ApplicationFlags](../enums/ApplicationFlags.md) +- [AuditLogEvents](../enums/AuditLogEvents.md) +- [AutoModerationActionType](../enums/AutoModerationActionType.md) +- [AutoModerationEventTypes](../enums/AutoModerationEventTypes.md) +- [AutoModerationTriggerTypes](../enums/AutoModerationTriggerTypes.md) +- [BitwisePermissionFlags](../enums/BitwisePermissionFlags.md) +- [ButtonStyles](../enums/ButtonStyles.md) +- [ChannelFlags](../enums/ChannelFlags.md) +- [ChannelTypes](../enums/ChannelTypes.md) +- [DefaultMessageNotificationLevels](../enums/DefaultMessageNotificationLevels.md) +- [DiscordAutoModerationRuleTriggerMetadataPresets](../enums/DiscordAutoModerationRuleTriggerMetadataPresets.md) +- [ExplicitContentFilterLevels](../enums/ExplicitContentFilterLevels.md) +- [GatewayCloseEventCodes](../enums/GatewayCloseEventCodes.md) +- [GatewayIntents](../enums/GatewayIntents.md) +- [GatewayOpcodes](../enums/GatewayOpcodes.md) +- [GuildFeatures](../enums/GuildFeatures.md) +- [GuildNsfwLevel](../enums/GuildNsfwLevel.md) +- [IntegrationExpireBehaviors](../enums/IntegrationExpireBehaviors.md) +- [InteractionResponseTypes](../enums/InteractionResponseTypes.md) +- [InteractionTypes](../enums/InteractionTypes.md) +- [Locales](../enums/Locales.md) +- [MessageActivityTypes](../enums/MessageActivityTypes.md) +- [MessageComponentTypes](../enums/MessageComponentTypes.md) +- [MessageTypes](../enums/MessageTypes.md) +- [MfaLevels](../enums/MfaLevels.md) +- [OverwriteTypes](../enums/OverwriteTypes.md) +- [PremiumTiers](../enums/PremiumTiers.md) +- [PremiumTypes](../enums/PremiumTypes.md) +- [PresenceStatus](../enums/PresenceStatus.md) +- [ScheduledEventEntityType](../enums/ScheduledEventEntityType.md) +- [ScheduledEventPrivacyLevel](../enums/ScheduledEventPrivacyLevel.md) +- [ScheduledEventStatus](../enums/ScheduledEventStatus.md) +- [SortOrderTypes](../enums/SortOrderTypes.md) +- [StickerFormatTypes](../enums/StickerFormatTypes.md) +- [StickerTypes](../enums/StickerTypes.md) +- [SystemChannelFlags](../enums/SystemChannelFlags.md) +- [TargetTypes](../enums/TargetTypes.md) +- [TeamMembershipStates](../enums/TeamMembershipStates.md) +- [TextStyles](../enums/TextStyles.md) +- [UserFlags](../enums/UserFlags.md) +- [VerificationLevels](../enums/VerificationLevels.md) +- [VideoQualityModes](../enums/VideoQualityModes.md) +- [WebhookTypes](../enums/WebhookTypes.md) + +### Interfaces + +- [ActionRow](../interfaces/ActionRow.md) +- [AllowedMentions](../interfaces/AllowedMentions.md) +- [ApplicationCommandOption](../interfaces/ApplicationCommandOption.md) +- [ApplicationCommandOptionChoice](../interfaces/ApplicationCommandOptionChoice.md) +- [ApplicationCommandPermissions](../interfaces/ApplicationCommandPermissions.md) +- [BeginGuildPrune](../interfaces/BeginGuildPrune.md) +- [ButtonComponent](../interfaces/ButtonComponent.md) +- [CreateAutoModerationRuleOptions](../interfaces/CreateAutoModerationRuleOptions.md) +- [CreateChannelInvite](../interfaces/CreateChannelInvite.md) +- [CreateContextApplicationCommand](../interfaces/CreateContextApplicationCommand.md) +- [CreateForumPostWithMessage](../interfaces/CreateForumPostWithMessage.md) +- [CreateGuild](../interfaces/CreateGuild.md) +- [CreateGuildBan](../interfaces/CreateGuildBan.md) +- [CreateGuildChannel](../interfaces/CreateGuildChannel.md) +- [CreateGuildEmoji](../interfaces/CreateGuildEmoji.md) +- [CreateGuildFromTemplate](../interfaces/CreateGuildFromTemplate.md) +- [CreateGuildRole](../interfaces/CreateGuildRole.md) +- [CreateGuildStickerOptions](../interfaces/CreateGuildStickerOptions.md) +- [CreateMessageOptions](../interfaces/CreateMessageOptions.md) +- [CreateScheduledEvent](../interfaces/CreateScheduledEvent.md) +- [CreateSlashApplicationCommand](../interfaces/CreateSlashApplicationCommand.md) +- [CreateStageInstance](../interfaces/CreateStageInstance.md) +- [CreateTemplate](../interfaces/CreateTemplate.md) +- [DeleteWebhookMessageOptions](../interfaces/DeleteWebhookMessageOptions.md) +- [DiscordActionRow](../interfaces/DiscordActionRow.md) +- [DiscordActiveThreads](../interfaces/DiscordActiveThreads.md) +- [DiscordActivity](../interfaces/DiscordActivity.md) +- [DiscordActivityAssets](../interfaces/DiscordActivityAssets.md) +- [DiscordActivityButton](../interfaces/DiscordActivityButton.md) +- [DiscordActivityEmoji](../interfaces/DiscordActivityEmoji.md) +- [DiscordActivityParty](../interfaces/DiscordActivityParty.md) +- [DiscordActivitySecrets](../interfaces/DiscordActivitySecrets.md) +- [DiscordActivityTimestamps](../interfaces/DiscordActivityTimestamps.md) +- [DiscordAllowedMentions](../interfaces/DiscordAllowedMentions.md) +- [DiscordApplication](../interfaces/DiscordApplication.md) +- [DiscordApplicationCommand](../interfaces/DiscordApplicationCommand.md) +- [DiscordApplicationCommandOption](../interfaces/DiscordApplicationCommandOption.md) +- [DiscordApplicationCommandOptionChoice](../interfaces/DiscordApplicationCommandOptionChoice.md) +- [DiscordApplicationCommandPermissions](../interfaces/DiscordApplicationCommandPermissions.md) +- [DiscordApplicationWebhook](../interfaces/DiscordApplicationWebhook.md) +- [DiscordAttachment](../interfaces/DiscordAttachment.md) +- [DiscordAuditLog](../interfaces/DiscordAuditLog.md) +- [DiscordAuditLogEntry](../interfaces/DiscordAuditLogEntry.md) +- [DiscordAutoModerationAction](../interfaces/DiscordAutoModerationAction.md) +- [DiscordAutoModerationActionExecution](../interfaces/DiscordAutoModerationActionExecution.md) +- [DiscordAutoModerationActionMetadata](../interfaces/DiscordAutoModerationActionMetadata.md) +- [DiscordAutoModerationRule](../interfaces/DiscordAutoModerationRule.md) +- [DiscordAutoModerationRuleTriggerMetadata](../interfaces/DiscordAutoModerationRuleTriggerMetadata.md) +- [DiscordBan](../interfaces/DiscordBan.md) +- [DiscordButtonComponent](../interfaces/DiscordButtonComponent.md) +- [DiscordChannel](../interfaces/DiscordChannel.md) +- [DiscordChannelMention](../interfaces/DiscordChannelMention.md) +- [DiscordChannelPinsUpdate](../interfaces/DiscordChannelPinsUpdate.md) +- [DiscordClientStatus](../interfaces/DiscordClientStatus.md) +- [DiscordCreateApplicationCommand](../interfaces/DiscordCreateApplicationCommand.md) +- [DiscordCreateForumPostWithMessage](../interfaces/DiscordCreateForumPostWithMessage.md) +- [DiscordCreateGuildChannel](../interfaces/DiscordCreateGuildChannel.md) +- [DiscordCreateGuildEmoji](../interfaces/DiscordCreateGuildEmoji.md) +- [DiscordCreateMessage](../interfaces/DiscordCreateMessage.md) +- [DiscordCreateWebhook](../interfaces/DiscordCreateWebhook.md) +- [DiscordDefaultReactionEmoji](../interfaces/DiscordDefaultReactionEmoji.md) +- [DiscordEditChannelPermissionOverridesOptions](../interfaces/DiscordEditChannelPermissionOverridesOptions.md) +- [DiscordEmbed](../interfaces/DiscordEmbed.md) +- [DiscordEmbedAuthor](../interfaces/DiscordEmbedAuthor.md) +- [DiscordEmbedField](../interfaces/DiscordEmbedField.md) +- [DiscordEmbedFooter](../interfaces/DiscordEmbedFooter.md) +- [DiscordEmbedImage](../interfaces/DiscordEmbedImage.md) +- [DiscordEmbedProvider](../interfaces/DiscordEmbedProvider.md) +- [DiscordEmbedThumbnail](../interfaces/DiscordEmbedThumbnail.md) +- [DiscordEmbedVideo](../interfaces/DiscordEmbedVideo.md) +- [DiscordEmoji](../interfaces/DiscordEmoji.md) +- [DiscordFollowAnnouncementChannel](../interfaces/DiscordFollowAnnouncementChannel.md) +- [DiscordFollowedChannel](../interfaces/DiscordFollowedChannel.md) +- [DiscordForumTag](../interfaces/DiscordForumTag.md) +- [DiscordGatewayPayload](../interfaces/DiscordGatewayPayload.md) +- [DiscordGetGatewayBot](../interfaces/DiscordGetGatewayBot.md) +- [DiscordGuild](../interfaces/DiscordGuild.md) +- [DiscordGuildApplicationCommandPermissions](../interfaces/DiscordGuildApplicationCommandPermissions.md) +- [DiscordGuildBanAddRemove](../interfaces/DiscordGuildBanAddRemove.md) +- [DiscordGuildEmojisUpdate](../interfaces/DiscordGuildEmojisUpdate.md) +- [DiscordGuildIntegrationsUpdate](../interfaces/DiscordGuildIntegrationsUpdate.md) +- [DiscordGuildMemberAdd](../interfaces/DiscordGuildMemberAdd.md) +- [DiscordGuildMemberRemove](../interfaces/DiscordGuildMemberRemove.md) +- [DiscordGuildMemberUpdate](../interfaces/DiscordGuildMemberUpdate.md) +- [DiscordGuildMembersChunk](../interfaces/DiscordGuildMembersChunk.md) +- [DiscordGuildPreview](../interfaces/DiscordGuildPreview.md) +- [DiscordGuildRoleCreate](../interfaces/DiscordGuildRoleCreate.md) +- [DiscordGuildRoleDelete](../interfaces/DiscordGuildRoleDelete.md) +- [DiscordGuildRoleUpdate](../interfaces/DiscordGuildRoleUpdate.md) +- [DiscordGuildStickersUpdate](../interfaces/DiscordGuildStickersUpdate.md) +- [DiscordGuildWidget](../interfaces/DiscordGuildWidget.md) +- [DiscordGuildWidgetSettings](../interfaces/DiscordGuildWidgetSettings.md) +- [DiscordHello](../interfaces/DiscordHello.md) +- [DiscordIncomingWebhook](../interfaces/DiscordIncomingWebhook.md) +- [DiscordInputTextComponent](../interfaces/DiscordInputTextComponent.md) +- [DiscordInstallParams](../interfaces/DiscordInstallParams.md) +- [DiscordIntegration](../interfaces/DiscordIntegration.md) +- [DiscordIntegrationAccount](../interfaces/DiscordIntegrationAccount.md) +- [DiscordIntegrationApplication](../interfaces/DiscordIntegrationApplication.md) +- [DiscordIntegrationCreateUpdate](../interfaces/DiscordIntegrationCreateUpdate.md) +- [DiscordIntegrationDelete](../interfaces/DiscordIntegrationDelete.md) +- [DiscordInteraction](../interfaces/DiscordInteraction.md) +- [DiscordInteractionData](../interfaces/DiscordInteractionData.md) +- [DiscordInteractionDataOption](../interfaces/DiscordInteractionDataOption.md) +- [DiscordInteractionMember](../interfaces/DiscordInteractionMember.md) +- [DiscordInvite](../interfaces/DiscordInvite.md) +- [DiscordInviteCreate](../interfaces/DiscordInviteCreate.md) +- [DiscordInviteDelete](../interfaces/DiscordInviteDelete.md) +- [DiscordInviteMetadata](../interfaces/DiscordInviteMetadata.md) +- [DiscordInviteStageInstance](../interfaces/DiscordInviteStageInstance.md) +- [DiscordListActiveThreads](../interfaces/DiscordListActiveThreads.md) +- [DiscordListArchivedThreads](../interfaces/DiscordListArchivedThreads.md) +- [DiscordMember](../interfaces/DiscordMember.md) +- [DiscordMemberWithUser](../interfaces/DiscordMemberWithUser.md) +- [DiscordMessage](../interfaces/DiscordMessage.md) +- [DiscordMessageActivity](../interfaces/DiscordMessageActivity.md) +- [DiscordMessageDelete](../interfaces/DiscordMessageDelete.md) +- [DiscordMessageDeleteBulk](../interfaces/DiscordMessageDeleteBulk.md) +- [DiscordMessageInteraction](../interfaces/DiscordMessageInteraction.md) +- [DiscordMessageReactionAdd](../interfaces/DiscordMessageReactionAdd.md) +- [DiscordMessageReactionRemove](../interfaces/DiscordMessageReactionRemove.md) +- [DiscordMessageReactionRemoveAll](../interfaces/DiscordMessageReactionRemoveAll.md) +- [DiscordMessageReference](../interfaces/DiscordMessageReference.md) +- [DiscordModifyChannel](../interfaces/DiscordModifyChannel.md) +- [DiscordModifyGuildChannelPositions](../interfaces/DiscordModifyGuildChannelPositions.md) +- [DiscordModifyGuildEmoji](../interfaces/DiscordModifyGuildEmoji.md) +- [DiscordModifyGuildWelcomeScreen](../interfaces/DiscordModifyGuildWelcomeScreen.md) +- [DiscordOptionalAuditEntryInfo](../interfaces/DiscordOptionalAuditEntryInfo.md) +- [DiscordOverwrite](../interfaces/DiscordOverwrite.md) +- [DiscordPresenceUpdate](../interfaces/DiscordPresenceUpdate.md) +- [DiscordPrunedCount](../interfaces/DiscordPrunedCount.md) +- [DiscordReaction](../interfaces/DiscordReaction.md) +- [DiscordReady](../interfaces/DiscordReady.md) +- [DiscordRole](../interfaces/DiscordRole.md) +- [DiscordRoleTags](../interfaces/DiscordRoleTags.md) +- [DiscordScheduledEvent](../interfaces/DiscordScheduledEvent.md) +- [DiscordScheduledEventEntityMetadata](../interfaces/DiscordScheduledEventEntityMetadata.md) +- [DiscordScheduledEventUserAdd](../interfaces/DiscordScheduledEventUserAdd.md) +- [DiscordScheduledEventUserRemove](../interfaces/DiscordScheduledEventUserRemove.md) +- [DiscordSelectMenuComponent](../interfaces/DiscordSelectMenuComponent.md) +- [DiscordSelectOption](../interfaces/DiscordSelectOption.md) +- [DiscordSessionStartLimit](../interfaces/DiscordSessionStartLimit.md) +- [DiscordStageInstance](../interfaces/DiscordStageInstance.md) +- [DiscordSticker](../interfaces/DiscordSticker.md) +- [DiscordStickerItem](../interfaces/DiscordStickerItem.md) +- [DiscordStickerPack](../interfaces/DiscordStickerPack.md) +- [DiscordTeam](../interfaces/DiscordTeam.md) +- [DiscordTeamMember](../interfaces/DiscordTeamMember.md) +- [DiscordTemplate](../interfaces/DiscordTemplate.md) +- [DiscordThreadListSync](../interfaces/DiscordThreadListSync.md) +- [DiscordThreadMember](../interfaces/DiscordThreadMember.md) +- [DiscordThreadMemberUpdate](../interfaces/DiscordThreadMemberUpdate.md) +- [DiscordThreadMembersUpdate](../interfaces/DiscordThreadMembersUpdate.md) +- [DiscordThreadMetadata](../interfaces/DiscordThreadMetadata.md) +- [DiscordTypingStart](../interfaces/DiscordTypingStart.md) +- [DiscordUnavailableGuild](../interfaces/DiscordUnavailableGuild.md) +- [DiscordUser](../interfaces/DiscordUser.md) +- [DiscordVanityUrl](../interfaces/DiscordVanityUrl.md) +- [DiscordVoiceRegion](../interfaces/DiscordVoiceRegion.md) +- [DiscordVoiceServerUpdate](../interfaces/DiscordVoiceServerUpdate.md) +- [DiscordVoiceState](../interfaces/DiscordVoiceState.md) +- [DiscordWebhookUpdate](../interfaces/DiscordWebhookUpdate.md) +- [DiscordWelcomeScreen](../interfaces/DiscordWelcomeScreen.md) +- [DiscordWelcomeScreenChannel](../interfaces/DiscordWelcomeScreenChannel.md) +- [EditAutoModerationRuleOptions](../interfaces/EditAutoModerationRuleOptions.md) +- [EditBotMemberOptions](../interfaces/EditBotMemberOptions.md) +- [EditChannelPermissionOverridesOptions](../interfaces/EditChannelPermissionOverridesOptions.md) +- [EditGuildRole](../interfaces/EditGuildRole.md) +- [EditGuildStickerOptions](../interfaces/EditGuildStickerOptions.md) +- [EditMessage](../interfaces/EditMessage.md) +- [EditOwnVoiceState](../interfaces/EditOwnVoiceState.md) +- [EditScheduledEvent](../interfaces/EditScheduledEvent.md) +- [EditStageInstanceOptions](../interfaces/EditStageInstanceOptions.md) +- [EditUserVoiceState](../interfaces/EditUserVoiceState.md) +- [ExecuteWebhook](../interfaces/ExecuteWebhook.md) +- [FileContent](../interfaces/FileContent.md) +- [GetBans](../interfaces/GetBans.md) +- [GetGuildAuditLog](../interfaces/GetGuildAuditLog.md) +- [GetGuildPruneCountQuery](../interfaces/GetGuildPruneCountQuery.md) +- [GetGuildWidgetImageQuery](../interfaces/GetGuildWidgetImageQuery.md) +- [GetInvite](../interfaces/GetInvite.md) +- [GetMessagesAfter](../interfaces/GetMessagesAfter.md) +- [GetMessagesAround](../interfaces/GetMessagesAround.md) +- [GetMessagesBefore](../interfaces/GetMessagesBefore.md) +- [GetMessagesLimit](../interfaces/GetMessagesLimit.md) +- [GetReactions](../interfaces/GetReactions.md) +- [GetScheduledEventUsers](../interfaces/GetScheduledEventUsers.md) +- [GetScheduledEvents](../interfaces/GetScheduledEvents.md) +- [GetWebhookMessageOptions](../interfaces/GetWebhookMessageOptions.md) +- [InputTextComponent](../interfaces/InputTextComponent.md) +- [InteractionCallbackData](../interfaces/InteractionCallbackData.md) +- [InteractionResponse](../interfaces/InteractionResponse.md) +- [ListArchivedThreads](../interfaces/ListArchivedThreads.md) +- [ListGuildMembers](../interfaces/ListGuildMembers.md) +- [ModifyChannel](../interfaces/ModifyChannel.md) +- [ModifyGuild](../interfaces/ModifyGuild.md) +- [ModifyGuildChannelPositions](../interfaces/ModifyGuildChannelPositions.md) +- [ModifyGuildEmoji](../interfaces/ModifyGuildEmoji.md) +- [ModifyGuildMember](../interfaces/ModifyGuildMember.md) +- [ModifyGuildTemplate](../interfaces/ModifyGuildTemplate.md) +- [ModifyRolePositions](../interfaces/ModifyRolePositions.md) +- [ModifyWebhook](../interfaces/ModifyWebhook.md) +- [OverwriteReadable](../interfaces/OverwriteReadable.md) +- [RequestGuildMembers](../interfaces/RequestGuildMembers.md) +- [SearchMembers](../interfaces/SearchMembers.md) +- [SelectMenuChannelsComponent](../interfaces/SelectMenuChannelsComponent.md) +- [SelectMenuComponent](../interfaces/SelectMenuComponent.md) +- [SelectMenuRolesComponent](../interfaces/SelectMenuRolesComponent.md) +- [SelectMenuUsersAndRolesComponent](../interfaces/SelectMenuUsersAndRolesComponent.md) +- [SelectMenuUsersComponent](../interfaces/SelectMenuUsersComponent.md) +- [SelectOption](../interfaces/SelectOption.md) +- [StartThreadWithMessage](../interfaces/StartThreadWithMessage.md) +- [StartThreadWithoutMessage](../interfaces/StartThreadWithoutMessage.md) +- [WithReason](../interfaces/WithReason.md) + +### Type Aliases + +- [AtLeastOne](md#atleastone) +- [BigString](md#bigstring) +- [CamelCase](md#camelcase) +- [Camelize](md#camelize) +- [CreateApplicationCommand](md#createapplicationcommand) +- [DiscordArchivedThreads](md#discordarchivedthreads) +- [DiscordAuditLogChange](md#discordauditlogchange) +- [DiscordMessageComponents](md#discordmessagecomponents) +- [DiscordMessageReactionRemoveEmoji](md#discordmessagereactionremoveemoji) +- [DiscordWebhook](md#discordwebhook) +- [EmbedTypes](md#embedtypes) +- [GatewayDispatchEventNames](md#gatewaydispatcheventnames) +- [GatewayEventNames](md#gatewayeventnames) +- [GetMessagesOptions](md#getmessagesoptions) +- [ImageFormat](md#imageformat) +- [ImageSize](md#imagesize) +- [Localization](md#localization) +- [MessageComponents](md#messagecomponents) +- [PermissionStrings](md#permissionstrings) +- [PickPartial](md#pickpartial) +- [SnakeCase](md#snakecase) +- [Snakelize](md#snakelize) + +### Variables + +- [Intents](md#intents) + +## Type Aliases + +### AtLeastOne + +Ƭ **AtLeastOne**<`T`, `U`\>: `Partial`<`T`\> & `U`[keyof `U`] + +#### Type parameters + +| Name | Type | +| :------ | :------ | +| `T` | `T` | +| `U` | { [K in keyof T]: Pick } | + +#### Defined in + +[packages/types/src/shared.ts:945](https://github.com/discordeno/discordeno/blob/b8c25357/packages/types/src/shared.ts#L945) + +___ + +### BigString + +Ƭ **BigString**: `bigint` \| `string` + +#### Defined in + +[packages/types/src/shared.ts:1](https://github.com/discordeno/discordeno/blob/b8c25357/packages/types/src/shared.ts#L1) + +___ + +### CamelCase + +Ƭ **CamelCase**<`S`\>: `S` extends \`${infer T}\_${infer U}\` ? \`${T}${Capitalize\>}\` : `S` + +#### Type parameters + +| Name | Type | +| :------ | :------ | +| `S` | extends `string` | + +#### Defined in + +[packages/types/src/shared.ts:946](https://github.com/discordeno/discordeno/blob/b8c25357/packages/types/src/shared.ts#L946) + +___ + +### Camelize + +Ƭ **Camelize**<`T`\>: `T` extends `any`[] ? `T` extends `Record`<`any`, `any`\>[] ? [`Camelize`](md#camelize)<`T`[`number`]\>[] : `T` : `T` extends `Record`<`any`, `any`\> ? { [K in keyof T as CamelCase]: Camelize } : `T` + +#### Type parameters + +| Name | +| :------ | +| `T` | + +#### Defined in + +[packages/types/src/shared.ts:949](https://github.com/discordeno/discordeno/blob/b8c25357/packages/types/src/shared.ts#L949) + +___ + +### CreateApplicationCommand + +Ƭ **CreateApplicationCommand**: [`CreateSlashApplicationCommand`](../interfaces/CreateSlashApplicationCommand.md) \| [`CreateContextApplicationCommand`](../interfaces/CreateContextApplicationCommand.md) + +#### Defined in + +[packages/types/src/discordeno.ts:386](https://github.com/discordeno/discordeno/blob/b8c25357/packages/types/src/discordeno.ts#L386) + +___ + +### DiscordArchivedThreads + +Ƭ **DiscordArchivedThreads**: [`DiscordActiveThreads`](../interfaces/DiscordActiveThreads.md) & { `hasMore`: `boolean` } + +#### Defined in + +[packages/types/src/discord.ts:2569](https://github.com/discordeno/discordeno/blob/b8c25357/packages/types/src/discord.ts#L2569) + +___ + +### DiscordAuditLogChange + +Ƭ **DiscordAuditLogChange**: { `key`: ``"name"`` \| ``"description"`` \| ``"discovery_splash_hash"`` \| ``"banner_hash"`` \| ``"preferred_locale"`` \| ``"rules_channel_id"`` \| ``"public_updates_channel_id"`` \| ``"icon_hash"`` \| ``"image_hash"`` \| ``"splash_hash"`` \| ``"owner_id"`` \| ``"region"`` \| ``"afk_channel_id"`` \| ``"vanity_url_code"`` \| ``"widget_channel_id"`` \| ``"system_channel_id"`` \| ``"topic"`` \| ``"application_id"`` \| ``"permissions"`` \| ``"allow"`` \| ``"deny"`` \| ``"code"`` \| ``"channel_id"`` \| ``"inviter_id"`` \| ``"nick"`` \| ``"avatar_hash"`` \| ``"id"`` \| ``"location"`` \| ``"command_id"`` ; `new_value`: `string` ; `old_value`: `string` } \| { `key`: ``"afk_timeout"`` \| ``"mfa_level"`` \| ``"verification_level"`` \| ``"explicit_content_filter"`` \| ``"default_message_notifications"`` \| ``"prune_delete_days"`` \| ``"position"`` \| ``"bitrate"`` \| ``"rate_limit_per_user"`` \| ``"color"`` \| ``"max_uses"`` \| ``"uses"`` \| ``"max_age"`` \| ``"expire_behavior"`` \| ``"expire_grace_period"`` \| ``"user_limit"`` \| ``"privacy_level"`` \| ``"auto_archive_duration"`` \| ``"default_auto_archive_duration"`` \| ``"entity_type"`` \| ``"status"`` \| ``"communication_disabled_until"`` ; `new_value`: `number` ; `old_value`: `number` } \| { `key`: ``"$add"`` \| ``"$remove"`` ; `new_value`: `Partial`<[`DiscordRole`](../interfaces/DiscordRole.md)\>[] ; `old_value?`: `Partial`<[`DiscordRole`](../interfaces/DiscordRole.md)\>[] } \| { `key`: ``"widget_enabled"`` \| ``"nsfw"`` \| ``"hoist"`` \| ``"mentionable"`` \| ``"temporary"`` \| ``"deaf"`` \| ``"mute"`` \| ``"enable_emoticons"`` \| ``"archived"`` \| ``"locked"`` \| ``"invitable"`` ; `new_value`: `boolean` ; `old_value`: `boolean` } \| { `key`: ``"permission_overwrites"`` ; `new_value`: [`DiscordOverwrite`](../interfaces/DiscordOverwrite.md)[] ; `old_value`: [`DiscordOverwrite`](../interfaces/DiscordOverwrite.md)[] } \| { `key`: ``"type"`` ; `new_value`: `string` \| `number` ; `old_value`: `string` \| `number` } + +https://discord.com/developers/docs/resources/audit-log#audit-log-change-object-audit-log-change-structure + +#### Defined in + +[packages/types/src/discord.ts:1495](https://github.com/discordeno/discordeno/blob/b8c25357/packages/types/src/discord.ts#L1495) + +___ + +### DiscordMessageComponents + +Ƭ **DiscordMessageComponents**: [`DiscordActionRow`](../interfaces/DiscordActionRow.md)[] + +#### Defined in + +[packages/types/src/discord.ts:1110](https://github.com/discordeno/discordeno/blob/b8c25357/packages/types/src/discord.ts#L1110) + +___ + +### DiscordMessageReactionRemoveEmoji + +Ƭ **DiscordMessageReactionRemoveEmoji**: `Pick`<[`DiscordMessageReactionAdd`](../interfaces/DiscordMessageReactionAdd.md), ``"channel_id"`` \| ``"guild_id"`` \| ``"message_id"`` \| ``"emoji"``\> + +https://discord.com/developers/docs/topics/gateway#message-reaction-remove-emoji + +#### Defined in + +[packages/types/src/discord.ts:2251](https://github.com/discordeno/discordeno/blob/b8c25357/packages/types/src/discord.ts#L2251) + +___ + +### DiscordWebhook + +Ƭ **DiscordWebhook**: [`DiscordIncomingWebhook`](../interfaces/DiscordIncomingWebhook.md) \| [`DiscordApplicationWebhook`](../interfaces/DiscordApplicationWebhook.md) + +https://discord.com/developers/docs/resources/webhook#webhook-object-webhook-structure + +#### Defined in + +[packages/types/src/discord.ts:422](https://github.com/discordeno/discordeno/blob/b8c25357/packages/types/src/discord.ts#L422) + +___ + +### EmbedTypes + +Ƭ **EmbedTypes**: ``"rich"`` \| ``"image"`` \| ``"video"`` \| ``"gifv"`` \| ``"article"`` \| ``"link"`` + +https://discord.com/developers/docs/resources/channel#embed-object-embed-types + +#### Defined in + +[packages/types/src/shared.ts:142](https://github.com/discordeno/discordeno/blob/b8c25357/packages/types/src/shared.ts#L142) + +___ + +### GatewayDispatchEventNames + +Ƭ **GatewayDispatchEventNames**: ``"READY"`` \| ``"APPLICATION_COMMAND_PERMISSIONS_UPDATE"`` \| ``"AUTO_MODERATION_RULE_CREATE"`` \| ``"AUTO_MODERATION_RULE_UPDATE"`` \| ``"AUTO_MODERATION_RULE_DELETE"`` \| ``"AUTO_MODERATION_ACTION_EXECUTION"`` \| ``"CHANNEL_CREATE"`` \| ``"CHANNEL_UPDATE"`` \| ``"CHANNEL_DELETE"`` \| ``"CHANNEL_PINS_UPDATE"`` \| ``"THREAD_CREATE"`` \| ``"THREAD_UPDATE"`` \| ``"THREAD_DELETE"`` \| ``"THREAD_LIST_SYNC"`` \| ``"THREAD_MEMBER_UPDATE"`` \| ``"THREAD_MEMBERS_UPDATE"`` \| ``"GUILD_CREATE"`` \| ``"GUILD_UPDATE"`` \| ``"GUILD_DELETE"`` \| ``"GUILD_BAN_ADD"`` \| ``"GUILD_BAN_REMOVE"`` \| ``"GUILD_EMOJIS_UPDATE"`` \| ``"GUILD_STICKERS_UPDATE"`` \| ``"GUILD_INTEGRATIONS_UPDATE"`` \| ``"GUILD_MEMBER_ADD"`` \| ``"GUILD_MEMBER_REMOVE"`` \| ``"GUILD_MEMBER_UPDATE"`` \| ``"GUILD_MEMBERS_CHUNK"`` \| ``"GUILD_ROLE_CREATE"`` \| ``"GUILD_ROLE_UPDATE"`` \| ``"GUILD_ROLE_DELETE"`` \| ``"GUILD_SCHEDULED_EVENT_CREATE"`` \| ``"GUILD_SCHEDULED_EVENT_UPDATE"`` \| ``"GUILD_SCHEDULED_EVENT_DELETE"`` \| ``"GUILD_SCHEDULED_EVENT_USER_ADD"`` \| ``"GUILD_SCHEDULED_EVENT_USER_REMOVE"`` \| ``"INTEGRATION_CREATE"`` \| ``"INTEGRATION_UPDATE"`` \| ``"INTEGRATION_DELETE"`` \| ``"INTERACTION_CREATE"`` \| ``"INVITE_CREATE"`` \| ``"INVITE_DELETE"`` \| ``"MESSAGE_CREATE"`` \| ``"MESSAGE_UPDATE"`` \| ``"MESSAGE_DELETE"`` \| ``"MESSAGE_DELETE_BULK"`` \| ``"MESSAGE_REACTION_ADD"`` \| ``"MESSAGE_REACTION_REMOVE"`` \| ``"MESSAGE_REACTION_REMOVE_ALL"`` \| ``"MESSAGE_REACTION_REMOVE_EMOJI"`` \| ``"PRESENCE_UPDATE"`` \| ``"STAGE_INSTANCE_CREATE"`` \| ``"STAGE_INSTANCE_UPDATE"`` \| ``"STAGE_INSTANCE_DELETE"`` \| ``"TYPING_START"`` \| ``"USER_UPDATE"`` \| ``"VOICE_STATE_UPDATE"`` \| ``"VOICE_SERVER_UPDATE"`` \| ``"WEBHOOKS_UPDATE"`` + +#### Defined in + +[packages/types/src/shared.ts:686](https://github.com/discordeno/discordeno/blob/b8c25357/packages/types/src/shared.ts#L686) + +___ + +### GatewayEventNames + +Ƭ **GatewayEventNames**: [`GatewayDispatchEventNames`](md#gatewaydispatcheventnames) \| ``"READY"`` \| ``"RESUMED"`` + +#### Defined in + +[packages/types/src/shared.ts:747](https://github.com/discordeno/discordeno/blob/b8c25357/packages/types/src/shared.ts#L747) + +___ + +### GetMessagesOptions + +Ƭ **GetMessagesOptions**: [`GetMessagesAfter`](../interfaces/GetMessagesAfter.md) \| [`GetMessagesBefore`](../interfaces/GetMessagesBefore.md) \| [`GetMessagesAround`](../interfaces/GetMessagesAround.md) \| [`GetMessagesLimit`](../interfaces/GetMessagesLimit.md) + +#### Defined in + +[packages/types/src/discordeno.ts:310](https://github.com/discordeno/discordeno/blob/b8c25357/packages/types/src/discordeno.ts#L310) + +___ + +### ImageFormat + +Ƭ **ImageFormat**: ``"jpg"`` \| ``"jpeg"`` \| ``"png"`` \| ``"webp"`` \| ``"gif"`` \| ``"json"`` + +https://discord.com/developers/docs/reference#image-formatting +json is only for stickers + +#### Defined in + +[packages/types/src/shared.ts:905](https://github.com/discordeno/discordeno/blob/b8c25357/packages/types/src/shared.ts#L905) + +___ + +### ImageSize + +Ƭ **ImageSize**: ``16`` \| ``32`` \| ``64`` \| ``128`` \| ``256`` \| ``512`` \| ``1024`` \| ``2048`` \| ``4096`` + +https://discord.com/developers/docs/reference#image-formatting + +#### Defined in + +[packages/types/src/shared.ts:908](https://github.com/discordeno/discordeno/blob/b8c25357/packages/types/src/shared.ts#L908) + +___ + +### Localization + +Ƭ **Localization**: `Partial`<`Record`<[`Locales`](../enums/Locales.md), `string`\>\> + +#### Defined in + +[packages/types/src/shared.ts:943](https://github.com/discordeno/discordeno/blob/b8c25357/packages/types/src/shared.ts#L943) + +___ + +### MessageComponents + +Ƭ **MessageComponents**: [`ActionRow`](../interfaces/ActionRow.md)[] + +#### Defined in + +[packages/types/src/discordeno.ts:73](https://github.com/discordeno/discordeno/blob/b8c25357/packages/types/src/discordeno.ts#L73) + +___ + +### PermissionStrings + +Ƭ **PermissionStrings**: keyof typeof [`BitwisePermissionFlags`](../enums/BitwisePermissionFlags.md) + +#### Defined in + +[packages/types/src/shared.ts:624](https://github.com/discordeno/discordeno/blob/b8c25357/packages/types/src/shared.ts#L624) + +___ + +### PickPartial + +Ƭ **PickPartial**<`T`, `K`\>: { [P in keyof T]?: T[P] } & { [P in K]: T[P] } + +#### Type parameters + +| Name | Type | +| :------ | :------ | +| `T` | `T` | +| `K` | extends keyof `T` | + +#### Defined in + +[packages/types/src/shared.ts:965](https://github.com/discordeno/discordeno/blob/b8c25357/packages/types/src/shared.ts#L965) + +___ + +### SnakeCase + +Ƭ **SnakeCase**<`S`\>: `S` extends \`${infer T}${infer U}\` ? \`${T extends Capitalize ? "\_" : ""}${Lowercase}${SnakeCase}\` : `S` + +#### Type parameters + +| Name | Type | +| :------ | :------ | +| `S` | extends `string` | + +#### Defined in + +[packages/types/src/shared.ts:947](https://github.com/discordeno/discordeno/blob/b8c25357/packages/types/src/shared.ts#L947) + +___ + +### Snakelize + +Ƭ **Snakelize**<`T`\>: `T` extends `any`[] ? `T` extends `Record`<`any`, `any`\>[] ? [`Snakelize`](md#snakelize)<`T`[`number`]\>[] : `T` : `T` extends `Record`<`any`, `any`\> ? { [K in keyof T as SnakeCase]: Snakelize } : `T` + +#### Type parameters + +| Name | +| :------ | +| `T` | + +#### Defined in + +[packages/types/src/shared.ts:957](https://github.com/discordeno/discordeno/blob/b8c25357/packages/types/src/shared.ts#L957) + +## Variables + +### Intents + +• `Const` **Intents**: typeof [`GatewayIntents`](../enums/GatewayIntents.md) = `GatewayIntents` + +https://discord.com/developers/docs/topics/gateway#list-of-intents + +#### Defined in + +[packages/types/src/shared.ts:874](https://github.com/discordeno/discordeno/blob/b8c25357/packages/types/src/shared.ts#L874) diff --git a/website/docs/generated/modules_utils.md b/website/docs/generated/modules_utils.md new file mode 100644 index 000000000..444ae83de --- /dev/null +++ b/website/docs/generated/modules_utils.md @@ -0,0 +1,2000 @@ +[discordeno-monorepo](../README.md) / [Modules](../modules.md) / @discordeno/utils + +# Module: @discordeno/utils + +## Table of contents + +### Enumerations + +- [LogDepth](../enums/LogDepth.md) +- [LogLevels](../enums/LogLevels.md) + +### Classes + +- [Collection](../classes/Collection.md) + +### Interfaces + +- [Code](../interfaces/Code.md) +- [CollectionOptions](../interfaces/CollectionOptions.md) +- [CollectionSweeper](../interfaces/CollectionSweeper.md) +- [LeakyBucket](../interfaces/LeakyBucket.md) +- [PlaceHolderBot](../interfaces/PlaceHolderBot.md) +- [Rgb](../interfaces/Rgb.md) + +### Variables + +- [logger](md#logger) + +### Functions + +- [acquire](md#acquire) +- [avatarUrl](md#avatarurl) +- [bgBlack](md#bgblack) +- [bgBlue](md#bgblue) +- [bgBrightBlack](md#bgbrightblack) +- [bgBrightBlue](md#bgbrightblue) +- [bgBrightCyan](md#bgbrightcyan) +- [bgBrightGreen](md#bgbrightgreen) +- [bgBrightMagenta](md#bgbrightmagenta) +- [bgBrightRed](md#bgbrightred) +- [bgBrightWhite](md#bgbrightwhite) +- [bgBrightYellow](md#bgbrightyellow) +- [bgCyan](md#bgcyan) +- [bgGreen](md#bggreen) +- [bgMagenta](md#bgmagenta) +- [bgRed](md#bgred) +- [bgRgb24](md#bgrgb24) +- [bgRgb8](md#bgrgb8) +- [bgWhite](md#bgwhite) +- [bgYellow](md#bgyellow) +- [black](md#black) +- [blue](md#blue) +- [bold](md#bold) +- [brightBlack](md#brightblack) +- [brightBlue](md#brightblue) +- [brightCyan](md#brightcyan) +- [brightGreen](md#brightgreen) +- [brightMagenta](md#brightmagenta) +- [brightRed](md#brightred) +- [brightWhite](md#brightwhite) +- [brightYellow](md#brightyellow) +- [calculateBits](md#calculatebits) +- [calculatePermissions](md#calculatepermissions) +- [camelToSnakeCase](md#cameltosnakecase) +- [camelize](md#camelize) +- [coerceToFileContent](md#coercetofilecontent) +- [createLeakyBucket](md#createleakybucket) +- [createLogger](md#createlogger) +- [cyan](md#cyan) +- [decode](md#decode) +- [delay](md#delay) +- [dim](md#dim) +- [emojiUrl](md#emojiurl) +- [encode](md#encode) +- [findFiles](md#findfiles) +- [formatImageUrl](md#formatimageurl) +- [getBotIdFromToken](md#getbotidfromtoken) +- [getColorEnabled](md#getcolorenabled) +- [getWidgetImageUrl](md#getwidgetimageurl) +- [gray](md#gray) +- [green](md#green) +- [guildBannerUrl](md#guildbannerurl) +- [guildIconUrl](md#guildiconurl) +- [guildSplashUrl](md#guildsplashurl) +- [hasProperty](md#hasproperty) +- [hidden](md#hidden) +- [iconBigintToHash](md#iconbiginttohash) +- [iconHashToBigInt](md#iconhashtobigint) +- [inverse](md#inverse) +- [isGetMessagesAfter](md#isgetmessagesafter) +- [isGetMessagesAround](md#isgetmessagesaround) +- [isGetMessagesBefore](md#isgetmessagesbefore) +- [isGetMessagesLimit](md#isgetmessageslimit) +- [italic](md#italic) +- [magenta](md#magenta) +- [nextRefill](md#nextrefill) +- [processReactionString](md#processreactionstring) +- [red](md#red) +- [removeTokenPrefix](md#removetokenprefix) +- [reset](md#reset) +- [rgb24](md#rgb24) +- [rgb8](md#rgb8) +- [setColorEnabled](md#setcolorenabled) +- [snakeToCamelCase](md#snaketocamelcase) +- [snakelize](md#snakelize) +- [strikethrough](md#strikethrough) +- [stripColor](md#stripcolor) +- [underline](md#underline) +- [updateTokens](md#updatetokens) +- [urlToBase64](md#urltobase64) +- [white](md#white) +- [yellow](md#yellow) + +## Variables + +### logger + +• `Const` **logger**: `Object` + +#### Type declaration + +| Name | Type | +| :------ | :------ | +| `debug` | (...`args`: `any`[]) => `void` | +| `error` | (...`args`: `any`[]) => `void` | +| `fatal` | (...`args`: `any`[]) => `void` | +| `info` | (...`args`: `any`[]) => `void` | +| `log` | (`level`: [`LogLevels`](../enums/LogLevels.md), ...`args`: `any`[]) => `void` | +| `setDepth` | (`level`: [`LogDepth`](../enums/LogDepth.md)) => `void` | +| `setLevel` | (`level`: [`LogLevels`](../enums/LogLevels.md)) => `void` | +| `warn` | (...`args`: `any`[]) => `void` | + +#### Defined in + +[packages/utils/src/logger.ts:118](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/logger.ts#L118) + +## Functions + +### acquire + +▸ **acquire**(`bucket`, `amount`, `highPriority?`): `Promise`<`void`\> + +#### Parameters + +| Name | Type | Default value | +| :------ | :------ | :------ | +| `bucket` | [`LeakyBucket`](../interfaces/LeakyBucket.md) | `undefined` | +| `amount` | `number` | `undefined` | +| `highPriority` | `boolean` | `false` | + +#### Returns + +`Promise`<`void`\> + +#### Defined in + +[packages/utils/src/bucket.ts:113](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/bucket.ts#L113) + +___ + +### avatarUrl + +▸ **avatarUrl**(`userId`, `discriminator`, `options?`): `string` + +Builds a URL to a user's avatar stored in the Discord CDN. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `userId` | `BigString` | The ID of the user to get the avatar of. | +| `discriminator` | `string` | The user's discriminator. (4-digit tag after the hashtag.) | +| `options?` | `Object` | The parameters for the building of the URL. | +| `options.avatar` | `undefined` \| `BigString` | - | +| `options.format?` | `ImageFormat` | - | +| `options.size?` | `ImageSize` | - | + +#### Returns + +`string` + +The link to the resource. + +#### Defined in + +[packages/utils/src/images.ts:29](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/images.ts#L29) + +___ + +### bgBlack + +▸ **bgBlack**(`str`): `string` + +Set background color to black. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make its background black | + +#### Returns + +`string` + +#### Defined in + +[packages/utils/src/colors.ts:268](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/colors.ts#L268) + +___ + +### bgBlue + +▸ **bgBlue**(`str`): `string` + +Set background color to blue. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make its background blue | + +#### Returns + +`string` + +#### Defined in + +[packages/utils/src/colors.ts:300](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/colors.ts#L300) + +___ + +### bgBrightBlack + +▸ **bgBrightBlack**(`str`): `string` + +Set background color to bright black. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make its background bright-black | + +#### Returns + +`string` + +#### Defined in + +[packages/utils/src/colors.ts:332](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/colors.ts#L332) + +___ + +### bgBrightBlue + +▸ **bgBrightBlue**(`str`): `string` + +Set background color to bright blue. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make its background bright-blue | + +#### Returns + +`string` + +#### Defined in + +[packages/utils/src/colors.ts:364](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/colors.ts#L364) + +___ + +### bgBrightCyan + +▸ **bgBrightCyan**(`str`): `string` + +Set background color to bright cyan. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make its background bright-cyan | + +#### Returns + +`string` + +#### Defined in + +[packages/utils/src/colors.ts:380](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/colors.ts#L380) + +___ + +### bgBrightGreen + +▸ **bgBrightGreen**(`str`): `string` + +Set background color to bright green. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make its background bright-green | + +#### Returns + +`string` + +#### Defined in + +[packages/utils/src/colors.ts:348](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/colors.ts#L348) + +___ + +### bgBrightMagenta + +▸ **bgBrightMagenta**(`str`): `string` + +Set background color to bright magenta. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make its background bright-magenta | + +#### Returns + +`string` + +#### Defined in + +[packages/utils/src/colors.ts:372](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/colors.ts#L372) + +___ + +### bgBrightRed + +▸ **bgBrightRed**(`str`): `string` + +Set background color to bright red. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make its background bright-red | + +#### Returns + +`string` + +#### Defined in + +[packages/utils/src/colors.ts:340](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/colors.ts#L340) + +___ + +### bgBrightWhite + +▸ **bgBrightWhite**(`str`): `string` + +Set background color to bright white. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make its background bright-white | + +#### Returns + +`string` + +#### Defined in + +[packages/utils/src/colors.ts:388](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/colors.ts#L388) + +___ + +### bgBrightYellow + +▸ **bgBrightYellow**(`str`): `string` + +Set background color to bright yellow. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make its background bright-yellow | + +#### Returns + +`string` + +#### Defined in + +[packages/utils/src/colors.ts:356](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/colors.ts#L356) + +___ + +### bgCyan + +▸ **bgCyan**(`str`): `string` + +Set background color to cyan. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make its background cyan | + +#### Returns + +`string` + +#### Defined in + +[packages/utils/src/colors.ts:316](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/colors.ts#L316) + +___ + +### bgGreen + +▸ **bgGreen**(`str`): `string` + +Set background color to green. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make its background green | + +#### Returns + +`string` + +#### Defined in + +[packages/utils/src/colors.ts:284](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/colors.ts#L284) + +___ + +### bgMagenta + +▸ **bgMagenta**(`str`): `string` + +Set background color to magenta. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make its background magenta | + +#### Returns + +`string` + +#### Defined in + +[packages/utils/src/colors.ts:308](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/colors.ts#L308) + +___ + +### bgRed + +▸ **bgRed**(`str`): `string` + +Set background color to red. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make its background red | + +#### Returns + +`string` + +#### Defined in + +[packages/utils/src/colors.ts:276](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/colors.ts#L276) + +___ + +### bgRgb24 + +▸ **bgRgb24**(`str`, `color`): `string` + +Set background color using 24bit rgb. +`color` can be a number in range `0x000000` to `0xffffff` or +an `Rgb`. + +To produce the color magenta: + +```ts + import { bgRgb24 } from "./colors.ts"; + bgRgb24("foo", 0xff00ff); + bgRgb24("foo", {r: 255, g: 0, b: 255}); +``` + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text color to apply 24bit rgb to | +| `color` | `number` \| [`Rgb`](../interfaces/Rgb.md) | code | + +#### Returns + +`string` + +#### Defined in + +[packages/utils/src/colors.ts:461](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/colors.ts#L461) + +___ + +### bgRgb8 + +▸ **bgRgb8**(`str`, `color`): `string` + +Set background color using paletted 8bit colors. +https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text color to apply paletted 8bit background colors to | +| `color` | `number` | code | + +#### Returns + +`string` + +#### Defined in + +[packages/utils/src/colors.ts:420](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/colors.ts#L420) + +___ + +### bgWhite + +▸ **bgWhite**(`str`): `string` + +Set background color to white. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make its background white | + +#### Returns + +`string` + +#### Defined in + +[packages/utils/src/colors.ts:324](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/colors.ts#L324) + +___ + +### bgYellow + +▸ **bgYellow**(`str`): `string` + +Set background color to yellow. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make its background yellow | + +#### Returns + +`string` + +#### Defined in + +[packages/utils/src/colors.ts:292](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/colors.ts#L292) + +___ + +### black + +▸ **black**(`str`): `string` + +Set text color to black. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make black | + +#### Returns + +`string` + +#### Defined in + +[packages/utils/src/colors.ts:132](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/colors.ts#L132) + +___ + +### blue + +▸ **blue**(`str`): `string` + +Set text color to blue. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make blue | + +#### Returns + +`string` + +#### Defined in + +[packages/utils/src/colors.ts:164](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/colors.ts#L164) + +___ + +### bold + +▸ **bold**(`str`): `string` + +Make the text bold. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make bold | + +#### Returns + +`string` + +#### Defined in + +[packages/utils/src/colors.ts:76](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/colors.ts#L76) + +___ + +### brightBlack + +▸ **brightBlack**(`str`): `string` + +Set text color to bright black. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make bright-black | + +#### Returns + +`string` + +#### Defined in + +[packages/utils/src/colors.ts:204](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/colors.ts#L204) + +___ + +### brightBlue + +▸ **brightBlue**(`str`): `string` + +Set text color to bright blue. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make bright-blue | + +#### Returns + +`string` + +#### Defined in + +[packages/utils/src/colors.ts:236](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/colors.ts#L236) + +___ + +### brightCyan + +▸ **brightCyan**(`str`): `string` + +Set text color to bright cyan. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make bright-cyan | + +#### Returns + +`string` + +#### Defined in + +[packages/utils/src/colors.ts:252](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/colors.ts#L252) + +___ + +### brightGreen + +▸ **brightGreen**(`str`): `string` + +Set text color to bright green. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make bright-green | + +#### Returns + +`string` + +#### Defined in + +[packages/utils/src/colors.ts:220](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/colors.ts#L220) + +___ + +### brightMagenta + +▸ **brightMagenta**(`str`): `string` + +Set text color to bright magenta. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make bright-magenta | + +#### Returns + +`string` + +#### Defined in + +[packages/utils/src/colors.ts:244](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/colors.ts#L244) + +___ + +### brightRed + +▸ **brightRed**(`str`): `string` + +Set text color to bright red. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make bright-red | + +#### Returns + +`string` + +#### Defined in + +[packages/utils/src/colors.ts:212](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/colors.ts#L212) + +___ + +### brightWhite + +▸ **brightWhite**(`str`): `string` + +Set text color to bright white. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make bright-white | + +#### Returns + +`string` + +#### Defined in + +[packages/utils/src/colors.ts:260](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/colors.ts#L260) + +___ + +### brightYellow + +▸ **brightYellow**(`str`): `string` + +Set text color to bright yellow. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make bright-yellow | + +#### Returns + +`string` + +#### Defined in + +[packages/utils/src/colors.ts:228](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/colors.ts#L228) + +___ + +### calculateBits + +▸ **calculateBits**(`permissions`): `string` + +This function converts an array of permissions into the bitwise string. + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `permissions` | (``"CREATE_INSTANT_INVITE"`` \| ``"KICK_MEMBERS"`` \| ``"BAN_MEMBERS"`` \| ``"ADMINISTRATOR"`` \| ``"MANAGE_CHANNELS"`` \| ``"MANAGE_GUILD"`` \| ``"ADD_REACTIONS"`` \| ``"VIEW_AUDIT_LOG"`` \| ``"PRIORITY_SPEAKER"`` \| ``"STREAM"`` \| ``"VIEW_CHANNEL"`` \| ``"SEND_MESSAGES"`` \| ``"SEND_TTS_MESSAGES"`` \| ``"MANAGE_MESSAGES"`` \| ``"EMBED_LINKS"`` \| ``"ATTACH_FILES"`` \| ``"READ_MESSAGE_HISTORY"`` \| ``"MENTION_EVERYONE"`` \| ``"USE_EXTERNAL_EMOJIS"`` \| ``"VIEW_GUILD_INSIGHTS"`` \| ``"CONNECT"`` \| ``"SPEAK"`` \| ``"MUTE_MEMBERS"`` \| ``"DEAFEN_MEMBERS"`` \| ``"MOVE_MEMBERS"`` \| ``"USE_VAD"`` \| ``"CHANGE_NICKNAME"`` \| ``"MANAGE_NICKNAMES"`` \| ``"MANAGE_ROLES"`` \| ``"MANAGE_WEBHOOKS"`` \| ``"MANAGE_EMOJIS_AND_STICKERS"`` \| ``"USE_SLASH_COMMANDS"`` \| ``"REQUEST_TO_SPEAK"`` \| ``"MANAGE_EVENTS"`` \| ``"MANAGE_THREADS"`` \| ``"CREATE_PUBLIC_THREADS"`` \| ``"CREATE_PRIVATE_THREADS"`` \| ``"USE_EXTERNAL_STICKERS"`` \| ``"SEND_MESSAGES_IN_THREADS"`` \| ``"USE_EMBEDDED_ACTIVITIES"`` \| ``"MODERATE_MEMBERS"``)[] | + +#### Returns + +`string` + +#### Defined in + +[packages/utils/src/permissions.ts:15](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/permissions.ts#L15) + +___ + +### calculatePermissions + +▸ **calculatePermissions**(`permissionBits`): `PermissionStrings`[] + +This function converts a bitwise string to permission strings + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `permissionBits` | `bigint` | + +#### Returns + +`PermissionStrings`[] + +#### Defined in + +[packages/utils/src/permissions.ts:5](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/permissions.ts#L5) + +___ + +### camelToSnakeCase + +▸ **camelToSnakeCase**(`str`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `str` | `string` | + +#### Returns + +`string` + +#### Defined in + +[packages/utils/src/casing.ts:53](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/casing.ts#L53) + +___ + +### camelize + +▸ **camelize**<`T`\>(`object`): `Camelize`<`T`\> + +#### Type parameters + +| Name | +| :------ | +| `T` | + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `object` | `T` | + +#### Returns + +`Camelize`<`T`\> + +#### Defined in + +[packages/utils/src/casing.ts:3](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/casing.ts#L3) + +___ + +### coerceToFileContent + +▸ **coerceToFileContent**(`value`): value is FileContent + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `value` | `unknown` | + +#### Returns + +value is FileContent + +#### Defined in + +[packages/utils/src/files.ts:13](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/files.ts#L13) + +___ + +### createLeakyBucket + +▸ **createLeakyBucket**(`«destructured»`): [`LeakyBucket`](../interfaces/LeakyBucket.md) + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `«destructured»` | `Omit`<`PickPartial`<[`LeakyBucket`](../interfaces/LeakyBucket.md), ``"max"`` \| ``"refillInterval"`` \| ``"refillAmount"``\>, ``"tokens"``\> & { `tokens?`: `number` } | + +#### Returns + +[`LeakyBucket`](../interfaces/LeakyBucket.md) + +#### Defined in + +[packages/utils/src/bucket.ts:53](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/bucket.ts#L53) + +___ + +### createLogger + +▸ **createLogger**(`«destructured»?`): `Object` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `«destructured»` | `Object` | +| › `logLevel?` | [`LogLevels`](../enums/LogLevels.md) | +| › `name?` | `string` | + +#### Returns + +`Object` + +| Name | Type | +| :------ | :------ | +| `debug` | (...`args`: `any`[]) => `void` | +| `error` | (...`args`: `any`[]) => `void` | +| `fatal` | (...`args`: `any`[]) => `void` | +| `info` | (...`args`: `any`[]) => `void` | +| `log` | (`level`: [`LogLevels`](../enums/LogLevels.md), ...`args`: `any`[]) => `void` | +| `setDepth` | (`level`: [`LogDepth`](../enums/LogDepth.md)) => `void` | +| `setLevel` | (`level`: [`LogLevels`](../enums/LogLevels.md)) => `void` | +| `warn` | (...`args`: `any`[]) => `void` | + +#### Defined in + +[packages/utils/src/logger.ts:34](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/logger.ts#L34) + +___ + +### cyan + +▸ **cyan**(`str`): `string` + +Set text color to cyan. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make cyan | + +#### Returns + +`string` + +#### Defined in + +[packages/utils/src/colors.ts:180](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/colors.ts#L180) + +___ + +### decode + +▸ **decode**(`data`): `Uint8Array` + +CREDIT: https://gist.github.com/enepomnyaschih/72c423f727d395eeaa09697058238727 +Decodes RFC4648 base64 string into an Uint8Array + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `data` | `string` | + +#### Returns + +`Uint8Array` + +#### Defined in + +[packages/utils/src/base64.ts:38](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/base64.ts#L38) + +___ + +### delay + +▸ **delay**(`ms`): `Promise`<`void`\> + +Pause the execution for a given amount of milliseconds. + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `ms` | `number` | + +#### Returns + +`Promise`<`void`\> + +#### Defined in + +[packages/utils/src/utils.ts:2](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/utils.ts#L2) + +___ + +### dim + +▸ **dim**(`str`): `string` + +The text emits only a small amount of light. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to dim | + +#### Returns + +`string` + +#### Defined in + +[packages/utils/src/colors.ts:84](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/colors.ts#L84) + +___ + +### emojiUrl + +▸ **emojiUrl**(`emojiId`, `animated?`): `string` + +Get the url for an emoji. + +#### Parameters + +| Name | Type | Default value | Description | +| :------ | :------ | :------ | :------ | +| `emojiId` | `BigString` | `undefined` | The id of the emoji | +| `animated` | `boolean` | `false` | Whether or not the emoji is animated | + +#### Returns + +`string` + +string + +#### Defined in + +[packages/utils/src/images.ts:17](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/images.ts#L17) + +___ + +### encode + +▸ **encode**(`data`): `string` + +CREDIT: https://gist.github.com/enepomnyaschih/72c423f727d395eeaa09697058238727 +Encodes a given Uint8Array, ArrayBuffer or string into RFC4648 base64 representation + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `data` | `string` \| `ArrayBuffer` | + +#### Returns + +`string` + +#### Defined in + +[packages/utils/src/base64.ts:6](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/base64.ts#L6) + +___ + +### findFiles + +▸ **findFiles**(`file`): `FileContent`[] + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `file` | `unknown` | + +#### Returns + +`FileContent`[] + +#### Defined in + +[packages/utils/src/files.ts:4](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/files.ts#L4) + +___ + +### formatImageUrl + +▸ **formatImageUrl**(`url`, `size?`, `format?`): `string` + +Help format an image url. + +#### Parameters + +| Name | Type | Default value | +| :------ | :------ | :------ | +| `url` | `string` | `undefined` | +| `size` | `ImageSize` | `128` | +| `format?` | `ImageFormat` | `undefined` | + +#### Returns + +`string` + +#### Defined in + +[packages/utils/src/images.ts:6](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/images.ts#L6) + +___ + +### getBotIdFromToken + +▸ **getBotIdFromToken**(`token`): `bigint` + +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. + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `token` | `string` | + +#### Returns + +`bigint` + +#### Defined in + +[packages/utils/src/token.ts:16](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/token.ts#L16) + +___ + +### getColorEnabled + +▸ **getColorEnabled**(): `boolean` + +Get whether text color change is enabled or disabled. + +#### Returns + +`boolean` + +#### Defined in + +[packages/utils/src/colors.ts:38](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/colors.ts#L38) + +___ + +### getWidgetImageUrl + +▸ **getWidgetImageUrl**(`guildId`, `options?`): `string` + +Builds a URL to the guild widget image stored in the Discord CDN. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `guildId` | `BigString` | The ID of the guild to get the link to the widget image for. | +| `options?` | `GetGuildWidgetImageQuery` | The parameters for the building of the URL. | + +#### Returns + +`string` + +The link to the resource. + +#### Defined in + +[packages/utils/src/images.ts:127](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/images.ts#L127) + +___ + +### gray + +▸ **gray**(`str`): `string` + +Set text color to gray. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make gray | + +#### Returns + +`string` + +#### Defined in + +[packages/utils/src/colors.ts:196](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/colors.ts#L196) + +___ + +### green + +▸ **green**(`str`): `string` + +Set text color to green. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make green | + +#### Returns + +`string` + +#### Defined in + +[packages/utils/src/colors.ts:148](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/colors.ts#L148) + +___ + +### guildBannerUrl + +▸ **guildBannerUrl**(`guildId`, `options`): `string` \| `undefined` + +Builds a URL to the guild banner stored in the Discord CDN. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `guildId` | `BigString` | The ID of the guild to get the link to the banner for. | +| `options` | `Object` | The parameters for the building of the URL. | +| `options.banner?` | `string` \| `bigint` | - | +| `options.format?` | `ImageFormat` | - | +| `options.size?` | `ImageSize` | - | + +#### Returns + +`string` \| `undefined` + +The link to the resource or `undefined` if no banner has been set. + +#### Defined in + +[packages/utils/src/images.ts:54](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/images.ts#L54) + +___ + +### guildIconUrl + +▸ **guildIconUrl**(`guildId`, `imageHash`, `options?`): `string` \| `undefined` + +Builds a URL to the guild icon stored in the Discord CDN. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `guildId` | `BigString` | The ID of the guild to get the link to the banner for. | +| `imageHash` | `undefined` \| `BigString` | - | +| `options?` | `Object` | The parameters for the building of the URL. | +| `options.format?` | `ImageFormat` | - | +| `options.size?` | `ImageSize` | - | + +#### Returns + +`string` \| `undefined` + +The link to the resource or `undefined` if no banner has been set. + +#### Defined in + +[packages/utils/src/images.ts:78](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/images.ts#L78) + +___ + +### guildSplashUrl + +▸ **guildSplashUrl**(`guildId`, `imageHash`, `options?`): `string` \| `undefined` + +Builds the URL to a guild splash stored in the Discord CDN. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `guildId` | `BigString` | The ID of the guild to get the splash of. | +| `imageHash` | `undefined` \| `BigString` | The hash identifying the splash image. | +| `options?` | `Object` | The parameters for the building of the URL. | +| `options.format?` | `ImageFormat` | - | +| `options.size?` | `ImageSize` | - | + +#### Returns + +`string` \| `undefined` + +The link to the resource or `undefined` if the guild does not have a splash image set. + +#### Defined in + +[packages/utils/src/images.ts:103](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/images.ts#L103) + +___ + +### hasProperty + +▸ **hasProperty**<`T`, `Y`\>(`obj`, `prop`): obj is T & Record + +TS save way to check if a property exists in an object + +#### Type parameters + +| Name | Type | +| :------ | :------ | +| `T` | extends `Object` | +| `Y` | extends `PropertyKey` = `string` | + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `obj` | `T` | +| `prop` | `Y` | + +#### Returns + +obj is T & Record + +#### Defined in + +[packages/utils/src/utils.ts:15](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/utils.ts#L15) + +___ + +### hidden + +▸ **hidden**(`str`): `string` + +Make the text hidden. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to hide | + +#### Returns + +`string` + +#### Defined in + +[packages/utils/src/colors.ts:116](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/colors.ts#L116) + +___ + +### iconBigintToHash + +▸ **iconBigintToHash**(`icon`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `icon` | `bigint` | + +#### Returns + +`string` + +#### Defined in + +[packages/utils/src/hash.ts:14](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/hash.ts#L14) + +___ + +### iconHashToBigInt + +▸ **iconHashToBigInt**(`hash`): `bigint` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `hash` | `string` | + +#### Returns + +`bigint` + +#### Defined in + +[packages/utils/src/hash.ts:1](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/hash.ts#L1) + +___ + +### inverse + +▸ **inverse**(`str`): `string` + +Invert background color and text color. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to invert its color | + +#### Returns + +`string` + +#### Defined in + +[packages/utils/src/colors.ts:108](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/colors.ts#L108) + +___ + +### isGetMessagesAfter + +▸ **isGetMessagesAfter**(`options`): options is GetMessagesAfter + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `options` | `GetMessagesOptions` | + +#### Returns + +options is GetMessagesAfter + +#### Defined in + +[packages/utils/src/typeguards.ts:4](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/typeguards.ts#L4) + +___ + +### isGetMessagesAround + +▸ **isGetMessagesAround**(`options`): options is GetMessagesAround + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `options` | `GetMessagesOptions` | + +#### Returns + +options is GetMessagesAround + +#### Defined in + +[packages/utils/src/typeguards.ts:12](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/typeguards.ts#L12) + +___ + +### isGetMessagesBefore + +▸ **isGetMessagesBefore**(`options`): options is GetMessagesBefore + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `options` | `GetMessagesOptions` | + +#### Returns + +options is GetMessagesBefore + +#### Defined in + +[packages/utils/src/typeguards.ts:8](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/typeguards.ts#L8) + +___ + +### isGetMessagesLimit + +▸ **isGetMessagesLimit**(`options`): options is GetMessagesLimit + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `options` | `GetMessagesOptions` | + +#### Returns + +options is GetMessagesLimit + +#### Defined in + +[packages/utils/src/typeguards.ts:16](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/typeguards.ts#L16) + +___ + +### italic + +▸ **italic**(`str`): `string` + +Make the text italic. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make italic | + +#### Returns + +`string` + +#### Defined in + +[packages/utils/src/colors.ts:92](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/colors.ts#L92) + +___ + +### magenta + +▸ **magenta**(`str`): `string` + +Set text color to magenta. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make magenta | + +#### Returns + +`string` + +#### Defined in + +[packages/utils/src/colors.ts:172](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/colors.ts#L172) + +___ + +### nextRefill + +▸ **nextRefill**(`bucket`): `number` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `bucket` | [`LeakyBucket`](../interfaces/LeakyBucket.md) | + +#### Returns + +`number` + +#### Defined in + +[packages/utils/src/bucket.ts:106](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/bucket.ts#L106) + +___ + +### processReactionString + +▸ **processReactionString**(`reaction`): `string` + +Converts an reaction emoji unicode string to the discord required form of name:id + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `reaction` | `string` | + +#### Returns + +`string` + +#### Defined in + +[packages/utils/src/reactions.ts:2](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/reactions.ts#L2) + +___ + +### red + +▸ **red**(`str`): `string` + +Set text color to red. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make red | + +#### Returns + +`string` + +#### Defined in + +[packages/utils/src/colors.ts:140](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/colors.ts#L140) + +___ + +### removeTokenPrefix + +▸ **removeTokenPrefix**(`token?`, `type?`): `string` + +Removes the Bot before the token. + +#### Parameters + +| Name | Type | Default value | +| :------ | :------ | :------ | +| `token?` | `string` | `undefined` | +| `type` | ``"GATEWAY"`` \| ``"REST"`` | `'REST'` | + +#### Returns + +`string` + +#### Defined in + +[packages/utils/src/token.ts:4](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/token.ts#L4) + +___ + +### reset + +▸ **reset**(`str`): `string` + +Reset the text modified + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to reset | + +#### Returns + +`string` + +#### Defined in + +[packages/utils/src/colors.ts:68](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/colors.ts#L68) + +___ + +### rgb24 + +▸ **rgb24**(`str`, `color`): `string` + +Set text color using 24bit rgb. +`color` can be a number in range `0x000000` to `0xffffff` or +an `Rgb`. + +To produce the color magenta: + +```ts + import { rgb24 } from "./colors.ts"; + rgb24("foo", 0xff00ff); + rgb24("foo", {r: 255, g: 0, b: 255}); +``` + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text color to apply 24bit rgb to | +| `color` | `number` \| [`Rgb`](../interfaces/Rgb.md) | code | + +#### Returns + +`string` + +#### Defined in + +[packages/utils/src/colors.ts:439](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/colors.ts#L439) + +___ + +### rgb8 + +▸ **rgb8**(`str`, `color`): `string` + +Set text color using paletted 8bit colors. +https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text color to apply paletted 8bit colors to | +| `color` | `number` | code | + +#### Returns + +`string` + +#### Defined in + +[packages/utils/src/colors.ts:410](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/colors.ts#L410) + +___ + +### setColorEnabled + +▸ **setColorEnabled**(`value`): `void` + +Set changing text color to enabled or disabled + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `value` | `boolean` | + +#### Returns + +`void` + +#### Defined in + +[packages/utils/src/colors.ts:29](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/colors.ts#L29) + +___ + +### snakeToCamelCase + +▸ **snakeToCamelCase**(`str`): `string` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `str` | `string` | + +#### Returns + +`string` + +#### Defined in + +[packages/utils/src/casing.ts:36](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/casing.ts#L36) + +___ + +### snakelize + +▸ **snakelize**<`T`\>(`object`): `Snakelize`<`T`\> + +#### Type parameters + +| Name | +| :------ | +| `T` | + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `object` | `T` | + +#### Returns + +`Snakelize`<`T`\> + +#### Defined in + +[packages/utils/src/casing.ts:19](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/casing.ts#L19) + +___ + +### strikethrough + +▸ **strikethrough**(`str`): `string` + +Put horizontal line through the center of the text. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to strike through | + +#### Returns + +`string` + +#### Defined in + +[packages/utils/src/colors.ts:124](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/colors.ts#L124) + +___ + +### stripColor + +▸ **stripColor**(`string`): `string` + +Remove ANSI escape codes from the string. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `string` | `string` | to remove ANSI escape codes from | + +#### Returns + +`string` + +#### Defined in + +[packages/utils/src/colors.ts:481](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/colors.ts#L481) + +___ + +### underline + +▸ **underline**(`str`): `string` + +Make the text underline. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to underline | + +#### Returns + +`string` + +#### Defined in + +[packages/utils/src/colors.ts:100](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/colors.ts#L100) + +___ + +### updateTokens + +▸ **updateTokens**(`bucket`): `number` + +Update the tokens of that bucket. + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `bucket` | [`LeakyBucket`](../interfaces/LeakyBucket.md) | + +#### Returns + +`number` + +The amount of current available tokens. + +#### Defined in + +[packages/utils/src/bucket.ts:95](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/bucket.ts#L95) + +___ + +### urlToBase64 + +▸ **urlToBase64**(`url`): `Promise`<`string`\> + +Converts a url to base 64. Useful for example, uploading/creating server emojis. + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `url` | `string` | + +#### Returns + +`Promise`<`string`\> + +#### Defined in + +[packages/utils/src/urlToBase64.ts:4](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/urlToBase64.ts#L4) + +___ + +### white + +▸ **white**(`str`): `string` + +Set text color to white. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make white | + +#### Returns + +`string` + +#### Defined in + +[packages/utils/src/colors.ts:188](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/colors.ts#L188) + +___ + +### yellow + +▸ **yellow**(`str`): `string` + +Set text color to yellow. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `str` | `string` | text to make yellow | + +#### Returns + +`string` + +#### Defined in + +[packages/utils/src/colors.ts:156](https://github.com/discordeno/discordeno/blob/b8c25357/packages/utils/src/colors.ts#L156) diff --git a/website/docs/tutorial-extras/manage-docs-versions.md b/website/docs/tutorial-extras/manage-docs-versions.md index e12c3f344..18c909f58 100644 --- a/website/docs/tutorial-extras/manage-docs-versions.md +++ b/website/docs/tutorial-extras/manage-docs-versions.md @@ -40,7 +40,7 @@ module.exports = { ], }, }, -}; +} ``` The docs version dropdown appears in your navbar: diff --git a/website/docs/tutorial-extras/translate-your-site.md b/website/docs/tutorial-extras/translate-your-site.md index caeaffb05..cbad169ea 100644 --- a/website/docs/tutorial-extras/translate-your-site.md +++ b/website/docs/tutorial-extras/translate-your-site.md @@ -16,7 +16,7 @@ module.exports = { defaultLocale: 'en', locales: ['en', 'fr'], }, -}; +} ``` ## Translate a doc @@ -66,7 +66,7 @@ module.exports = { ], }, }, -}; +} ``` The locale dropdown now appears in your navbar: diff --git a/website/package.json b/website/package.json index af00ed9c0..63d10cc25 100644 --- a/website/package.json +++ b/website/package.json @@ -15,6 +15,7 @@ "typecheck": "tsc" }, "dependencies": { + "@babel/plugin-syntax-flow": "^7.18.6", "@docusaurus/core": "2.3.1", "@docusaurus/preset-classic": "2.3.1", "@easyops-cn/docusaurus-search-local": "^0.34.0", diff --git a/website/src/components/HomepageFeatures/index.tsx b/website/src/components/HomepageFeatures/index.tsx index e1e468565..444878afa 100644 --- a/website/src/components/HomepageFeatures/index.tsx +++ b/website/src/components/HomepageFeatures/index.tsx @@ -1,17 +1,17 @@ -import React from 'react'; -import clsx from 'clsx'; -import styles from './styles.module.css'; +import React from 'react' +import clsx from 'clsx' +import styles from './styles.module.css' type FeatureItem = { - title: string; - Svg: React.ComponentType>; - description: JSX.Element; -}; + title: string + Svg: React.ComponentType> + description: JSX.Element +} const FeatureList: FeatureItem[] = [ { - title: "REST does not rest!", - Svg: require("@site/static/img/undraw_docusaurus_mountain.svg").default, + title: 'REST does not rest!', + Svg: require('@site/static/img/undraw_docusaurus_mountain.svg').default, description: ( <>
          @@ -26,14 +26,14 @@ const FeatureList: FeatureItem[] = [ ), }, { - title: "Zero Downtime Updates", - Svg: require("@site/static/img/undraw_docusaurus_tree.svg").default, + title: 'Zero Downtime Updates', + Svg: require('@site/static/img/undraw_docusaurus_tree.svg').default, description: ( <>
          • Instant bot restarts/updates.
          • - Automated sharding &{" "} + Automated sharding &{' '} re @@ -48,8 +48,8 @@ const FeatureList: FeatureItem[] = [ ), }, { - title: "No More Forks!", - Svg: require("@site/static/img/undraw_docusaurus_react.svg").default, + title: 'No More Forks!', + Svg: require('@site/static/img/undraw_docusaurus_react.svg').default, description: ( <>
              @@ -63,9 +63,9 @@ const FeatureList: FeatureItem[] = [ ), }, -]; +] -function Feature({title, Svg, description}: FeatureItem) { +function Feature({ title, Svg, description }: FeatureItem) { return (
              @@ -76,7 +76,7 @@ function Feature({title, Svg, description}: FeatureItem) {

              {description}

              - ); + ) } export default function HomepageFeatures(): JSX.Element { @@ -90,5 +90,5 @@ export default function HomepageFeatures(): JSX.Element {
        - ); + ) } diff --git a/website/src/pages/index.tsx b/website/src/pages/index.tsx index 899ab5550..397ca1e43 100644 --- a/website/src/pages/index.tsx +++ b/website/src/pages/index.tsx @@ -1,41 +1,37 @@ -import React from 'react'; -import clsx from 'clsx'; -import Link from '@docusaurus/Link'; -import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; -import Layout from '@theme/Layout'; -import HomepageFeatures from '@site/src/components/HomepageFeatures'; +import React from 'react' +import clsx from 'clsx' +import Link from '@docusaurus/Link' +import useDocusaurusContext from '@docusaurus/useDocusaurusContext' +import Layout from '@theme/Layout' +import HomepageFeatures from '@site/src/components/HomepageFeatures' -import styles from './index.module.css'; +import styles from './index.module.css' function HomepageHeader() { - const {siteConfig} = useDocusaurusContext(); + const { siteConfig } = useDocusaurusContext() return (

        It's time to ditch Eris and Discord.JS

        Discordeno - {siteConfig.tagline}

        - + Learn Discordeno!
        - ); + ) } export default function Home(): JSX.Element { - const {siteConfig} = useDocusaurusContext(); + const { siteConfig } = useDocusaurusContext() return ( - +
        - ); + ) } diff --git a/website/yarn.lock b/website/yarn.lock index f65c1d770..440f57f49 100644 --- a/website/yarn.lock +++ b/website/yarn.lock @@ -829,6 +829,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-syntax-flow@npm:^7.18.6": + version: 7.18.6 + resolution: "@babel/plugin-syntax-flow@npm:7.18.6" + dependencies: + "@babel/helper-plugin-utils": ^7.18.6 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: abe82062b3eef14de7d2b3c0e4fecf80a3e796ca497e9df616d12dd250968abf71495ee85a955b43a6c827137203f0c409450cf792732ed0d6907c806580ea71 + languageName: node + linkType: hard + "@babel/plugin-syntax-import-assertions@npm:^7.20.0": version: 7.20.0 resolution: "@babel/plugin-syntax-import-assertions@npm:7.20.0" @@ -10854,6 +10865,7 @@ __metadata: version: 0.0.0-use.local resolution: "website@workspace:." dependencies: + "@babel/plugin-syntax-flow": ^7.18.6 "@docusaurus/core": 2.3.1 "@docusaurus/module-type-aliases": 2.3.1 "@docusaurus/preset-classic": 2.3.1