@seedcord/gateway 0.1.0-next.1 → 0.1.0-next.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +196 -330
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +17 -90
- package/dist/index.mjs +166 -304
- package/dist/index.mjs.map +1 -1
- package/package.json +8 -8
package/dist/index.mjs
CHANGED
|
@@ -1,21 +1,24 @@
|
|
|
1
1
|
import "reflect-metadata";
|
|
2
|
+
import { installNodeDefaults } from "@seedcord/logger/node";
|
|
2
3
|
import { BuilderComponent, CustomId, DispatchContext, Fault, Notice, RegisterCommand, RowComponent, Silence, defineGate, paginate } from "@seedcord/core";
|
|
3
|
-
import { CommandMetadataKey, ComponentDefsKey, EventMetadataKey, GateNotice, GatedMetadataKey, InteractionMetadataKey, InteractionRouteKeys, InteractionRoutes, MiddlewareMetadataKey, NotInGuild, NoticeCard, PAGE_MAX, SubscribeMetadataKey, decodeFor, pageCursor, pickNotice, prefixOf, routeIdOf, runHandlerGates, setBotColor } from "@seedcord/core/internal";
|
|
4
|
+
import { CommandMetadataKey, ComponentDefsKey, EventMetadataKey, GateNotice, GatedMetadataKey, HmrManager, InteractionMetadataKey, InteractionRouteKeys, InteractionRoutes, MiddlewareMetadataKey, NotInGuild, NoticeCard, PAGE_MAX, SubscribeMetadataKey, decodeFor, getDevChannel, pageCursor, pickNotice, prefixOf, routeIdOf, runHandlerGates, setBotColor } from "@seedcord/core/internal";
|
|
4
5
|
import { ApplicationCommandType, AttachmentBuilder, ButtonStyle, Client, Collection, ComponentType, DiscordAPIError, Events, Guild, GuildMember, Message, MessageFlags, PermissionFlagsBits, RESTJSONErrorCodes, Role, SeparatorSpacingSize, SnowflakeUtil, TextChannel, User, WebhookClient, chatInputApplicationCommandMention } from "discord.js";
|
|
5
6
|
import { SeedcordErrorCode } from "@seedcord/errors";
|
|
6
7
|
import { SeedcordError, SeedcordRangeError, SeedcordTypeError, validateDiscordToken } from "@seedcord/errors/internal";
|
|
7
|
-
import { filterCirculars, formatFilePath, hasKeys, prettify
|
|
8
|
-
import {
|
|
9
|
-
import chalk from "chalk";
|
|
8
|
+
import { filterCirculars, formatFilePath, hasKeys, prettify } from "@seedcord/utils";
|
|
9
|
+
import { Logger, LoggerChannelRegistry, paint } from "@seedcord/logger";
|
|
10
10
|
import { ActionRowBuilder, ButtonBuilder, ContextMenuCommandBuilder, SlashCommandBuilder, TextDisplayBuilder } from "@discordjs/builders";
|
|
11
11
|
import { buildSlashRoute, routeLeavesOf } from "@seedcord/utils/internal";
|
|
12
12
|
import { TypedEventEmitter } from "@seedcord/event-emitter";
|
|
13
|
-
import { existsSync } from "node:fs";
|
|
14
|
-
import { resolve } from "node:path";
|
|
15
|
-
import { pathToFileURL } from "node:url";
|
|
16
13
|
import { MemoryRateLimiter } from "@seedcord/rate-limiter";
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
14
|
+
import { CoordinatedShutdown, CoordinatedStartup, HealthCheck, ShutdownPhase, StartupPhase } from "@seedcord/services";
|
|
15
|
+
import { SeedcordBrand } from "@seedcord/types/internal";
|
|
16
|
+
import { Envapter } from "envapt";
|
|
17
|
+
import chalk from "chalk";
|
|
18
|
+
import { Envapt } from "envapt/legacy";
|
|
19
|
+
import { resolve } from "node:path";
|
|
20
|
+
import { HmrModuleHandler } from "@seedcord/core/hmr";
|
|
21
|
+
import { traverseDirectory } from "@seedcord/utils/node";
|
|
19
22
|
import * as crypto from "node:crypto";
|
|
20
23
|
|
|
21
24
|
export * from "@seedcord/core"
|
|
@@ -24,12 +27,18 @@ export * from "@seedcord/errors"
|
|
|
24
27
|
|
|
25
28
|
export * from "@seedcord/utils"
|
|
26
29
|
|
|
27
|
-
export * from "@seedcord/
|
|
30
|
+
export * from "@seedcord/logger"
|
|
28
31
|
|
|
29
32
|
export * from "@seedcord/event-emitter"
|
|
30
33
|
|
|
31
34
|
export * from "@seedcord/rate-limiter"
|
|
32
35
|
|
|
36
|
+
export * from "@seedcord/services"
|
|
37
|
+
|
|
38
|
+
//#region src/logger-bootstrap.ts
|
|
39
|
+
installNodeDefaults();
|
|
40
|
+
|
|
41
|
+
//#endregion
|
|
33
42
|
//#region src/bot/decorators/Events.ts
|
|
34
43
|
/**
|
|
35
44
|
* Registers an event handler class with one or more Discord.js events.
|
|
@@ -673,7 +682,7 @@ var EmojiInjector = class {
|
|
|
673
682
|
async init() {
|
|
674
683
|
this.clearEmojis();
|
|
675
684
|
if (!this.core.config.bot.emojis || Object.keys(this.core.config.bot.emojis).length === 0) {
|
|
676
|
-
this.logger.debug(
|
|
685
|
+
this.logger.debug("No emojis configured, skipping emoji injection.");
|
|
677
686
|
return;
|
|
678
687
|
}
|
|
679
688
|
const configEmojis = this.core.config.bot.emojis;
|
|
@@ -1230,16 +1239,6 @@ async function getConfirmation(interaction, prompt, options) {
|
|
|
1230
1239
|
return confirmed;
|
|
1231
1240
|
}
|
|
1232
1241
|
|
|
1233
|
-
//#endregion
|
|
1234
|
-
//#region src/hmr/devChannel.ts
|
|
1235
|
-
let channel;
|
|
1236
|
-
function setDevChannel(next) {
|
|
1237
|
-
channel = next;
|
|
1238
|
-
}
|
|
1239
|
-
function getDevChannel() {
|
|
1240
|
-
return channel;
|
|
1241
|
-
}
|
|
1242
|
-
|
|
1243
1242
|
//#endregion
|
|
1244
1243
|
//#region src/interfaces/Plugin.ts
|
|
1245
1244
|
/**
|
|
@@ -2160,171 +2159,6 @@ var WebhookLog = class extends Subscriber {
|
|
|
2160
2159
|
}
|
|
2161
2160
|
};
|
|
2162
2161
|
|
|
2163
|
-
//#endregion
|
|
2164
|
-
//#region src/hmr/HmrModuleHandler.ts
|
|
2165
|
-
/**
|
|
2166
|
-
* Reloads THandler and optional TMiddleware modules on HMR updates.
|
|
2167
|
-
*
|
|
2168
|
-
* You can either implement a custom `onHmr()` method in your class by extending `HmrAware`, or if it's a plugin, override the existing `onHmr()` with fully custom logic. Or, use this class's `handle()` method inside your `onHmr()` to get standard HMR handling for your modules based on the provided options you give to the constructor.
|
|
2169
|
-
*
|
|
2170
|
-
* This is only useful during development.
|
|
2171
|
-
*/
|
|
2172
|
-
var HmrModuleHandler = class {
|
|
2173
|
-
store;
|
|
2174
|
-
options;
|
|
2175
|
-
constructor(options) {
|
|
2176
|
-
this.options = {
|
|
2177
|
-
...options,
|
|
2178
|
-
logger: options.logger.inChannel("hmr")
|
|
2179
|
-
};
|
|
2180
|
-
this.store = {
|
|
2181
|
-
fileToHandlers: /* @__PURE__ */ new Map(),
|
|
2182
|
-
fileToMiddlewares: /* @__PURE__ */ new Map(),
|
|
2183
|
-
handlerArtifacts: /* @__PURE__ */ new Map()
|
|
2184
|
-
};
|
|
2185
|
-
}
|
|
2186
|
-
/**
|
|
2187
|
-
* Handles an HMR update event by reloading affected modules based on the event details and config. It receives an {@link HmrUpdateEvent}, then checks the type of update.
|
|
2188
|
-
*
|
|
2189
|
-
* - If it's a deletion, it unloads the module.
|
|
2190
|
-
* - If it's an update/creation, it checks if the file is tracked, unloads it if so, then reloads the file if it is in the handlers or middlewares directory and is a valid handler/middleware.
|
|
2191
|
-
*/
|
|
2192
|
-
async handle(event) {
|
|
2193
|
-
const { file, affectedModules, type } = event;
|
|
2194
|
-
const { logger, handlersDir, middlewaresDir } = this.options;
|
|
2195
|
-
if (type === "delete" || type === "deleteDir") {
|
|
2196
|
-
this.unload(file);
|
|
2197
|
-
return;
|
|
2198
|
-
}
|
|
2199
|
-
if (type === "update" && !existsSync(file)) {
|
|
2200
|
-
if (this.isTracked(file)) {
|
|
2201
|
-
logger.info(`Received update for non-existent file: ${formatFilePath(file)}, treating as delete`);
|
|
2202
|
-
this.unload(file);
|
|
2203
|
-
}
|
|
2204
|
-
return;
|
|
2205
|
-
}
|
|
2206
|
-
const rollbackEnabled = event.rollback ?? true;
|
|
2207
|
-
const filesToReload = affectedModules && affectedModules.length > 0 ? affectedModules : [file];
|
|
2208
|
-
const absHandlersDir = resolve(process.cwd(), handlersDir);
|
|
2209
|
-
const absMiddlewaresDir = middlewaresDir ? resolve(process.cwd(), middlewaresDir) : null;
|
|
2210
|
-
for (const fileToReload of filesToReload) {
|
|
2211
|
-
const isHandler = fileToReload.startsWith(absHandlersDir);
|
|
2212
|
-
const isMiddleware = absMiddlewaresDir ? fileToReload.startsWith(absMiddlewaresDir) : false;
|
|
2213
|
-
if (!isHandler && !isMiddleware) continue;
|
|
2214
|
-
await this.reloadWithRollback(fileToReload, rollbackEnabled);
|
|
2215
|
-
}
|
|
2216
|
-
}
|
|
2217
|
-
async reloadWithRollback(file, rollbackEnabled) {
|
|
2218
|
-
const { logger } = this.options;
|
|
2219
|
-
const snapshot = this.snapshotUnits(file);
|
|
2220
|
-
this.unload(file);
|
|
2221
|
-
if (await this.reloadFile(file)) return;
|
|
2222
|
-
this.unload(file);
|
|
2223
|
-
if (!rollbackEnabled) return;
|
|
2224
|
-
this.restoreUnits(file, snapshot);
|
|
2225
|
-
logger.warn(`${chalk.yellow.bold("Rolled back")} ${chalk.gray(formatFilePath(file))} to the last-good version`);
|
|
2226
|
-
}
|
|
2227
|
-
/**
|
|
2228
|
-
* Tracks a handler module as being loaded from a specific file.
|
|
2229
|
-
* @param file - The file path the handler was loaded from.
|
|
2230
|
-
* @param handler - The handler module instance.
|
|
2231
|
-
*/
|
|
2232
|
-
trackHandler(file, handler) {
|
|
2233
|
-
let set = this.store.fileToHandlers.get(file);
|
|
2234
|
-
if (!set) {
|
|
2235
|
-
set = /* @__PURE__ */ new Set();
|
|
2236
|
-
this.store.fileToHandlers.set(file, set);
|
|
2237
|
-
}
|
|
2238
|
-
set.add(handler);
|
|
2239
|
-
if (this.options.getArtifacts) {
|
|
2240
|
-
const artifacts = this.options.getArtifacts(handler);
|
|
2241
|
-
this.store.handlerArtifacts.set(handler, artifacts);
|
|
2242
|
-
}
|
|
2243
|
-
}
|
|
2244
|
-
/**
|
|
2245
|
-
* Tracks a middleware module as being loaded from a specific file.
|
|
2246
|
-
* @param file - The file path the middleware was loaded from.
|
|
2247
|
-
* @param middleware - The middleware module instance.
|
|
2248
|
-
*/
|
|
2249
|
-
trackMiddleware(file, middleware) {
|
|
2250
|
-
let set = this.store.fileToMiddlewares.get(file);
|
|
2251
|
-
if (!set) {
|
|
2252
|
-
set = /* @__PURE__ */ new Set();
|
|
2253
|
-
this.store.fileToMiddlewares.set(file, set);
|
|
2254
|
-
}
|
|
2255
|
-
set.add(middleware);
|
|
2256
|
-
}
|
|
2257
|
-
isTracked(file) {
|
|
2258
|
-
return this.store.fileToHandlers.has(file) || this.store.fileToMiddlewares.has(file);
|
|
2259
|
-
}
|
|
2260
|
-
unload(file) {
|
|
2261
|
-
const { logger } = this.options;
|
|
2262
|
-
const handlers = this.store.fileToHandlers.get(file);
|
|
2263
|
-
if (handlers) {
|
|
2264
|
-
for (const handler of handlers) {
|
|
2265
|
-
const artifacts = this.store.handlerArtifacts.get(handler);
|
|
2266
|
-
this.options.unregisterHandler(handler, artifacts);
|
|
2267
|
-
this.store.handlerArtifacts.delete(handler);
|
|
2268
|
-
const name = handler.name ?? "Handler";
|
|
2269
|
-
logger.info(`${chalk.red.bold("Unloaded")} ${chalk.cyan.bold(name)} from ${chalk.gray(formatFilePath(file))}`);
|
|
2270
|
-
}
|
|
2271
|
-
this.store.fileToHandlers.delete(file);
|
|
2272
|
-
}
|
|
2273
|
-
const middlewares = this.store.fileToMiddlewares.get(file);
|
|
2274
|
-
if (middlewares) {
|
|
2275
|
-
for (const middleware of middlewares) {
|
|
2276
|
-
this.options.unregisterMiddleware?.(middleware);
|
|
2277
|
-
const name = middleware.name ?? "Middleware";
|
|
2278
|
-
logger.info(`${chalk.red.bold("Unloaded")} ${chalk.cyan.bold(name)} from ${chalk.gray(formatFilePath(file))}`);
|
|
2279
|
-
}
|
|
2280
|
-
this.store.fileToMiddlewares.delete(file);
|
|
2281
|
-
}
|
|
2282
|
-
}
|
|
2283
|
-
async reloadFile(file) {
|
|
2284
|
-
const { logger, isHandler, isMiddleware, registerHandler, registerMiddleware } = this.options;
|
|
2285
|
-
if (!existsSync(file)) {
|
|
2286
|
-
logger.info(`File does not exist, skipping reload: ${formatFilePath(file)}`);
|
|
2287
|
-
return false;
|
|
2288
|
-
}
|
|
2289
|
-
try {
|
|
2290
|
-
let fileUrl = pathToFileURL(file).href;
|
|
2291
|
-
if (process.env.VITEST === "true") fileUrl += `?update=${Date.now()}`;
|
|
2292
|
-
const imported = await import(fileUrl);
|
|
2293
|
-
for (const val of Object.values(imported)) if (isHandler(val)) {
|
|
2294
|
-
registerHandler(val, file);
|
|
2295
|
-
this.trackHandler(file, val);
|
|
2296
|
-
const name = val.name ?? "Handler";
|
|
2297
|
-
logger.info(`${chalk.blue.bold("Reloaded")} ${chalk.cyan.bold(name)} from ${chalk.gray(formatFilePath(file))}`);
|
|
2298
|
-
} else if (isMiddleware && registerMiddleware && isMiddleware(val)) {
|
|
2299
|
-
registerMiddleware(val, file);
|
|
2300
|
-
this.trackMiddleware(file, val);
|
|
2301
|
-
const name = val.name ?? "Middleware";
|
|
2302
|
-
logger.info(`${chalk.blue.bold("Reloaded")} ${chalk.cyan.bold(name)} from ${chalk.gray(formatFilePath(file))}`);
|
|
2303
|
-
}
|
|
2304
|
-
return true;
|
|
2305
|
-
} catch (error) {
|
|
2306
|
-
logger.error(`Failed to reload file: ${file}`, error);
|
|
2307
|
-
return false;
|
|
2308
|
-
}
|
|
2309
|
-
}
|
|
2310
|
-
snapshotUnits(file) {
|
|
2311
|
-
return {
|
|
2312
|
-
handlers: [...this.store.fileToHandlers.get(file) ?? []],
|
|
2313
|
-
middlewares: [...this.store.fileToMiddlewares.get(file) ?? []]
|
|
2314
|
-
};
|
|
2315
|
-
}
|
|
2316
|
-
restoreUnits(file, snapshot) {
|
|
2317
|
-
for (const handler of snapshot.handlers) {
|
|
2318
|
-
this.options.registerHandler(handler, file);
|
|
2319
|
-
this.trackHandler(file, handler);
|
|
2320
|
-
}
|
|
2321
|
-
if (this.options.registerMiddleware) for (const middleware of snapshot.middlewares) {
|
|
2322
|
-
this.options.registerMiddleware(middleware, file);
|
|
2323
|
-
this.trackMiddleware(file, middleware);
|
|
2324
|
-
}
|
|
2325
|
-
}
|
|
2326
|
-
};
|
|
2327
|
-
|
|
2328
2162
|
//#endregion
|
|
2329
2163
|
//#region src/bot/utilities/miscellaneous/contextMenuLeaves.ts
|
|
2330
2164
|
/**
|
|
@@ -2385,6 +2219,8 @@ var CommandRegistry = class {
|
|
|
2385
2219
|
globalCommands = [];
|
|
2386
2220
|
guildCommands = new Collection();
|
|
2387
2221
|
ctorToCommand = /* @__PURE__ */ new Map();
|
|
2222
|
+
loading = false;
|
|
2223
|
+
loadedCommands = [];
|
|
2388
2224
|
hmrHandler;
|
|
2389
2225
|
pendingEvents = /* @__PURE__ */ new Map();
|
|
2390
2226
|
constructor(core, onDeployed) {
|
|
@@ -2411,16 +2247,33 @@ var CommandRegistry = class {
|
|
|
2411
2247
|
this.isInitialised = true;
|
|
2412
2248
|
const commandsDir = this.core.config.bot.commands.path;
|
|
2413
2249
|
if (!commandsDir) return;
|
|
2414
|
-
this.
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2250
|
+
this.loading = true;
|
|
2251
|
+
this.loadedCommands.length = 0;
|
|
2252
|
+
try {
|
|
2253
|
+
await this.loadCommands(commandsDir);
|
|
2254
|
+
} finally {
|
|
2255
|
+
this.loading = false;
|
|
2256
|
+
}
|
|
2257
|
+
this.reportLoad();
|
|
2420
2258
|
getDevChannel()?.on("seedcord:refresh-commands", (data) => {
|
|
2421
2259
|
this.refresh(data.shouldRefresh);
|
|
2422
2260
|
});
|
|
2423
2261
|
}
|
|
2262
|
+
reportLoad() {
|
|
2263
|
+
const { utils } = this.logger;
|
|
2264
|
+
utils.summary("Loaded commands", {
|
|
2265
|
+
global: this.globalCommands.length,
|
|
2266
|
+
"guild groups": this.guildCommands.size
|
|
2267
|
+
});
|
|
2268
|
+
let slash = 0;
|
|
2269
|
+
let menu = 0;
|
|
2270
|
+
for (const command of this.loadedCommands) if (command.kind === "slash command") slash++;
|
|
2271
|
+
else menu++;
|
|
2272
|
+
utils.block("Loaded commands", [...utils.entries(this.loadedCommands), ...utils.counts({
|
|
2273
|
+
"slash commands": slash,
|
|
2274
|
+
"context menus": menu
|
|
2275
|
+
})]);
|
|
2276
|
+
}
|
|
2424
2277
|
/** @internal */
|
|
2425
2278
|
async refresh(shouldRefresh = true) {
|
|
2426
2279
|
if (!shouldRefresh) {
|
|
@@ -2458,25 +2311,27 @@ var CommandRegistry = class {
|
|
|
2458
2311
|
const meta = Reflect.getMetadata(CommandMetadataKey, ctor);
|
|
2459
2312
|
if (!meta) return;
|
|
2460
2313
|
const comp = new ctor().component;
|
|
2461
|
-
const
|
|
2462
|
-
if (meta.scope === "global")
|
|
2463
|
-
|
|
2464
|
-
this.
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
for (const g of meta.guilds) {
|
|
2468
|
-
const arr = this.guildCommands.get(g) ?? [];
|
|
2469
|
-
arr.push(comp);
|
|
2470
|
-
this.guildCommands.set(g, arr);
|
|
2471
|
-
}
|
|
2472
|
-
this.logger.utils.registration(ctor.name, rel);
|
|
2473
|
-
this.logger.utils.item(`Guild ${commandType}: ${chalk.bold.cyan(comp.name)} for ${chalk.magenta.bold(meta.guilds.length)} guild(s)`);
|
|
2314
|
+
const kind = comp instanceof SlashCommandBuilder ? "slash command" : "context menu";
|
|
2315
|
+
if (meta.scope === "global") this.globalCommands.push(comp);
|
|
2316
|
+
else for (const g of meta.guilds) {
|
|
2317
|
+
const arr = this.guildCommands.get(g) ?? [];
|
|
2318
|
+
arr.push(comp);
|
|
2319
|
+
this.guildCommands.set(g, arr);
|
|
2474
2320
|
}
|
|
2475
2321
|
this.ctorToCommand.set(ctor, {
|
|
2476
2322
|
name: comp.name,
|
|
2477
2323
|
scope: meta.scope,
|
|
2478
2324
|
...meta.scope === "guild" && { guilds: meta.guilds }
|
|
2479
2325
|
});
|
|
2326
|
+
if (this.loading) {
|
|
2327
|
+
this.loadedCommands.push({
|
|
2328
|
+
name: comp.name,
|
|
2329
|
+
from: formatFilePath(rel),
|
|
2330
|
+
kind
|
|
2331
|
+
});
|
|
2332
|
+
return;
|
|
2333
|
+
}
|
|
2334
|
+
this.logger.utils.registration(comp.name, rel, `${meta.scope} ${kind}`);
|
|
2480
2335
|
}
|
|
2481
2336
|
unregisterCommand(ctor, artifacts) {
|
|
2482
2337
|
const info = artifacts ?? this.ctorToCommand.get(ctor);
|
|
@@ -2503,8 +2358,7 @@ var CommandRegistry = class {
|
|
|
2503
2358
|
const deployed = await this.core.bot.client.application?.commands.set(this.globalCommands);
|
|
2504
2359
|
if (deployed) result.global = deployed;
|
|
2505
2360
|
const tag = this.globalCommands.length === 1 ? "command" : "commands";
|
|
2506
|
-
this.logger.utils.
|
|
2507
|
-
this.logger.utils.item(`${this.globalCommands.map((command) => chalk.bold.cyan(command.name)).join(", ")}`);
|
|
2361
|
+
this.logger.utils.block(`Deployed ${this.globalCommands.length} global ${tag}`, this.logger.utils.wrap(this.globalCommands.map((command) => command.name)), "info");
|
|
2508
2362
|
}
|
|
2509
2363
|
for (const [guildId, commands] of this.guildCommands.entries()) {
|
|
2510
2364
|
const guild = this.core.bot.client.guilds.cache.get(guildId);
|
|
@@ -2515,8 +2369,7 @@ var CommandRegistry = class {
|
|
|
2515
2369
|
const deployed = await guild.commands.set(commands);
|
|
2516
2370
|
result.guilds.set(guildId, deployed);
|
|
2517
2371
|
const tag = commands.length === 1 ? "command" : "commands";
|
|
2518
|
-
this.logger.utils.
|
|
2519
|
-
this.logger.utils.item(`${commands.map((command) => chalk.bold.cyan(command.name)).join(", ")}`);
|
|
2372
|
+
this.logger.utils.block(`Deployed ${commands.length} ${tag} to ${paint.amber.bold(guild.name)}`, this.logger.utils.wrap(commands.map((command) => command.name)), "info");
|
|
2520
2373
|
}
|
|
2521
2374
|
this.onDeployed?.(result);
|
|
2522
2375
|
return result;
|
|
@@ -2828,6 +2681,9 @@ var EventDispatcher = class {
|
|
|
2828
2681
|
middlewares = [];
|
|
2829
2682
|
executedOnceHandlers = /* @__PURE__ */ new Set();
|
|
2830
2683
|
attachedEvents = /* @__PURE__ */ new Set();
|
|
2684
|
+
loading = false;
|
|
2685
|
+
loadedHandlers = [];
|
|
2686
|
+
loadedMiddlewares = [];
|
|
2831
2687
|
hmrHandler;
|
|
2832
2688
|
constructor(core) {
|
|
2833
2689
|
this.core = core;
|
|
@@ -2857,20 +2713,29 @@ var EventDispatcher = class {
|
|
|
2857
2713
|
this.isInitialized = true;
|
|
2858
2714
|
const handlersDir = this.core.config.bot.events.path;
|
|
2859
2715
|
if (!handlersDir) return;
|
|
2860
|
-
this.logger.info(chalk.bold(handlersDir));
|
|
2861
2716
|
const middlewareDir = hasKeys(this.core.config.bot.events, ["middlewares"]) ? this.core.config.bot.events.middlewares : void 0;
|
|
2862
|
-
|
|
2863
|
-
|
|
2864
|
-
|
|
2717
|
+
this.loading = true;
|
|
2718
|
+
this.loadedHandlers.length = 0;
|
|
2719
|
+
this.loadedMiddlewares.length = 0;
|
|
2720
|
+
try {
|
|
2721
|
+
if (middlewareDir) await this.loadMiddlewares(middlewareDir);
|
|
2722
|
+
await this.loadHandlers(handlersDir);
|
|
2723
|
+
} finally {
|
|
2724
|
+
this.loading = false;
|
|
2865
2725
|
}
|
|
2866
|
-
await this.loadHandlers(handlersDir);
|
|
2867
2726
|
this.attachToClient();
|
|
2868
|
-
this.
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
2727
|
+
this.reportLoad();
|
|
2728
|
+
}
|
|
2729
|
+
reportLoad() {
|
|
2730
|
+
const { utils } = this.logger;
|
|
2731
|
+
utils.summary("Loaded", {
|
|
2732
|
+
"event handlers": this.loadedHandlers.length,
|
|
2733
|
+
middlewares: this.loadedMiddlewares.length
|
|
2872
2734
|
});
|
|
2873
|
-
this.
|
|
2735
|
+
if (this.loadedMiddlewares.length > 0) utils.block("Loaded event middlewares", utils.entries(this.loadedMiddlewares));
|
|
2736
|
+
const perEvent = {};
|
|
2737
|
+
for (const [event, handlers] of this.eventMap) perEvent[event] = handlers.length;
|
|
2738
|
+
utils.block("Loaded event handlers", [...utils.entries(this.loadedHandlers), ...utils.counts(perEvent)]);
|
|
2874
2739
|
}
|
|
2875
2740
|
async loadHandlers(dir) {
|
|
2876
2741
|
await traverseDirectory(dir, (fullPath, relativePath, imported) => {
|
|
@@ -2920,7 +2785,14 @@ var EventDispatcher = class {
|
|
|
2920
2785
|
...metadata.events && { events: metadata.events }
|
|
2921
2786
|
});
|
|
2922
2787
|
this.middlewares.sort((a, b) => a.priority - b.priority);
|
|
2923
|
-
|
|
2788
|
+
if (this.loading) {
|
|
2789
|
+
this.loadedMiddlewares.push({
|
|
2790
|
+
name: `${middlewareCtor.name} (${metadata.priority})`,
|
|
2791
|
+
from: formatFilePath(relativePath)
|
|
2792
|
+
});
|
|
2793
|
+
return;
|
|
2794
|
+
}
|
|
2795
|
+
this.logger.utils.registration(`${middlewareCtor.name} ${paint.mute(`(${metadata.priority})`)}`, relativePath, "event middleware");
|
|
2924
2796
|
}
|
|
2925
2797
|
async runMiddlewares(eventName, args) {
|
|
2926
2798
|
for (const { ctor, events } of this.middlewares) {
|
|
@@ -2961,7 +2833,12 @@ var EventDispatcher = class {
|
|
|
2961
2833
|
const names = areRoutes(raw) ? raw : typeof raw === "string" ? [raw] : [];
|
|
2962
2834
|
for (const name of names) register(name, "on");
|
|
2963
2835
|
}
|
|
2964
|
-
|
|
2836
|
+
const from = formatFilePath(relativePath);
|
|
2837
|
+
if (this.loading) this.loadedHandlers.push({
|
|
2838
|
+
name: handlerClass.name,
|
|
2839
|
+
from
|
|
2840
|
+
});
|
|
2841
|
+
else this.logger.utils.registration(handlerClass.name, from);
|
|
2965
2842
|
}
|
|
2966
2843
|
attachToClient() {
|
|
2967
2844
|
for (const [eventName] of this.eventMap) this.attachListener(eventName);
|
|
@@ -2970,12 +2847,12 @@ var EventDispatcher = class {
|
|
|
2970
2847
|
if (this.attachedEvents.has(eventName)) return;
|
|
2971
2848
|
this.attachedEvents.add(eventName);
|
|
2972
2849
|
const handlerEntries = this.eventMap.get(eventName);
|
|
2973
|
-
this.logger.debug(`Attaching ${
|
|
2850
|
+
this.logger.debug(`Attaching ${paint.mint.bold(eventName)} to the client with ${paint.mute(handlerEntries?.length ?? 0)} handler(s)`);
|
|
2974
2851
|
this.core.bot.client.on(eventName, (...args) => {
|
|
2975
2852
|
this.core.bot.emitSafe("any:event", eventName, ...args);
|
|
2976
2853
|
(async () => {
|
|
2977
2854
|
await this.processEvent(eventName, args).catch((err) => {
|
|
2978
|
-
this.logger.error(`[${
|
|
2855
|
+
this.logger.error(`[${paint.coral.bold("UNHANDLED ERROR AT ROOT")}] ${err.name}`, err.stack);
|
|
2979
2856
|
this.core.bot.emit("error:unhandled:event", err);
|
|
2980
2857
|
});
|
|
2981
2858
|
})();
|
|
@@ -2997,7 +2874,7 @@ var EventDispatcher = class {
|
|
|
2997
2874
|
}
|
|
2998
2875
|
async processHandler(eventName, ctor, args) {
|
|
2999
2876
|
try {
|
|
3000
|
-
this.logger.debug(`Processing ${
|
|
2877
|
+
this.logger.debug(`Processing ${paint.mint.bold(eventName)} with ${paint.mute(ctor.name)}`);
|
|
3001
2878
|
const handler = new ctor(args, this.core, eventName);
|
|
3002
2879
|
await runHandlerGates(ctor, eventGateContext(eventName, args, this.core));
|
|
3003
2880
|
await handler.execute();
|
|
@@ -3089,6 +2966,9 @@ var InteractionDispatcher = class {
|
|
|
3089
2966
|
autocompleteMap = /* @__PURE__ */ new Map();
|
|
3090
2967
|
keysToIgnore = /* @__PURE__ */ new Set();
|
|
3091
2968
|
middlewares = [];
|
|
2969
|
+
loading = false;
|
|
2970
|
+
loadedHandlers = [];
|
|
2971
|
+
loadedMiddlewares = [];
|
|
3092
2972
|
hmrHandler;
|
|
3093
2973
|
routeTypes = [
|
|
3094
2974
|
[InteractionRoutes.Slash, this.slashMap],
|
|
@@ -3131,7 +3011,7 @@ var InteractionDispatcher = class {
|
|
|
3131
3011
|
* @internal
|
|
3132
3012
|
*/
|
|
3133
3013
|
warnUnhandledRoutes(commandLeaves) {
|
|
3134
|
-
for (const route of commandLeaves) if (!this.slashMap.has(route)) this.logger.warn(`Slash route ${
|
|
3014
|
+
for (const route of commandLeaves) if (!this.slashMap.has(route)) this.logger.warn(`Slash route ${paint.sky.bold(route)} has no registered ${chalk.bold("@SlashRoute")} handler.`);
|
|
3135
3015
|
}
|
|
3136
3016
|
/**
|
|
3137
3017
|
* Warns for each context-menu command with no matching handler, which would fall through to UnhandledEvent
|
|
@@ -3140,8 +3020,8 @@ var InteractionDispatcher = class {
|
|
|
3140
3020
|
* @internal
|
|
3141
3021
|
*/
|
|
3142
3022
|
warnUnhandledContextMenuRoutes(leaves) {
|
|
3143
|
-
for (const name of leaves.user) if (!this.userContextMenuMap.has(name)) this.logger.warn(`User context menu ${
|
|
3144
|
-
for (const name of leaves.message) if (!this.messageContextMenuMap.has(name)) this.logger.warn(`Message context menu ${
|
|
3023
|
+
for (const name of leaves.user) if (!this.userContextMenuMap.has(name)) this.logger.warn(`User context menu ${paint.sky.bold(name)} has no registered ${chalk.bold("@ContextMenuRoute")} handler.`);
|
|
3024
|
+
for (const name of leaves.message) if (!this.messageContextMenuMap.has(name)) this.logger.warn(`Message context menu ${paint.sky.bold(name)} has no registered ${chalk.bold("@ContextMenuRoute")} handler.`);
|
|
3145
3025
|
}
|
|
3146
3026
|
getArtifacts(handlerClass) {
|
|
3147
3027
|
const artifacts = [];
|
|
@@ -3159,29 +3039,39 @@ var InteractionDispatcher = class {
|
|
|
3159
3039
|
this.isInitialized = true;
|
|
3160
3040
|
const handlersDir = this.core.config.bot.interactions.path;
|
|
3161
3041
|
if (!handlersDir) return;
|
|
3162
|
-
this.logger.info(chalk.bold(handlersDir));
|
|
3163
3042
|
const middlewareDir = hasKeys(this.core.config.bot.interactions, ["middlewares"]) ? this.core.config.bot.interactions.middlewares : void 0;
|
|
3164
|
-
|
|
3165
|
-
|
|
3166
|
-
|
|
3043
|
+
this.loading = true;
|
|
3044
|
+
this.loadedHandlers.length = 0;
|
|
3045
|
+
this.loadedMiddlewares.length = 0;
|
|
3046
|
+
try {
|
|
3047
|
+
if (middlewareDir) await this.loadMiddlewares(middlewareDir);
|
|
3048
|
+
await this.loadHandlers(handlersDir);
|
|
3049
|
+
} finally {
|
|
3050
|
+
this.loading = false;
|
|
3167
3051
|
}
|
|
3168
|
-
await this.loadHandlers(handlersDir);
|
|
3169
3052
|
this.attachToClient();
|
|
3170
|
-
this.
|
|
3171
|
-
|
|
3172
|
-
|
|
3173
|
-
|
|
3174
|
-
|
|
3175
|
-
|
|
3176
|
-
|
|
3177
|
-
|
|
3178
|
-
|
|
3179
|
-
|
|
3180
|
-
|
|
3181
|
-
|
|
3182
|
-
|
|
3183
|
-
|
|
3184
|
-
|
|
3053
|
+
this.reportLoad();
|
|
3054
|
+
}
|
|
3055
|
+
reportLoad() {
|
|
3056
|
+
const { utils } = this.logger;
|
|
3057
|
+
utils.summary("Loaded", {
|
|
3058
|
+
"interaction handlers": this.loadedHandlers.length,
|
|
3059
|
+
middlewares: this.loadedMiddlewares.length
|
|
3060
|
+
});
|
|
3061
|
+
if (this.loadedMiddlewares.length > 0) utils.block("Loaded middlewares", utils.entries(this.loadedMiddlewares));
|
|
3062
|
+
utils.block("Loaded interaction handlers", [...utils.entries(this.loadedHandlers), ...utils.counts({
|
|
3063
|
+
slash: this.slashMap.size,
|
|
3064
|
+
buttons: this.buttonMap.size,
|
|
3065
|
+
modals: this.modalMap.size,
|
|
3066
|
+
"string selects": this.stringSelectMap.size,
|
|
3067
|
+
"user selects": this.userSelectMap.size,
|
|
3068
|
+
"role selects": this.roleSelectMap.size,
|
|
3069
|
+
"channel selects": this.channelSelectMap.size,
|
|
3070
|
+
"mentionable selects": this.mentionableSelectMap.size,
|
|
3071
|
+
"message menus": this.messageContextMenuMap.size,
|
|
3072
|
+
"user menus": this.userContextMenuMap.size,
|
|
3073
|
+
autocomplete: this.autocompleteMap.size
|
|
3074
|
+
})]);
|
|
3185
3075
|
}
|
|
3186
3076
|
async loadHandlers(dir) {
|
|
3187
3077
|
await traverseDirectory(dir, (fullPath, relativePath, imported) => {
|
|
@@ -3211,7 +3101,14 @@ var InteractionDispatcher = class {
|
|
|
3211
3101
|
priority: metadata.priority
|
|
3212
3102
|
});
|
|
3213
3103
|
this.middlewares.sort((a, b) => a.priority - b.priority);
|
|
3214
|
-
|
|
3104
|
+
if (this.loading) {
|
|
3105
|
+
this.loadedMiddlewares.push({
|
|
3106
|
+
name: `${middlewareCtor.name} (${metadata.priority})`,
|
|
3107
|
+
from: formatFilePath(relativePath)
|
|
3108
|
+
});
|
|
3109
|
+
return;
|
|
3110
|
+
}
|
|
3111
|
+
this.logger.utils.registration(`${middlewareCtor.name} ${paint.mute(`(${metadata.priority})`)}`, relativePath, "middleware");
|
|
3215
3112
|
}
|
|
3216
3113
|
isHandlerClass(obj) {
|
|
3217
3114
|
if (typeof obj !== "function") return false;
|
|
@@ -3235,9 +3132,15 @@ var InteractionDispatcher = class {
|
|
|
3235
3132
|
]);
|
|
3236
3133
|
writes.push([map, route]);
|
|
3237
3134
|
}
|
|
3238
|
-
this.logger.utils.registration(handlerClass.name, formatFilePath(relativePath));
|
|
3239
3135
|
}
|
|
3136
|
+
if (writes.length === 0) return;
|
|
3240
3137
|
for (const [map, route] of writes) map.set(route, handlerClass);
|
|
3138
|
+
const from = formatFilePath(relativePath);
|
|
3139
|
+
if (this.loading) this.loadedHandlers.push({
|
|
3140
|
+
name: handlerClass.name,
|
|
3141
|
+
from
|
|
3142
|
+
});
|
|
3143
|
+
else this.logger.utils.registration(handlerClass.name, from);
|
|
3241
3144
|
}
|
|
3242
3145
|
/** @internal For use in dev mode */
|
|
3243
3146
|
async onHmr(event) {
|
|
@@ -3265,7 +3168,7 @@ var InteractionDispatcher = class {
|
|
|
3265
3168
|
this.core.bot.client.on(Events.InteractionCreate, (interaction) => {
|
|
3266
3169
|
this.core.bot.emitSafe("any:interaction", interaction);
|
|
3267
3170
|
this.handleInteraction(interaction).catch((err) => {
|
|
3268
|
-
this.logger.error(`[${
|
|
3171
|
+
this.logger.error(`[${paint.coral.bold("UNHANDLED ERROR AT ROOT")}] ${err.name}`, err.stack);
|
|
3269
3172
|
this.core.bot.emit("error:unhandled:interaction", err);
|
|
3270
3173
|
});
|
|
3271
3174
|
});
|
|
@@ -3282,10 +3185,10 @@ var InteractionDispatcher = class {
|
|
|
3282
3185
|
if (!interaction.isAutocomplete()) for (const { ctor } of this.middlewares) await new ctor(interaction, this.core).execute();
|
|
3283
3186
|
let HandlerCtor = getHandler(key);
|
|
3284
3187
|
if (!HandlerCtor) {
|
|
3285
|
-
this.logger.warn(`No handler found for key ${
|
|
3188
|
+
this.logger.warn(`No handler found for key ${paint.sky.bold(key)}. Falling back to UnhandledEvent.`);
|
|
3286
3189
|
HandlerCtor = UnhandledEvent;
|
|
3287
3190
|
}
|
|
3288
|
-
this.logger.debug(`Processing ${
|
|
3191
|
+
this.logger.debug(`Processing ${paint.mint.bold(key)} with ${paint.mute(HandlerCtor.name)}`);
|
|
3289
3192
|
const dispatch = new DispatchContext(routeIdOf(HandlerCtor));
|
|
3290
3193
|
const handler = new HandlerCtor(interaction, this.core, dispatch);
|
|
3291
3194
|
if (!interaction.isAutocomplete()) await runHandlerGates(HandlerCtor, interactionGateContext(interaction, this.core));
|
|
@@ -3368,7 +3271,7 @@ var InteractionDispatcher = class {
|
|
|
3368
3271
|
async handleAutocomplete(interaction) {
|
|
3369
3272
|
const route = slashRouteOf(interaction);
|
|
3370
3273
|
if (!this.autocompleteMap.has(route)) {
|
|
3371
|
-
this.logger.warn(`No autocomplete handler for ${
|
|
3274
|
+
this.logger.warn(`No autocomplete handler for ${paint.sky.bold(route)}.`);
|
|
3372
3275
|
await interaction.respond([]);
|
|
3373
3276
|
return;
|
|
3374
3277
|
}
|
|
@@ -3487,46 +3390,6 @@ var Bot = class extends Plugin {
|
|
|
3487
3390
|
};
|
|
3488
3391
|
__decorate([Envapt("DISCORD_BOT_TOKEN", { converter: (raw) => validateDiscordToken(raw) }), __decorateMetadata("design:type", String)], Bot.prototype, "botToken", void 0);
|
|
3489
3392
|
|
|
3490
|
-
//#endregion
|
|
3491
|
-
//#region src/hmr/HmrManager.ts
|
|
3492
|
-
var HmrManager = class {
|
|
3493
|
-
logger = new Logger("HMR", { channel: "hmr" });
|
|
3494
|
-
listeners = /* @__PURE__ */ new Set();
|
|
3495
|
-
constructor() {}
|
|
3496
|
-
/** @internal */
|
|
3497
|
-
init() {
|
|
3498
|
-
if (!import.meta.hot) return;
|
|
3499
|
-
setDevChannel(wrapHot(import.meta.hot));
|
|
3500
|
-
if (Envapter.isDevelopment || Envapter.isTest) {
|
|
3501
|
-
this.logger.info("Enabled");
|
|
3502
|
-
getDevChannel()?.on("seedcord:hmr", (payload) => {
|
|
3503
|
-
const affected = payload.affectedModules?.length ?? 0;
|
|
3504
|
-
this.logger.info(`${chalk.bold("1")} module changed, ${chalk.bold(affected)} affected modules`);
|
|
3505
|
-
if (payload.affectedModules) this.logger.utils.list(payload.affectedModules.map((mod) => formatFilePath(mod)), "Affected modules: ");
|
|
3506
|
-
this.handleUpdate(payload);
|
|
3507
|
-
});
|
|
3508
|
-
}
|
|
3509
|
-
}
|
|
3510
|
-
/** @internal */
|
|
3511
|
-
register(listener) {
|
|
3512
|
-
this.listeners.add(listener);
|
|
3513
|
-
}
|
|
3514
|
-
/** @internal */
|
|
3515
|
-
unregister(listener) {
|
|
3516
|
-
this.listeners.delete(listener);
|
|
3517
|
-
}
|
|
3518
|
-
async handleUpdate(event) {
|
|
3519
|
-
const promises = [...this.listeners].map(async (listener) => {
|
|
3520
|
-
try {
|
|
3521
|
-
await listener.onHmr(event);
|
|
3522
|
-
} catch (error) {
|
|
3523
|
-
this.logger.error(`Error handling HMR update in ${chalk.bold(listener.name)}: `, error);
|
|
3524
|
-
}
|
|
3525
|
-
});
|
|
3526
|
-
await Promise.all(promises);
|
|
3527
|
-
}
|
|
3528
|
-
};
|
|
3529
|
-
|
|
3530
3393
|
//#endregion
|
|
3531
3394
|
//#region src/subscribers/bases/webhookHelpers.ts
|
|
3532
3395
|
const DISCORD_WEBHOOK_REGEX = new RegExp(String.raw`^https?:\/\/(?:canary\.|ptb\.)?discord(?:app)?\.com\/api\/webhooks\/\d+\/[\w$-]+$`);
|
|
@@ -3817,7 +3680,7 @@ var Bus = class extends Plugin {
|
|
|
3817
3680
|
//#endregion
|
|
3818
3681
|
//#region src/version.ts
|
|
3819
3682
|
/** Package version */
|
|
3820
|
-
const version = "0.1.0-next.
|
|
3683
|
+
const version = "0.1.0-next.2";
|
|
3821
3684
|
|
|
3822
3685
|
//#endregion
|
|
3823
3686
|
//#region src/Seedcord.ts
|
|
@@ -3836,6 +3699,8 @@ var Seedcord = class Seedcord extends Pluggable {
|
|
|
3836
3699
|
/** @internal */
|
|
3837
3700
|
version = version;
|
|
3838
3701
|
static isInstantiated = false;
|
|
3702
|
+
healthCheck;
|
|
3703
|
+
hmrManager;
|
|
3839
3704
|
/** @see {@link CoordinatedShutdown} */
|
|
3840
3705
|
shutdown;
|
|
3841
3706
|
/** @see {@link CoordinatedStartup} */
|
|
@@ -3846,10 +3711,6 @@ var Seedcord = class Seedcord extends Pluggable {
|
|
|
3846
3711
|
bot;
|
|
3847
3712
|
/** @see {@link IRateLimiter} */
|
|
3848
3713
|
rateLimiter;
|
|
3849
|
-
/** @see {@link HealthCheck} */
|
|
3850
|
-
healthCheck;
|
|
3851
|
-
/** @see {@link HmrManager} */
|
|
3852
|
-
hmrManager;
|
|
3853
3714
|
/**
|
|
3854
3715
|
* Creates a new Seedcord instance
|
|
3855
3716
|
*
|
|
@@ -3863,6 +3724,7 @@ var Seedcord = class Seedcord extends Pluggable {
|
|
|
3863
3724
|
const startup = new CoordinatedStartup();
|
|
3864
3725
|
super(shutdown, startup);
|
|
3865
3726
|
this.config = config;
|
|
3727
|
+
installNodeDefaults(config.logger);
|
|
3866
3728
|
setBotColor(config.botColor);
|
|
3867
3729
|
this.shutdown = shutdown;
|
|
3868
3730
|
this.startup = startup;
|
|
@@ -3874,14 +3736,14 @@ var Seedcord = class Seedcord extends Pluggable {
|
|
|
3874
3736
|
this.healthCheck = new HealthCheck(this.shutdown, config.healthCheck);
|
|
3875
3737
|
this.registerStartupTasks();
|
|
3876
3738
|
}
|
|
3877
|
-
/**
|
|
3739
|
+
/** The bot's discord username, populated after login. */
|
|
3740
|
+
get username() {
|
|
3741
|
+
return this.bot.client.user?.username;
|
|
3742
|
+
}
|
|
3878
3743
|
static reset() {
|
|
3879
3744
|
Seedcord.isInstantiated = false;
|
|
3745
|
+
LoggerChannelRegistry.instance.reset();
|
|
3880
3746
|
}
|
|
3881
|
-
/**
|
|
3882
|
-
* Registers default startup tasks
|
|
3883
|
-
* @internal
|
|
3884
|
-
*/
|
|
3885
3747
|
registerStartupTasks() {
|
|
3886
3748
|
if (Envapter.isDevelopment || Envapter.isTest) this.registerHmrAwareModules();
|
|
3887
3749
|
this.startup.addTask(StartupPhase.Configuration, "Bus Initialization", async () => {
|
|
@@ -3920,5 +3782,5 @@ var Seedcord = class Seedcord extends Pluggable {
|
|
|
3920
3782
|
};
|
|
3921
3783
|
|
|
3922
3784
|
//#endregion
|
|
3923
|
-
export { ArraySource, AutocompleteHandler, AutocompleteRoute, ButtonHandler, ButtonRoute, CommandMentions, ContextMenuHandler, ContextMenuRoute, CursorSource, Emojis, EventHandler, EventMiddleware, Gated,
|
|
3785
|
+
export { ArraySource, AutocompleteHandler, AutocompleteRoute, ButtonHandler, ButtonRoute, CommandMentions, ContextMenuHandler, ContextMenuRoute, CursorSource, Emojis, EventHandler, EventMiddleware, Gated, IgnoreBots, InteractionHandler, InteractionMiddleware, Middleware, MiddlewareType, ModalHandler, ModalRoute, Nsfw, Paginator, Pluggable, Plugin, RegisterCommand, RegisterEvent, ReplySender, RequireBotPermissions, RequirePermissions, RequireRole, Seedcord, SelectMenuHandler, SelectMenuKind, SelectMenuRoute, SlashHandler, SlashRoute, Subscribe, Subscriber, WebhookLog, checkBotPermissions, checkPermissions, fetchGuildMember, fetchManyGuildMembers, fetchManyUsers, fetchRole, fetchText, fetchUser, getBotRole, getConfirmation, hasPermsToAssign, updateMemberRoles, version };
|
|
3924
3786
|
//# sourceMappingURL=index.mjs.map
|