@seedcord/gateway 0.1.0-next.0 → 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 +230 -353
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +44 -107
- package/dist/index.mjs +197 -329
- package/dist/index.mjs.map +1 -1
- package/package.json +11 -10
package/dist/index.cjs
CHANGED
|
@@ -27,26 +27,34 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
27
27
|
|
|
28
28
|
//#endregion
|
|
29
29
|
require("reflect-metadata");
|
|
30
|
+
let _seedcord_logger_node = require("@seedcord/logger/node");
|
|
30
31
|
let _seedcord_core = require("@seedcord/core");
|
|
31
32
|
let _seedcord_core_internal = require("@seedcord/core/internal");
|
|
32
33
|
let discord_js = require("discord.js");
|
|
33
34
|
let _seedcord_errors = require("@seedcord/errors");
|
|
34
35
|
let _seedcord_errors_internal = require("@seedcord/errors/internal");
|
|
35
36
|
let _seedcord_utils = require("@seedcord/utils");
|
|
36
|
-
let
|
|
37
|
-
let chalk = require("chalk");
|
|
38
|
-
chalk = __toESM(chalk, 1);
|
|
37
|
+
let _seedcord_logger = require("@seedcord/logger");
|
|
39
38
|
let _discordjs_builders = require("@discordjs/builders");
|
|
40
39
|
let _seedcord_utils_internal = require("@seedcord/utils/internal");
|
|
41
|
-
let
|
|
42
|
-
let node_path = require("node:path");
|
|
43
|
-
let node_url = require("node:url");
|
|
40
|
+
let _seedcord_event_emitter = require("@seedcord/event-emitter");
|
|
44
41
|
let _seedcord_rate_limiter = require("@seedcord/rate-limiter");
|
|
42
|
+
let _seedcord_services = require("@seedcord/services");
|
|
45
43
|
let _seedcord_types_internal = require("@seedcord/types/internal");
|
|
46
44
|
let envapt = require("envapt");
|
|
45
|
+
let chalk = require("chalk");
|
|
46
|
+
chalk = __toESM(chalk, 1);
|
|
47
|
+
let envapt_legacy = require("envapt/legacy");
|
|
48
|
+
let node_path = require("node:path");
|
|
49
|
+
let _seedcord_core_hmr = require("@seedcord/core/hmr");
|
|
50
|
+
let _seedcord_utils_node = require("@seedcord/utils/node");
|
|
47
51
|
let node_crypto = require("node:crypto");
|
|
48
52
|
node_crypto = __toESM(node_crypto, 1);
|
|
49
53
|
|
|
54
|
+
//#region src/logger-bootstrap.ts
|
|
55
|
+
(0, _seedcord_logger_node.installNodeDefaults)();
|
|
56
|
+
|
|
57
|
+
//#endregion
|
|
50
58
|
//#region src/bot/decorators/Events.ts
|
|
51
59
|
/**
|
|
52
60
|
* Registers an event handler class with one or more Discord.js events.
|
|
@@ -683,14 +691,14 @@ const Emojis = emojiStorage;
|
|
|
683
691
|
*/
|
|
684
692
|
var EmojiInjector = class {
|
|
685
693
|
core;
|
|
686
|
-
logger = new
|
|
694
|
+
logger = new _seedcord_logger.Logger("Emojis");
|
|
687
695
|
constructor(core) {
|
|
688
696
|
this.core = core;
|
|
689
697
|
}
|
|
690
698
|
async init() {
|
|
691
699
|
this.clearEmojis();
|
|
692
700
|
if (!this.core.config.bot.emojis || Object.keys(this.core.config.bot.emojis).length === 0) {
|
|
693
|
-
this.logger.debug(
|
|
701
|
+
this.logger.debug("No emojis configured, skipping emoji injection.");
|
|
694
702
|
return;
|
|
695
703
|
}
|
|
696
704
|
const configEmojis = this.core.config.bot.emojis;
|
|
@@ -758,7 +766,7 @@ const MULTI_GUILD = Symbol("seedcord:commandmentions:multi-guild");
|
|
|
758
766
|
*/
|
|
759
767
|
var CommandMentionInjector = class {
|
|
760
768
|
core;
|
|
761
|
-
logger = new
|
|
769
|
+
logger = new _seedcord_logger.Logger("CommandMentions");
|
|
762
770
|
constructor(core) {
|
|
763
771
|
this.core = core;
|
|
764
772
|
}
|
|
@@ -885,7 +893,7 @@ function checkBotPermissions(target, scope, inverse = false, errors) {
|
|
|
885
893
|
}
|
|
886
894
|
const me = target.guild.members.me;
|
|
887
895
|
if (!me) {
|
|
888
|
-
new
|
|
896
|
+
new _seedcord_logger.Logger("checkBotPermissions").warn(`Bot member is unavailable in guild ${target.guild.id} while checking permissions in channel ${target.id}`);
|
|
889
897
|
const names = scope.map((bit) => PermissionNames.get(bit) ?? String(bit));
|
|
890
898
|
throw new ((errors?.missing) ?? MissingPermissions)("Missing Permissions", target, names);
|
|
891
899
|
}
|
|
@@ -1111,7 +1119,7 @@ function flagsFor(ephemeral) {
|
|
|
1111
1119
|
*/
|
|
1112
1120
|
var ReplySender = class {
|
|
1113
1121
|
interaction;
|
|
1114
|
-
logger = new
|
|
1122
|
+
logger = new _seedcord_logger.Logger("ReplySender");
|
|
1115
1123
|
constructor(interaction) {
|
|
1116
1124
|
this.interaction = interaction;
|
|
1117
1125
|
}
|
|
@@ -1247,16 +1255,6 @@ async function getConfirmation(interaction, prompt, options) {
|
|
|
1247
1255
|
return confirmed;
|
|
1248
1256
|
}
|
|
1249
1257
|
|
|
1250
|
-
//#endregion
|
|
1251
|
-
//#region src/hmr/devChannel.ts
|
|
1252
|
-
let channel;
|
|
1253
|
-
function setDevChannel(next) {
|
|
1254
|
-
channel = next;
|
|
1255
|
-
}
|
|
1256
|
-
function getDevChannel() {
|
|
1257
|
-
return channel;
|
|
1258
|
-
}
|
|
1259
|
-
|
|
1260
1258
|
//#endregion
|
|
1261
1259
|
//#region src/interfaces/Plugin.ts
|
|
1262
1260
|
/**
|
|
@@ -1265,7 +1263,7 @@ function getDevChannel() {
|
|
|
1265
1263
|
* Extend this class to create plugins that integrate with the Seedcord lifecycle.
|
|
1266
1264
|
* Plugins have access to the core instance and must implement initialization logic.
|
|
1267
1265
|
*/
|
|
1268
|
-
var Plugin = class extends
|
|
1266
|
+
var Plugin = class extends _seedcord_event_emitter.TypedEventEmitter {
|
|
1269
1267
|
pluggable;
|
|
1270
1268
|
name = this.constructor.name;
|
|
1271
1269
|
constructor(pluggable) {
|
|
@@ -1284,19 +1282,15 @@ var Plugin = class extends _seedcord_services.StrictEventEmitter {
|
|
|
1284
1282
|
* @param patterns - Glob patterns relative to the project root
|
|
1285
1283
|
*/
|
|
1286
1284
|
registerCriticalFiles(patterns) {
|
|
1287
|
-
getDevChannel()?.send("seedcord:register-critical-files", { patterns });
|
|
1288
|
-
}
|
|
1289
|
-
/** @internal */
|
|
1290
|
-
setMaxListeners(n) {
|
|
1291
|
-
return super.setMaxListeners(n);
|
|
1285
|
+
(0, _seedcord_core_internal.getDevChannel)()?.send("seedcord:register-critical-files", { patterns });
|
|
1292
1286
|
}
|
|
1293
1287
|
/** @internal */
|
|
1294
1288
|
removeListener(event, listener) {
|
|
1295
1289
|
return super.removeListener(event, listener);
|
|
1296
1290
|
}
|
|
1297
1291
|
/** @internal */
|
|
1298
|
-
removeAllListeners(
|
|
1299
|
-
return super.removeAllListeners(
|
|
1292
|
+
removeAllListeners(event) {
|
|
1293
|
+
return super.removeAllListeners(event);
|
|
1300
1294
|
}
|
|
1301
1295
|
};
|
|
1302
1296
|
/**
|
|
@@ -1305,7 +1299,7 @@ var Plugin = class extends _seedcord_services.StrictEventEmitter {
|
|
|
1305
1299
|
* Provides plugin attachment capabilities and lifecycle management. Plugins are attached during
|
|
1306
1300
|
* configuration and initialized during startup. Not constructed directly, the host is a {@link Seedcord}.
|
|
1307
1301
|
*/
|
|
1308
|
-
var Pluggable = class Pluggable extends
|
|
1302
|
+
var Pluggable = class Pluggable extends _seedcord_event_emitter.TypedEventEmitter {
|
|
1309
1303
|
isInitialized = false;
|
|
1310
1304
|
shutdown;
|
|
1311
1305
|
startup;
|
|
@@ -1358,16 +1352,12 @@ var Pluggable = class Pluggable extends _seedcord_services.StrictEventEmitter {
|
|
|
1358
1352
|
return Object.assign(this, entry);
|
|
1359
1353
|
}
|
|
1360
1354
|
/** @internal */
|
|
1361
|
-
setMaxListeners(n) {
|
|
1362
|
-
return super.setMaxListeners(n);
|
|
1363
|
-
}
|
|
1364
|
-
/** @internal */
|
|
1365
1355
|
removeListener(event, listener) {
|
|
1366
1356
|
return super.removeListener(event, listener);
|
|
1367
1357
|
}
|
|
1368
1358
|
/** @internal */
|
|
1369
|
-
removeAllListeners(
|
|
1370
|
-
return super.removeAllListeners(
|
|
1359
|
+
removeAllListeners(event) {
|
|
1360
|
+
return super.removeAllListeners(event);
|
|
1371
1361
|
}
|
|
1372
1362
|
};
|
|
1373
1363
|
|
|
@@ -1380,10 +1370,12 @@ var BaseHandler = class {
|
|
|
1380
1370
|
core;
|
|
1381
1371
|
event;
|
|
1382
1372
|
logger;
|
|
1383
|
-
|
|
1373
|
+
dispatch;
|
|
1374
|
+
constructor(event, core, dispatch) {
|
|
1384
1375
|
this.core = core;
|
|
1385
1376
|
this.event = event;
|
|
1386
|
-
this.logger = new
|
|
1377
|
+
this.logger = new _seedcord_logger.Logger(this.constructor.name);
|
|
1378
|
+
this.dispatch = dispatch;
|
|
1387
1379
|
}
|
|
1388
1380
|
/** @internal */
|
|
1389
1381
|
getEvent() {
|
|
@@ -1419,8 +1411,8 @@ var InteractionMiddleware = class extends BaseHandler {
|
|
|
1419
1411
|
* @typeParam Repliable - The interaction type this handler processes
|
|
1420
1412
|
*/
|
|
1421
1413
|
var InteractionHandler = class extends BaseHandler {
|
|
1422
|
-
constructor(event, core) {
|
|
1423
|
-
super(event, core);
|
|
1414
|
+
constructor(event, core, dispatch) {
|
|
1415
|
+
super(event, core, dispatch);
|
|
1424
1416
|
}
|
|
1425
1417
|
};
|
|
1426
1418
|
|
|
@@ -1565,8 +1557,8 @@ var ContextMenuHandler = class extends InteractionHandler {
|
|
|
1565
1557
|
* ```
|
|
1566
1558
|
*/
|
|
1567
1559
|
var AutocompleteHandler = class extends BaseHandler {
|
|
1568
|
-
constructor(event, core) {
|
|
1569
|
-
super(event, core);
|
|
1560
|
+
constructor(event, core, dispatch) {
|
|
1561
|
+
super(event, core, dispatch);
|
|
1570
1562
|
}
|
|
1571
1563
|
/**
|
|
1572
1564
|
* The focused option for this interaction. `value` is always the raw partial string the user is typing,
|
|
@@ -2125,7 +2117,7 @@ var Subscriber = class {
|
|
|
2125
2117
|
constructor(data, core) {
|
|
2126
2118
|
this.data = data;
|
|
2127
2119
|
this.core = core;
|
|
2128
|
-
this.logger = new
|
|
2120
|
+
this.logger = new _seedcord_logger.Logger(this.constructor.name);
|
|
2129
2121
|
}
|
|
2130
2122
|
};
|
|
2131
2123
|
|
|
@@ -2183,171 +2175,6 @@ var WebhookLog = class extends Subscriber {
|
|
|
2183
2175
|
}
|
|
2184
2176
|
};
|
|
2185
2177
|
|
|
2186
|
-
//#endregion
|
|
2187
|
-
//#region src/hmr/HmrModuleHandler.ts
|
|
2188
|
-
/**
|
|
2189
|
-
* Reloads THandler and optional TMiddleware modules on HMR updates.
|
|
2190
|
-
*
|
|
2191
|
-
* 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.
|
|
2192
|
-
*
|
|
2193
|
-
* This is only useful during development.
|
|
2194
|
-
*/
|
|
2195
|
-
var HmrModuleHandler = class {
|
|
2196
|
-
store;
|
|
2197
|
-
options;
|
|
2198
|
-
constructor(options) {
|
|
2199
|
-
this.options = {
|
|
2200
|
-
...options,
|
|
2201
|
-
logger: options.logger.inChannel("hmr")
|
|
2202
|
-
};
|
|
2203
|
-
this.store = {
|
|
2204
|
-
fileToHandlers: /* @__PURE__ */ new Map(),
|
|
2205
|
-
fileToMiddlewares: /* @__PURE__ */ new Map(),
|
|
2206
|
-
handlerArtifacts: /* @__PURE__ */ new Map()
|
|
2207
|
-
};
|
|
2208
|
-
}
|
|
2209
|
-
/**
|
|
2210
|
-
* 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.
|
|
2211
|
-
*
|
|
2212
|
-
* - If it's a deletion, it unloads the module.
|
|
2213
|
-
* - 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.
|
|
2214
|
-
*/
|
|
2215
|
-
async handle(event) {
|
|
2216
|
-
const { file, affectedModules, type } = event;
|
|
2217
|
-
const { logger, handlersDir, middlewaresDir } = this.options;
|
|
2218
|
-
if (type === "delete" || type === "deleteDir") {
|
|
2219
|
-
this.unload(file);
|
|
2220
|
-
return;
|
|
2221
|
-
}
|
|
2222
|
-
if (type === "update" && !(0, node_fs.existsSync)(file)) {
|
|
2223
|
-
if (this.isTracked(file)) {
|
|
2224
|
-
logger.info(`Received update for non-existent file: ${(0, _seedcord_utils.formatFilePath)(file)}, treating as delete`);
|
|
2225
|
-
this.unload(file);
|
|
2226
|
-
}
|
|
2227
|
-
return;
|
|
2228
|
-
}
|
|
2229
|
-
const rollbackEnabled = event.rollback ?? true;
|
|
2230
|
-
const filesToReload = affectedModules && affectedModules.length > 0 ? affectedModules : [file];
|
|
2231
|
-
const absHandlersDir = (0, node_path.resolve)(process.cwd(), handlersDir);
|
|
2232
|
-
const absMiddlewaresDir = middlewaresDir ? (0, node_path.resolve)(process.cwd(), middlewaresDir) : null;
|
|
2233
|
-
for (const fileToReload of filesToReload) {
|
|
2234
|
-
const isHandler = fileToReload.startsWith(absHandlersDir);
|
|
2235
|
-
const isMiddleware = absMiddlewaresDir ? fileToReload.startsWith(absMiddlewaresDir) : false;
|
|
2236
|
-
if (!isHandler && !isMiddleware) continue;
|
|
2237
|
-
await this.reloadWithRollback(fileToReload, rollbackEnabled);
|
|
2238
|
-
}
|
|
2239
|
-
}
|
|
2240
|
-
async reloadWithRollback(file, rollbackEnabled) {
|
|
2241
|
-
const { logger } = this.options;
|
|
2242
|
-
const snapshot = this.snapshotUnits(file);
|
|
2243
|
-
this.unload(file);
|
|
2244
|
-
if (await this.reloadFile(file)) return;
|
|
2245
|
-
this.unload(file);
|
|
2246
|
-
if (!rollbackEnabled) return;
|
|
2247
|
-
this.restoreUnits(file, snapshot);
|
|
2248
|
-
logger.warn(`${chalk.default.yellow.bold("Rolled back")} ${chalk.default.gray((0, _seedcord_utils.formatFilePath)(file))} to the last-good version`);
|
|
2249
|
-
}
|
|
2250
|
-
/**
|
|
2251
|
-
* Tracks a handler module as being loaded from a specific file.
|
|
2252
|
-
* @param file - The file path the handler was loaded from.
|
|
2253
|
-
* @param handler - The handler module instance.
|
|
2254
|
-
*/
|
|
2255
|
-
trackHandler(file, handler) {
|
|
2256
|
-
let set = this.store.fileToHandlers.get(file);
|
|
2257
|
-
if (!set) {
|
|
2258
|
-
set = /* @__PURE__ */ new Set();
|
|
2259
|
-
this.store.fileToHandlers.set(file, set);
|
|
2260
|
-
}
|
|
2261
|
-
set.add(handler);
|
|
2262
|
-
if (this.options.getArtifacts) {
|
|
2263
|
-
const artifacts = this.options.getArtifacts(handler);
|
|
2264
|
-
this.store.handlerArtifacts.set(handler, artifacts);
|
|
2265
|
-
}
|
|
2266
|
-
}
|
|
2267
|
-
/**
|
|
2268
|
-
* Tracks a middleware module as being loaded from a specific file.
|
|
2269
|
-
* @param file - The file path the middleware was loaded from.
|
|
2270
|
-
* @param middleware - The middleware module instance.
|
|
2271
|
-
*/
|
|
2272
|
-
trackMiddleware(file, middleware) {
|
|
2273
|
-
let set = this.store.fileToMiddlewares.get(file);
|
|
2274
|
-
if (!set) {
|
|
2275
|
-
set = /* @__PURE__ */ new Set();
|
|
2276
|
-
this.store.fileToMiddlewares.set(file, set);
|
|
2277
|
-
}
|
|
2278
|
-
set.add(middleware);
|
|
2279
|
-
}
|
|
2280
|
-
isTracked(file) {
|
|
2281
|
-
return this.store.fileToHandlers.has(file) || this.store.fileToMiddlewares.has(file);
|
|
2282
|
-
}
|
|
2283
|
-
unload(file) {
|
|
2284
|
-
const { logger } = this.options;
|
|
2285
|
-
const handlers = this.store.fileToHandlers.get(file);
|
|
2286
|
-
if (handlers) {
|
|
2287
|
-
for (const handler of handlers) {
|
|
2288
|
-
const artifacts = this.store.handlerArtifacts.get(handler);
|
|
2289
|
-
this.options.unregisterHandler(handler, artifacts);
|
|
2290
|
-
this.store.handlerArtifacts.delete(handler);
|
|
2291
|
-
const name = handler.name ?? "Handler";
|
|
2292
|
-
logger.info(`${chalk.default.red.bold("Unloaded")} ${chalk.default.cyan.bold(name)} from ${chalk.default.gray((0, _seedcord_utils.formatFilePath)(file))}`);
|
|
2293
|
-
}
|
|
2294
|
-
this.store.fileToHandlers.delete(file);
|
|
2295
|
-
}
|
|
2296
|
-
const middlewares = this.store.fileToMiddlewares.get(file);
|
|
2297
|
-
if (middlewares) {
|
|
2298
|
-
for (const middleware of middlewares) {
|
|
2299
|
-
this.options.unregisterMiddleware?.(middleware);
|
|
2300
|
-
const name = middleware.name ?? "Middleware";
|
|
2301
|
-
logger.info(`${chalk.default.red.bold("Unloaded")} ${chalk.default.cyan.bold(name)} from ${chalk.default.gray((0, _seedcord_utils.formatFilePath)(file))}`);
|
|
2302
|
-
}
|
|
2303
|
-
this.store.fileToMiddlewares.delete(file);
|
|
2304
|
-
}
|
|
2305
|
-
}
|
|
2306
|
-
async reloadFile(file) {
|
|
2307
|
-
const { logger, isHandler, isMiddleware, registerHandler, registerMiddleware } = this.options;
|
|
2308
|
-
if (!(0, node_fs.existsSync)(file)) {
|
|
2309
|
-
logger.info(`File does not exist, skipping reload: ${(0, _seedcord_utils.formatFilePath)(file)}`);
|
|
2310
|
-
return false;
|
|
2311
|
-
}
|
|
2312
|
-
try {
|
|
2313
|
-
let fileUrl = (0, node_url.pathToFileURL)(file).href;
|
|
2314
|
-
if (process.env.VITEST === "true") fileUrl += `?update=${Date.now()}`;
|
|
2315
|
-
const imported = await import(fileUrl);
|
|
2316
|
-
for (const val of Object.values(imported)) if (isHandler(val)) {
|
|
2317
|
-
registerHandler(val, file);
|
|
2318
|
-
this.trackHandler(file, val);
|
|
2319
|
-
const name = val.name ?? "Handler";
|
|
2320
|
-
logger.info(`${chalk.default.blue.bold("Reloaded")} ${chalk.default.cyan.bold(name)} from ${chalk.default.gray((0, _seedcord_utils.formatFilePath)(file))}`);
|
|
2321
|
-
} else if (isMiddleware && registerMiddleware && isMiddleware(val)) {
|
|
2322
|
-
registerMiddleware(val, file);
|
|
2323
|
-
this.trackMiddleware(file, val);
|
|
2324
|
-
const name = val.name ?? "Middleware";
|
|
2325
|
-
logger.info(`${chalk.default.blue.bold("Reloaded")} ${chalk.default.cyan.bold(name)} from ${chalk.default.gray((0, _seedcord_utils.formatFilePath)(file))}`);
|
|
2326
|
-
}
|
|
2327
|
-
return true;
|
|
2328
|
-
} catch (error) {
|
|
2329
|
-
logger.error(`Failed to reload file: ${file}`, error);
|
|
2330
|
-
return false;
|
|
2331
|
-
}
|
|
2332
|
-
}
|
|
2333
|
-
snapshotUnits(file) {
|
|
2334
|
-
return {
|
|
2335
|
-
handlers: [...this.store.fileToHandlers.get(file) ?? []],
|
|
2336
|
-
middlewares: [...this.store.fileToMiddlewares.get(file) ?? []]
|
|
2337
|
-
};
|
|
2338
|
-
}
|
|
2339
|
-
restoreUnits(file, snapshot) {
|
|
2340
|
-
for (const handler of snapshot.handlers) {
|
|
2341
|
-
this.options.registerHandler(handler, file);
|
|
2342
|
-
this.trackHandler(file, handler);
|
|
2343
|
-
}
|
|
2344
|
-
if (this.options.registerMiddleware) for (const middleware of snapshot.middlewares) {
|
|
2345
|
-
this.options.registerMiddleware(middleware, file);
|
|
2346
|
-
this.trackMiddleware(file, middleware);
|
|
2347
|
-
}
|
|
2348
|
-
}
|
|
2349
|
-
};
|
|
2350
|
-
|
|
2351
2178
|
//#endregion
|
|
2352
2179
|
//#region src/bot/utilities/miscellaneous/contextMenuLeaves.ts
|
|
2353
2180
|
/**
|
|
@@ -2403,11 +2230,13 @@ var CommandRegistry = class {
|
|
|
2403
2230
|
core;
|
|
2404
2231
|
onDeployed;
|
|
2405
2232
|
name = "Commands";
|
|
2406
|
-
logger = new
|
|
2233
|
+
logger = new _seedcord_logger.Logger("Commands");
|
|
2407
2234
|
isInitialised = false;
|
|
2408
2235
|
globalCommands = [];
|
|
2409
2236
|
guildCommands = new discord_js.Collection();
|
|
2410
2237
|
ctorToCommand = /* @__PURE__ */ new Map();
|
|
2238
|
+
loading = false;
|
|
2239
|
+
loadedCommands = [];
|
|
2411
2240
|
hmrHandler;
|
|
2412
2241
|
pendingEvents = /* @__PURE__ */ new Map();
|
|
2413
2242
|
constructor(core, onDeployed) {
|
|
@@ -2416,7 +2245,7 @@ var CommandRegistry = class {
|
|
|
2416
2245
|
const commandsDir = this.core.config.bot.commands.path;
|
|
2417
2246
|
if (!commandsDir) throw new _seedcord_errors_internal.SeedcordError(_seedcord_errors.SeedcordErrorCode.CoreControllerPathMissing, ["CommandRegistry", "commands"]);
|
|
2418
2247
|
if (!envapt.Envapter.isDevelopment && !envapt.Envapter.isTest) return;
|
|
2419
|
-
this.hmrHandler = new HmrModuleHandler({
|
|
2248
|
+
this.hmrHandler = new _seedcord_core_hmr.HmrModuleHandler({
|
|
2420
2249
|
handlersDir: commandsDir,
|
|
2421
2250
|
isHandler: this.isCommandClass.bind(this),
|
|
2422
2251
|
registerHandler: this.registerCommand.bind(this),
|
|
@@ -2434,15 +2263,32 @@ var CommandRegistry = class {
|
|
|
2434
2263
|
this.isInitialised = true;
|
|
2435
2264
|
const commandsDir = this.core.config.bot.commands.path;
|
|
2436
2265
|
if (!commandsDir) return;
|
|
2437
|
-
this.
|
|
2438
|
-
|
|
2439
|
-
|
|
2266
|
+
this.loading = true;
|
|
2267
|
+
this.loadedCommands.length = 0;
|
|
2268
|
+
try {
|
|
2269
|
+
await this.loadCommands(commandsDir);
|
|
2270
|
+
} finally {
|
|
2271
|
+
this.loading = false;
|
|
2272
|
+
}
|
|
2273
|
+
this.reportLoad();
|
|
2274
|
+
(0, _seedcord_core_internal.getDevChannel)()?.on("seedcord:refresh-commands", (data) => {
|
|
2275
|
+
this.refresh(data.shouldRefresh);
|
|
2276
|
+
});
|
|
2277
|
+
}
|
|
2278
|
+
reportLoad() {
|
|
2279
|
+
const { utils } = this.logger;
|
|
2280
|
+
utils.summary("Loaded commands", {
|
|
2440
2281
|
global: this.globalCommands.length,
|
|
2441
2282
|
"guild groups": this.guildCommands.size
|
|
2442
2283
|
});
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2284
|
+
let slash = 0;
|
|
2285
|
+
let menu = 0;
|
|
2286
|
+
for (const command of this.loadedCommands) if (command.kind === "slash command") slash++;
|
|
2287
|
+
else menu++;
|
|
2288
|
+
utils.block("Loaded commands", [...utils.entries(this.loadedCommands), ...utils.counts({
|
|
2289
|
+
"slash commands": slash,
|
|
2290
|
+
"context menus": menu
|
|
2291
|
+
})]);
|
|
2446
2292
|
}
|
|
2447
2293
|
/** @internal */
|
|
2448
2294
|
async refresh(shouldRefresh = true) {
|
|
@@ -2462,11 +2308,11 @@ var CommandRegistry = class {
|
|
|
2462
2308
|
if (commandsDir && event.file.startsWith((0, node_path.resolve)(process.cwd(), commandsDir))) {
|
|
2463
2309
|
this.pendingEvents.delete(event.file);
|
|
2464
2310
|
this.pendingEvents.set(event.file, event);
|
|
2465
|
-
getDevChannel()?.send("seedcord:commands-update-prompt", { files: [...this.pendingEvents.keys()].map((f) => (0, _seedcord_utils.formatFilePath)(f)) });
|
|
2311
|
+
(0, _seedcord_core_internal.getDevChannel)()?.send("seedcord:commands-update-prompt", { files: [...this.pendingEvents.keys()].map((f) => (0, _seedcord_utils.formatFilePath)(f)) });
|
|
2466
2312
|
} else await this.hmrHandler?.handle(event);
|
|
2467
2313
|
}
|
|
2468
2314
|
async loadCommands(dir) {
|
|
2469
|
-
await (0,
|
|
2315
|
+
await (0, _seedcord_utils_node.traverseDirectory)(dir, (fullPath, rel, mod) => {
|
|
2470
2316
|
for (const exported of Object.values(mod)) if (this.isCommandClass(exported)) {
|
|
2471
2317
|
this.registerCommand(exported, rel);
|
|
2472
2318
|
this.hmrHandler?.trackHandler(fullPath, exported);
|
|
@@ -2481,25 +2327,27 @@ var CommandRegistry = class {
|
|
|
2481
2327
|
const meta = Reflect.getMetadata(_seedcord_core_internal.CommandMetadataKey, ctor);
|
|
2482
2328
|
if (!meta) return;
|
|
2483
2329
|
const comp = new ctor().component;
|
|
2484
|
-
const
|
|
2485
|
-
if (meta.scope === "global")
|
|
2486
|
-
|
|
2487
|
-
this.
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
for (const g of meta.guilds) {
|
|
2491
|
-
const arr = this.guildCommands.get(g) ?? [];
|
|
2492
|
-
arr.push(comp);
|
|
2493
|
-
this.guildCommands.set(g, arr);
|
|
2494
|
-
}
|
|
2495
|
-
this.logger.utils.registration(ctor.name, rel);
|
|
2496
|
-
this.logger.utils.item(`Guild ${commandType}: ${chalk.default.bold.cyan(comp.name)} for ${chalk.default.magenta.bold(meta.guilds.length)} guild(s)`);
|
|
2330
|
+
const kind = comp instanceof _discordjs_builders.SlashCommandBuilder ? "slash command" : "context menu";
|
|
2331
|
+
if (meta.scope === "global") this.globalCommands.push(comp);
|
|
2332
|
+
else for (const g of meta.guilds) {
|
|
2333
|
+
const arr = this.guildCommands.get(g) ?? [];
|
|
2334
|
+
arr.push(comp);
|
|
2335
|
+
this.guildCommands.set(g, arr);
|
|
2497
2336
|
}
|
|
2498
2337
|
this.ctorToCommand.set(ctor, {
|
|
2499
2338
|
name: comp.name,
|
|
2500
2339
|
scope: meta.scope,
|
|
2501
2340
|
...meta.scope === "guild" && { guilds: meta.guilds }
|
|
2502
2341
|
});
|
|
2342
|
+
if (this.loading) {
|
|
2343
|
+
this.loadedCommands.push({
|
|
2344
|
+
name: comp.name,
|
|
2345
|
+
from: (0, _seedcord_utils.formatFilePath)(rel),
|
|
2346
|
+
kind
|
|
2347
|
+
});
|
|
2348
|
+
return;
|
|
2349
|
+
}
|
|
2350
|
+
this.logger.utils.registration(comp.name, rel, `${meta.scope} ${kind}`);
|
|
2503
2351
|
}
|
|
2504
2352
|
unregisterCommand(ctor, artifacts) {
|
|
2505
2353
|
const info = artifacts ?? this.ctorToCommand.get(ctor);
|
|
@@ -2526,8 +2374,7 @@ var CommandRegistry = class {
|
|
|
2526
2374
|
const deployed = await this.core.bot.client.application?.commands.set(this.globalCommands);
|
|
2527
2375
|
if (deployed) result.global = deployed;
|
|
2528
2376
|
const tag = this.globalCommands.length === 1 ? "command" : "commands";
|
|
2529
|
-
this.logger.utils.
|
|
2530
|
-
this.logger.utils.item(`${this.globalCommands.map((command) => chalk.default.bold.cyan(command.name)).join(", ")}`);
|
|
2377
|
+
this.logger.utils.block(`Deployed ${this.globalCommands.length} global ${tag}`, this.logger.utils.wrap(this.globalCommands.map((command) => command.name)), "info");
|
|
2531
2378
|
}
|
|
2532
2379
|
for (const [guildId, commands] of this.guildCommands.entries()) {
|
|
2533
2380
|
const guild = this.core.bot.client.guilds.cache.get(guildId);
|
|
@@ -2538,8 +2385,7 @@ var CommandRegistry = class {
|
|
|
2538
2385
|
const deployed = await guild.commands.set(commands);
|
|
2539
2386
|
result.guilds.set(guildId, deployed);
|
|
2540
2387
|
const tag = commands.length === 1 ? "command" : "commands";
|
|
2541
|
-
this.logger.utils.
|
|
2542
|
-
this.logger.utils.item(`${commands.map((command) => chalk.default.bold.cyan(command.name)).join(", ")}`);
|
|
2388
|
+
this.logger.utils.block(`Deployed ${commands.length} ${tag} to ${_seedcord_logger.paint.amber.bold(guild.name)}`, this.logger.utils.wrap(commands.map((command) => command.name)), "info");
|
|
2543
2389
|
}
|
|
2544
2390
|
this.onDeployed?.(result);
|
|
2545
2391
|
return result;
|
|
@@ -2602,7 +2448,8 @@ function interactionGateContext(interaction, core) {
|
|
|
2602
2448
|
guildId: interaction.guildId,
|
|
2603
2449
|
channelId: interaction.channelId,
|
|
2604
2450
|
memberRoleIds,
|
|
2605
|
-
memberPermissions: interaction.memberPermissions?.bitfield ?? null
|
|
2451
|
+
memberPermissions: interaction.memberPermissions?.bitfield ?? null,
|
|
2452
|
+
routeId: null
|
|
2606
2453
|
};
|
|
2607
2454
|
}
|
|
2608
2455
|
function eventGateContext(eventName, args, core) {
|
|
@@ -2619,7 +2466,8 @@ function eventGateContext(eventName, args, core) {
|
|
|
2619
2466
|
guildId: actor.guild?.id ?? null,
|
|
2620
2467
|
channelId: actor.channelId,
|
|
2621
2468
|
memberRoleIds: actor.member ? [...actor.member.roles.cache.keys()].filter((id) => id !== actor.guild?.id) : [],
|
|
2622
|
-
memberPermissions: actor.member?.permissions.bitfield ?? null
|
|
2469
|
+
memberPermissions: actor.member?.permissions.bitfield ?? null,
|
|
2470
|
+
routeId: null
|
|
2623
2471
|
};
|
|
2624
2472
|
}
|
|
2625
2473
|
|
|
@@ -2658,7 +2506,7 @@ var FaultThrottle = class {
|
|
|
2658
2506
|
|
|
2659
2507
|
//#endregion
|
|
2660
2508
|
//#region src/miscellaneous/extractErrorResponse.ts
|
|
2661
|
-
const logger$2 = new
|
|
2509
|
+
const logger$2 = new _seedcord_logger.Logger("ErrorsHandling");
|
|
2662
2510
|
/**
|
|
2663
2511
|
* The single throttle for every fault publish, so a recurring fault reports once per window across both
|
|
2664
2512
|
* the interaction and event paths. Exported so tests reset it between cases.
|
|
@@ -2798,7 +2646,7 @@ function interactionKind(interaction) {
|
|
|
2798
2646
|
|
|
2799
2647
|
//#endregion
|
|
2800
2648
|
//#region src/bot/handleEventFault.ts
|
|
2801
|
-
const logger$1 = new
|
|
2649
|
+
const logger$1 = new _seedcord_logger.Logger("EventBoundary");
|
|
2802
2650
|
/**
|
|
2803
2651
|
* The event controller boundary. Reports a throw from an event handler and never replies, since a
|
|
2804
2652
|
* generic event has no reply target. A {@link Silence} or a non-reporting {@link Notice} stops quietly, a
|
|
@@ -2842,20 +2690,23 @@ function handleEventFault(caught, eventName, handlerName, args, core) {
|
|
|
2842
2690
|
*/
|
|
2843
2691
|
var EventDispatcher = class {
|
|
2844
2692
|
core;
|
|
2845
|
-
logger = new
|
|
2693
|
+
logger = new _seedcord_logger.Logger("Events");
|
|
2846
2694
|
isInitialized = false;
|
|
2847
2695
|
name = "Events";
|
|
2848
2696
|
eventMap = /* @__PURE__ */ new Map();
|
|
2849
2697
|
middlewares = [];
|
|
2850
2698
|
executedOnceHandlers = /* @__PURE__ */ new Set();
|
|
2851
2699
|
attachedEvents = /* @__PURE__ */ new Set();
|
|
2700
|
+
loading = false;
|
|
2701
|
+
loadedHandlers = [];
|
|
2702
|
+
loadedMiddlewares = [];
|
|
2852
2703
|
hmrHandler;
|
|
2853
2704
|
constructor(core) {
|
|
2854
2705
|
this.core = core;
|
|
2855
2706
|
const eventsDir = this.core.config.bot.events.path;
|
|
2856
2707
|
if (!eventsDir) throw new _seedcord_errors_internal.SeedcordError(_seedcord_errors.SeedcordErrorCode.CoreControllerPathMissing, ["EventDispatcher", "events"]);
|
|
2857
2708
|
if (!envapt.Envapter.isDevelopment && !envapt.Envapter.isTest) return;
|
|
2858
|
-
this.hmrHandler = new HmrModuleHandler({
|
|
2709
|
+
this.hmrHandler = new _seedcord_core_hmr.HmrModuleHandler({
|
|
2859
2710
|
handlersDir: eventsDir,
|
|
2860
2711
|
...(0, _seedcord_utils.hasKeys)(this.core.config.bot.events, ["middlewares"]) && { middlewaresDir: this.core.config.bot.events.middlewares },
|
|
2861
2712
|
isHandler: this.isEventHandlerClass.bind(this),
|
|
@@ -2878,23 +2729,32 @@ var EventDispatcher = class {
|
|
|
2878
2729
|
this.isInitialized = true;
|
|
2879
2730
|
const handlersDir = this.core.config.bot.events.path;
|
|
2880
2731
|
if (!handlersDir) return;
|
|
2881
|
-
this.logger.info(chalk.default.bold(handlersDir));
|
|
2882
2732
|
const middlewareDir = (0, _seedcord_utils.hasKeys)(this.core.config.bot.events, ["middlewares"]) ? this.core.config.bot.events.middlewares : void 0;
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
|
|
2733
|
+
this.loading = true;
|
|
2734
|
+
this.loadedHandlers.length = 0;
|
|
2735
|
+
this.loadedMiddlewares.length = 0;
|
|
2736
|
+
try {
|
|
2737
|
+
if (middlewareDir) await this.loadMiddlewares(middlewareDir);
|
|
2738
|
+
await this.loadHandlers(handlersDir);
|
|
2739
|
+
} finally {
|
|
2740
|
+
this.loading = false;
|
|
2886
2741
|
}
|
|
2887
|
-
await this.loadHandlers(handlersDir);
|
|
2888
2742
|
this.attachToClient();
|
|
2889
|
-
this.
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
|
|
2743
|
+
this.reportLoad();
|
|
2744
|
+
}
|
|
2745
|
+
reportLoad() {
|
|
2746
|
+
const { utils } = this.logger;
|
|
2747
|
+
utils.summary("Loaded", {
|
|
2748
|
+
"event handlers": this.loadedHandlers.length,
|
|
2749
|
+
middlewares: this.loadedMiddlewares.length
|
|
2893
2750
|
});
|
|
2894
|
-
this.
|
|
2751
|
+
if (this.loadedMiddlewares.length > 0) utils.block("Loaded event middlewares", utils.entries(this.loadedMiddlewares));
|
|
2752
|
+
const perEvent = {};
|
|
2753
|
+
for (const [event, handlers] of this.eventMap) perEvent[event] = handlers.length;
|
|
2754
|
+
utils.block("Loaded event handlers", [...utils.entries(this.loadedHandlers), ...utils.counts(perEvent)]);
|
|
2895
2755
|
}
|
|
2896
2756
|
async loadHandlers(dir) {
|
|
2897
|
-
await (0,
|
|
2757
|
+
await (0, _seedcord_utils_node.traverseDirectory)(dir, (fullPath, relativePath, imported) => {
|
|
2898
2758
|
for (const val of Object.values(imported)) {
|
|
2899
2759
|
if (!this.isEventHandlerClass(val)) continue;
|
|
2900
2760
|
this.registerHandler(val, relativePath);
|
|
@@ -2903,7 +2763,7 @@ var EventDispatcher = class {
|
|
|
2903
2763
|
}, this.logger);
|
|
2904
2764
|
}
|
|
2905
2765
|
async loadMiddlewares(dir) {
|
|
2906
|
-
await (0,
|
|
2766
|
+
await (0, _seedcord_utils_node.traverseDirectory)(dir, (fullPath, relativePath, imported) => {
|
|
2907
2767
|
for (const val of Object.values(imported)) {
|
|
2908
2768
|
if (!this.isMiddlewareClass(val)) continue;
|
|
2909
2769
|
this.registerMiddleware(val, relativePath);
|
|
@@ -2941,7 +2801,14 @@ var EventDispatcher = class {
|
|
|
2941
2801
|
...metadata.events && { events: metadata.events }
|
|
2942
2802
|
});
|
|
2943
2803
|
this.middlewares.sort((a, b) => a.priority - b.priority);
|
|
2944
|
-
|
|
2804
|
+
if (this.loading) {
|
|
2805
|
+
this.loadedMiddlewares.push({
|
|
2806
|
+
name: `${middlewareCtor.name} (${metadata.priority})`,
|
|
2807
|
+
from: (0, _seedcord_utils.formatFilePath)(relativePath)
|
|
2808
|
+
});
|
|
2809
|
+
return;
|
|
2810
|
+
}
|
|
2811
|
+
this.logger.utils.registration(`${middlewareCtor.name} ${_seedcord_logger.paint.mute(`(${metadata.priority})`)}`, relativePath, "event middleware");
|
|
2945
2812
|
}
|
|
2946
2813
|
async runMiddlewares(eventName, args) {
|
|
2947
2814
|
for (const { ctor, events } of this.middlewares) {
|
|
@@ -2982,7 +2849,12 @@ var EventDispatcher = class {
|
|
|
2982
2849
|
const names = areRoutes(raw) ? raw : typeof raw === "string" ? [raw] : [];
|
|
2983
2850
|
for (const name of names) register(name, "on");
|
|
2984
2851
|
}
|
|
2985
|
-
|
|
2852
|
+
const from = (0, _seedcord_utils.formatFilePath)(relativePath);
|
|
2853
|
+
if (this.loading) this.loadedHandlers.push({
|
|
2854
|
+
name: handlerClass.name,
|
|
2855
|
+
from
|
|
2856
|
+
});
|
|
2857
|
+
else this.logger.utils.registration(handlerClass.name, from);
|
|
2986
2858
|
}
|
|
2987
2859
|
attachToClient() {
|
|
2988
2860
|
for (const [eventName] of this.eventMap) this.attachListener(eventName);
|
|
@@ -2991,12 +2863,12 @@ var EventDispatcher = class {
|
|
|
2991
2863
|
if (this.attachedEvents.has(eventName)) return;
|
|
2992
2864
|
this.attachedEvents.add(eventName);
|
|
2993
2865
|
const handlerEntries = this.eventMap.get(eventName);
|
|
2994
|
-
this.logger.debug(`Attaching ${
|
|
2866
|
+
this.logger.debug(`Attaching ${_seedcord_logger.paint.mint.bold(eventName)} to the client with ${_seedcord_logger.paint.mute(handlerEntries?.length ?? 0)} handler(s)`);
|
|
2995
2867
|
this.core.bot.client.on(eventName, (...args) => {
|
|
2996
|
-
this.core.bot.
|
|
2868
|
+
this.core.bot.emitSafe("any:event", eventName, ...args);
|
|
2997
2869
|
(async () => {
|
|
2998
2870
|
await this.processEvent(eventName, args).catch((err) => {
|
|
2999
|
-
this.logger.error(`[${
|
|
2871
|
+
this.logger.error(`[${_seedcord_logger.paint.coral.bold("UNHANDLED ERROR AT ROOT")}] ${err.name}`, err.stack);
|
|
3000
2872
|
this.core.bot.emit("error:unhandled:event", err);
|
|
3001
2873
|
});
|
|
3002
2874
|
})();
|
|
@@ -3018,7 +2890,7 @@ var EventDispatcher = class {
|
|
|
3018
2890
|
}
|
|
3019
2891
|
async processHandler(eventName, ctor, args) {
|
|
3020
2892
|
try {
|
|
3021
|
-
this.logger.debug(`Processing ${
|
|
2893
|
+
this.logger.debug(`Processing ${_seedcord_logger.paint.mint.bold(eventName)} with ${_seedcord_logger.paint.mute(ctor.name)}`);
|
|
3022
2894
|
const handler = new ctor(args, this.core, eventName);
|
|
3023
2895
|
await (0, _seedcord_core_internal.runHandlerGates)(ctor, eventGateContext(eventName, args, this.core));
|
|
3024
2896
|
await handler.execute();
|
|
@@ -3047,7 +2919,7 @@ var UnhandledEvent = class extends InteractionHandler {
|
|
|
3047
2919
|
|
|
3048
2920
|
//#endregion
|
|
3049
2921
|
//#region src/bot/handleInteractionFault.ts
|
|
3050
|
-
const logger = new
|
|
2922
|
+
const logger = new _seedcord_logger.Logger("InteractionBoundary");
|
|
3051
2923
|
/**
|
|
3052
2924
|
* The interaction controller boundary. Sorts a throw from any handler-lifecycle phase into the right
|
|
3053
2925
|
* user reply plus the right bus event, building a {@link ReplySender} lazily so it reads the live
|
|
@@ -3094,7 +2966,7 @@ async function handleInteractionFault(caught, interaction, core) {
|
|
|
3094
2966
|
*/
|
|
3095
2967
|
var InteractionDispatcher = class {
|
|
3096
2968
|
core;
|
|
3097
|
-
logger = new
|
|
2969
|
+
logger = new _seedcord_logger.Logger("Interactions");
|
|
3098
2970
|
isInitialized = false;
|
|
3099
2971
|
name = "Interactions";
|
|
3100
2972
|
slashMap = /* @__PURE__ */ new Map();
|
|
@@ -3110,6 +2982,9 @@ var InteractionDispatcher = class {
|
|
|
3110
2982
|
autocompleteMap = /* @__PURE__ */ new Map();
|
|
3111
2983
|
keysToIgnore = /* @__PURE__ */ new Set();
|
|
3112
2984
|
middlewares = [];
|
|
2985
|
+
loading = false;
|
|
2986
|
+
loadedHandlers = [];
|
|
2987
|
+
loadedMiddlewares = [];
|
|
3113
2988
|
hmrHandler;
|
|
3114
2989
|
routeTypes = [
|
|
3115
2990
|
[_seedcord_core_internal.InteractionRoutes.Slash, this.slashMap],
|
|
@@ -3132,7 +3007,7 @@ var InteractionDispatcher = class {
|
|
|
3132
3007
|
const interactionsDir = this.core.config.bot.interactions.path;
|
|
3133
3008
|
if (!interactionsDir) throw new _seedcord_errors_internal.SeedcordError(_seedcord_errors.SeedcordErrorCode.CoreControllerPathMissing, ["InteractionDispatcher", "interactions"]);
|
|
3134
3009
|
if (!envapt.Envapter.isDevelopment && !envapt.Envapter.isTest) return;
|
|
3135
|
-
this.hmrHandler = new HmrModuleHandler({
|
|
3010
|
+
this.hmrHandler = new _seedcord_core_hmr.HmrModuleHandler({
|
|
3136
3011
|
handlersDir: interactionsDir,
|
|
3137
3012
|
...(0, _seedcord_utils.hasKeys)(this.core.config.bot.interactions, ["middlewares"]) && this.core.config.bot.interactions.middlewares && { middlewaresDir: this.core.config.bot.interactions.middlewares },
|
|
3138
3013
|
isHandler: this.isHandlerClass.bind(this),
|
|
@@ -3152,7 +3027,7 @@ var InteractionDispatcher = class {
|
|
|
3152
3027
|
* @internal
|
|
3153
3028
|
*/
|
|
3154
3029
|
warnUnhandledRoutes(commandLeaves) {
|
|
3155
|
-
for (const route of commandLeaves) if (!this.slashMap.has(route)) this.logger.warn(`Slash route ${
|
|
3030
|
+
for (const route of commandLeaves) if (!this.slashMap.has(route)) this.logger.warn(`Slash route ${_seedcord_logger.paint.sky.bold(route)} has no registered ${chalk.default.bold("@SlashRoute")} handler.`);
|
|
3156
3031
|
}
|
|
3157
3032
|
/**
|
|
3158
3033
|
* Warns for each context-menu command with no matching handler, which would fall through to UnhandledEvent
|
|
@@ -3161,8 +3036,8 @@ var InteractionDispatcher = class {
|
|
|
3161
3036
|
* @internal
|
|
3162
3037
|
*/
|
|
3163
3038
|
warnUnhandledContextMenuRoutes(leaves) {
|
|
3164
|
-
for (const name of leaves.user) if (!this.userContextMenuMap.has(name)) this.logger.warn(`User context menu ${
|
|
3165
|
-
for (const name of leaves.message) if (!this.messageContextMenuMap.has(name)) this.logger.warn(`Message context menu ${
|
|
3039
|
+
for (const name of leaves.user) if (!this.userContextMenuMap.has(name)) this.logger.warn(`User context menu ${_seedcord_logger.paint.sky.bold(name)} has no registered ${chalk.default.bold("@ContextMenuRoute")} handler.`);
|
|
3040
|
+
for (const name of leaves.message) if (!this.messageContextMenuMap.has(name)) this.logger.warn(`Message context menu ${_seedcord_logger.paint.sky.bold(name)} has no registered ${chalk.default.bold("@ContextMenuRoute")} handler.`);
|
|
3166
3041
|
}
|
|
3167
3042
|
getArtifacts(handlerClass) {
|
|
3168
3043
|
const artifacts = [];
|
|
@@ -3180,32 +3055,42 @@ var InteractionDispatcher = class {
|
|
|
3180
3055
|
this.isInitialized = true;
|
|
3181
3056
|
const handlersDir = this.core.config.bot.interactions.path;
|
|
3182
3057
|
if (!handlersDir) return;
|
|
3183
|
-
this.logger.info(chalk.default.bold(handlersDir));
|
|
3184
3058
|
const middlewareDir = (0, _seedcord_utils.hasKeys)(this.core.config.bot.interactions, ["middlewares"]) ? this.core.config.bot.interactions.middlewares : void 0;
|
|
3185
|
-
|
|
3186
|
-
|
|
3187
|
-
|
|
3059
|
+
this.loading = true;
|
|
3060
|
+
this.loadedHandlers.length = 0;
|
|
3061
|
+
this.loadedMiddlewares.length = 0;
|
|
3062
|
+
try {
|
|
3063
|
+
if (middlewareDir) await this.loadMiddlewares(middlewareDir);
|
|
3064
|
+
await this.loadHandlers(handlersDir);
|
|
3065
|
+
} finally {
|
|
3066
|
+
this.loading = false;
|
|
3188
3067
|
}
|
|
3189
|
-
await this.loadHandlers(handlersDir);
|
|
3190
3068
|
this.attachToClient();
|
|
3191
|
-
this.
|
|
3192
|
-
|
|
3193
|
-
|
|
3194
|
-
|
|
3195
|
-
|
|
3196
|
-
|
|
3197
|
-
|
|
3198
|
-
|
|
3199
|
-
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
|
|
3069
|
+
this.reportLoad();
|
|
3070
|
+
}
|
|
3071
|
+
reportLoad() {
|
|
3072
|
+
const { utils } = this.logger;
|
|
3073
|
+
utils.summary("Loaded", {
|
|
3074
|
+
"interaction handlers": this.loadedHandlers.length,
|
|
3075
|
+
middlewares: this.loadedMiddlewares.length
|
|
3076
|
+
});
|
|
3077
|
+
if (this.loadedMiddlewares.length > 0) utils.block("Loaded middlewares", utils.entries(this.loadedMiddlewares));
|
|
3078
|
+
utils.block("Loaded interaction handlers", [...utils.entries(this.loadedHandlers), ...utils.counts({
|
|
3079
|
+
slash: this.slashMap.size,
|
|
3080
|
+
buttons: this.buttonMap.size,
|
|
3081
|
+
modals: this.modalMap.size,
|
|
3082
|
+
"string selects": this.stringSelectMap.size,
|
|
3083
|
+
"user selects": this.userSelectMap.size,
|
|
3084
|
+
"role selects": this.roleSelectMap.size,
|
|
3085
|
+
"channel selects": this.channelSelectMap.size,
|
|
3086
|
+
"mentionable selects": this.mentionableSelectMap.size,
|
|
3087
|
+
"message menus": this.messageContextMenuMap.size,
|
|
3088
|
+
"user menus": this.userContextMenuMap.size,
|
|
3089
|
+
autocomplete: this.autocompleteMap.size
|
|
3090
|
+
})]);
|
|
3206
3091
|
}
|
|
3207
3092
|
async loadHandlers(dir) {
|
|
3208
|
-
await (0,
|
|
3093
|
+
await (0, _seedcord_utils_node.traverseDirectory)(dir, (fullPath, relativePath, imported) => {
|
|
3209
3094
|
for (const val of Object.values(imported)) {
|
|
3210
3095
|
if (!this.isHandlerClass(val)) continue;
|
|
3211
3096
|
this.registerHandler(val, relativePath);
|
|
@@ -3214,7 +3099,7 @@ var InteractionDispatcher = class {
|
|
|
3214
3099
|
}, this.logger);
|
|
3215
3100
|
}
|
|
3216
3101
|
async loadMiddlewares(dir) {
|
|
3217
|
-
await (0,
|
|
3102
|
+
await (0, _seedcord_utils_node.traverseDirectory)(dir, (fullPath, relativePath, imported) => {
|
|
3218
3103
|
for (const val of Object.values(imported)) {
|
|
3219
3104
|
if (!this.isMiddlewareClass(val)) continue;
|
|
3220
3105
|
this.registerMiddleware(val, relativePath);
|
|
@@ -3232,7 +3117,14 @@ var InteractionDispatcher = class {
|
|
|
3232
3117
|
priority: metadata.priority
|
|
3233
3118
|
});
|
|
3234
3119
|
this.middlewares.sort((a, b) => a.priority - b.priority);
|
|
3235
|
-
|
|
3120
|
+
if (this.loading) {
|
|
3121
|
+
this.loadedMiddlewares.push({
|
|
3122
|
+
name: `${middlewareCtor.name} (${metadata.priority})`,
|
|
3123
|
+
from: (0, _seedcord_utils.formatFilePath)(relativePath)
|
|
3124
|
+
});
|
|
3125
|
+
return;
|
|
3126
|
+
}
|
|
3127
|
+
this.logger.utils.registration(`${middlewareCtor.name} ${_seedcord_logger.paint.mute(`(${metadata.priority})`)}`, relativePath, "middleware");
|
|
3236
3128
|
}
|
|
3237
3129
|
isHandlerClass(obj) {
|
|
3238
3130
|
if (typeof obj !== "function") return false;
|
|
@@ -3256,9 +3148,15 @@ var InteractionDispatcher = class {
|
|
|
3256
3148
|
]);
|
|
3257
3149
|
writes.push([map, route]);
|
|
3258
3150
|
}
|
|
3259
|
-
this.logger.utils.registration(handlerClass.name, (0, _seedcord_utils.formatFilePath)(relativePath));
|
|
3260
3151
|
}
|
|
3152
|
+
if (writes.length === 0) return;
|
|
3261
3153
|
for (const [map, route] of writes) map.set(route, handlerClass);
|
|
3154
|
+
const from = (0, _seedcord_utils.formatFilePath)(relativePath);
|
|
3155
|
+
if (this.loading) this.loadedHandlers.push({
|
|
3156
|
+
name: handlerClass.name,
|
|
3157
|
+
from
|
|
3158
|
+
});
|
|
3159
|
+
else this.logger.utils.registration(handlerClass.name, from);
|
|
3262
3160
|
}
|
|
3263
3161
|
/** @internal For use in dev mode */
|
|
3264
3162
|
async onHmr(event) {
|
|
@@ -3284,9 +3182,9 @@ var InteractionDispatcher = class {
|
|
|
3284
3182
|
}
|
|
3285
3183
|
attachToClient() {
|
|
3286
3184
|
this.core.bot.client.on(discord_js.Events.InteractionCreate, (interaction) => {
|
|
3287
|
-
this.core.bot.
|
|
3185
|
+
this.core.bot.emitSafe("any:interaction", interaction);
|
|
3288
3186
|
this.handleInteraction(interaction).catch((err) => {
|
|
3289
|
-
this.logger.error(`[${
|
|
3187
|
+
this.logger.error(`[${_seedcord_logger.paint.coral.bold("UNHANDLED ERROR AT ROOT")}] ${err.name}`, err.stack);
|
|
3290
3188
|
this.core.bot.emit("error:unhandled:interaction", err);
|
|
3291
3189
|
});
|
|
3292
3190
|
});
|
|
@@ -3303,11 +3201,12 @@ var InteractionDispatcher = class {
|
|
|
3303
3201
|
if (!interaction.isAutocomplete()) for (const { ctor } of this.middlewares) await new ctor(interaction, this.core).execute();
|
|
3304
3202
|
let HandlerCtor = getHandler(key);
|
|
3305
3203
|
if (!HandlerCtor) {
|
|
3306
|
-
this.logger.warn(`No handler found for key ${
|
|
3204
|
+
this.logger.warn(`No handler found for key ${_seedcord_logger.paint.sky.bold(key)}. Falling back to UnhandledEvent.`);
|
|
3307
3205
|
HandlerCtor = UnhandledEvent;
|
|
3308
3206
|
}
|
|
3309
|
-
this.logger.debug(`Processing ${
|
|
3310
|
-
const
|
|
3207
|
+
this.logger.debug(`Processing ${_seedcord_logger.paint.mint.bold(key)} with ${_seedcord_logger.paint.mute(HandlerCtor.name)}`);
|
|
3208
|
+
const dispatch = new _seedcord_core.DispatchContext((0, _seedcord_core_internal.routeIdOf)(HandlerCtor));
|
|
3209
|
+
const handler = new HandlerCtor(interaction, this.core, dispatch);
|
|
3311
3210
|
if (!interaction.isAutocomplete()) await (0, _seedcord_core_internal.runHandlerGates)(HandlerCtor, interactionGateContext(interaction, this.core));
|
|
3312
3211
|
await handler.execute();
|
|
3313
3212
|
} catch (caught) {
|
|
@@ -3388,7 +3287,7 @@ var InteractionDispatcher = class {
|
|
|
3388
3287
|
async handleAutocomplete(interaction) {
|
|
3389
3288
|
const route = slashRouteOf(interaction);
|
|
3390
3289
|
if (!this.autocompleteMap.has(route)) {
|
|
3391
|
-
this.logger.warn(`No autocomplete handler for ${
|
|
3290
|
+
this.logger.warn(`No autocomplete handler for ${_seedcord_logger.paint.sky.bold(route)}.`);
|
|
3392
3291
|
await interaction.respond([]);
|
|
3393
3292
|
return;
|
|
3394
3293
|
}
|
|
@@ -3420,7 +3319,7 @@ function __decorate(decorators, target, key, desc) {
|
|
|
3420
3319
|
*/
|
|
3421
3320
|
var Bot = class extends Plugin {
|
|
3422
3321
|
/** @internal */
|
|
3423
|
-
logger = new
|
|
3322
|
+
logger = new _seedcord_logger.Logger("Bot");
|
|
3424
3323
|
isInitialized = false;
|
|
3425
3324
|
_client;
|
|
3426
3325
|
interactions;
|
|
@@ -3498,48 +3397,14 @@ var Bot = class extends Plugin {
|
|
|
3498
3397
|
emit(event, ...args) {
|
|
3499
3398
|
return super.emit(event, ...args);
|
|
3500
3399
|
}
|
|
3501
|
-
|
|
3502
|
-
|
|
3503
|
-
|
|
3504
|
-
//#endregion
|
|
3505
|
-
//#region src/hmr/HmrManager.ts
|
|
3506
|
-
var HmrManager = class {
|
|
3507
|
-
logger = new _seedcord_services.Logger("HMR", { channel: "hmr" });
|
|
3508
|
-
listeners = /* @__PURE__ */ new Set();
|
|
3509
|
-
constructor() {}
|
|
3510
|
-
/** @internal */
|
|
3511
|
-
init() {
|
|
3512
|
-
if (!{}.hot) return;
|
|
3513
|
-
setDevChannel((0, _seedcord_types_internal.wrapHot)({}.hot));
|
|
3514
|
-
if (envapt.Envapter.isDevelopment || envapt.Envapter.isTest) {
|
|
3515
|
-
this.logger.info("Enabled");
|
|
3516
|
-
getDevChannel()?.on("seedcord:hmr", (payload) => {
|
|
3517
|
-
const affected = payload.affectedModules?.length ?? 0;
|
|
3518
|
-
this.logger.info(`${chalk.default.bold("1")} module changed, ${chalk.default.bold(affected)} affected modules`);
|
|
3519
|
-
if (payload.affectedModules) this.logger.utils.list(payload.affectedModules.map((mod) => (0, _seedcord_utils.formatFilePath)(mod)), "Affected modules: ");
|
|
3520
|
-
this.handleUpdate(payload);
|
|
3521
|
-
});
|
|
3522
|
-
}
|
|
3523
|
-
}
|
|
3524
|
-
/** @internal */
|
|
3525
|
-
register(listener) {
|
|
3526
|
-
this.listeners.add(listener);
|
|
3527
|
-
}
|
|
3528
|
-
/** @internal */
|
|
3529
|
-
unregister(listener) {
|
|
3530
|
-
this.listeners.delete(listener);
|
|
3400
|
+
emitSafe(event, ...args) {
|
|
3401
|
+
return super.emitSafe(event, ...args);
|
|
3531
3402
|
}
|
|
3532
|
-
|
|
3533
|
-
|
|
3534
|
-
try {
|
|
3535
|
-
await listener.onHmr(event);
|
|
3536
|
-
} catch (error) {
|
|
3537
|
-
this.logger.error(`Error handling HMR update in ${chalk.default.bold(listener.name)}: `, error);
|
|
3538
|
-
}
|
|
3539
|
-
});
|
|
3540
|
-
await Promise.all(promises);
|
|
3403
|
+
onListenerError(error, event) {
|
|
3404
|
+
this.logger.error(`listener for ${String(event)} threw`, error);
|
|
3541
3405
|
}
|
|
3542
3406
|
};
|
|
3407
|
+
__decorate([(0, envapt_legacy.Envapt)("DISCORD_BOT_TOKEN", { converter: (raw) => (0, _seedcord_errors_internal.validateDiscordToken)(raw) }), __decorateMetadata("design:type", String)], Bot.prototype, "botToken", void 0);
|
|
3543
3408
|
|
|
3544
3409
|
//#endregion
|
|
3545
3410
|
//#region src/subscribers/bases/webhookHelpers.ts
|
|
@@ -3606,7 +3471,7 @@ let HandledException = class HandledException extends WebhookLog {
|
|
|
3606
3471
|
}
|
|
3607
3472
|
}
|
|
3608
3473
|
};
|
|
3609
|
-
__decorate([(0,
|
|
3474
|
+
__decorate([(0, envapt_legacy.Envapt)("HANDLED_EXCEPTION_WEBHOOK_URL", { converter: (raw) => webhookUrlValidator$1(raw) }), __decorateMetadata("design:type", String)], HandledException, "handledExceptionWebhookUrl", void 0);
|
|
3610
3475
|
HandledException = _HandledException = __decorate([Subscribe("handledException")], HandledException);
|
|
3611
3476
|
var HandledExceptionContainer = class extends _seedcord_core.BuilderComponent {
|
|
3612
3477
|
constructor(data) {
|
|
@@ -3676,7 +3541,7 @@ let UnknownException = class UnknownException extends WebhookLog {
|
|
|
3676
3541
|
}
|
|
3677
3542
|
}
|
|
3678
3543
|
};
|
|
3679
|
-
__decorate([(0,
|
|
3544
|
+
__decorate([(0, envapt_legacy.Envapt)("UNKNOWN_EXCEPTION_WEBHOOK_URL", { converter: (raw) => webhookUrlValidator(raw) }), __decorateMetadata("design:type", String)], UnknownException, "unknownExceptionWebhookUrl", void 0);
|
|
3680
3545
|
UnknownException = _UnknownException = __decorate([Subscribe("unknownException")], UnknownException);
|
|
3681
3546
|
var UnhandledErrorContainer = class extends _seedcord_core.BuilderComponent {
|
|
3682
3547
|
constructor(data) {
|
|
@@ -3715,7 +3580,7 @@ var UnhandledErrorContainer = class extends _seedcord_core.BuilderComponent {
|
|
|
3715
3580
|
*/
|
|
3716
3581
|
var Bus = class extends Plugin {
|
|
3717
3582
|
core;
|
|
3718
|
-
logger = new
|
|
3583
|
+
logger = new _seedcord_logger.Logger("Subscribers");
|
|
3719
3584
|
/** @internal */
|
|
3720
3585
|
name = "Subscribers";
|
|
3721
3586
|
isInitialized = false;
|
|
@@ -3727,7 +3592,7 @@ var Bus = class extends Plugin {
|
|
|
3727
3592
|
this.core = core;
|
|
3728
3593
|
if (this.core.config.subscribers.path) {
|
|
3729
3594
|
if (!envapt.Envapter.isDevelopment && !envapt.Envapter.isTest) return;
|
|
3730
|
-
this.hmrHandler = new HmrModuleHandler({
|
|
3595
|
+
this.hmrHandler = new _seedcord_core_hmr.HmrModuleHandler({
|
|
3731
3596
|
handlersDir: this.core.config.subscribers.path,
|
|
3732
3597
|
isHandler: this.isSubscriber.bind(this),
|
|
3733
3598
|
registerHandler: this.registerSubscriber.bind(this),
|
|
@@ -3760,7 +3625,7 @@ var Bus = class extends Plugin {
|
|
|
3760
3625
|
if (this.hmrHandler) await this.hmrHandler.handle(event);
|
|
3761
3626
|
}
|
|
3762
3627
|
async loadSubscribers(dir) {
|
|
3763
|
-
await (0,
|
|
3628
|
+
await (0, _seedcord_utils_node.traverseDirectory)(dir, (fullPath, relativePath, imported) => {
|
|
3764
3629
|
for (const exportName of Object.keys(imported)) {
|
|
3765
3630
|
const val = imported[exportName];
|
|
3766
3631
|
if (this.isSubscriber(val)) {
|
|
@@ -3831,7 +3696,7 @@ var Bus = class extends Plugin {
|
|
|
3831
3696
|
//#endregion
|
|
3832
3697
|
//#region src/version.ts
|
|
3833
3698
|
/** Package version */
|
|
3834
|
-
const version = "0.1.0-next.
|
|
3699
|
+
const version = "0.1.0-next.2";
|
|
3835
3700
|
|
|
3836
3701
|
//#endregion
|
|
3837
3702
|
//#region src/Seedcord.ts
|
|
@@ -3850,6 +3715,8 @@ var Seedcord = class Seedcord extends Pluggable {
|
|
|
3850
3715
|
/** @internal */
|
|
3851
3716
|
version = version;
|
|
3852
3717
|
static isInstantiated = false;
|
|
3718
|
+
healthCheck;
|
|
3719
|
+
hmrManager;
|
|
3853
3720
|
/** @see {@link CoordinatedShutdown} */
|
|
3854
3721
|
shutdown;
|
|
3855
3722
|
/** @see {@link CoordinatedStartup} */
|
|
@@ -3860,10 +3727,6 @@ var Seedcord = class Seedcord extends Pluggable {
|
|
|
3860
3727
|
bot;
|
|
3861
3728
|
/** @see {@link IRateLimiter} */
|
|
3862
3729
|
rateLimiter;
|
|
3863
|
-
/** @see {@link HealthCheck} */
|
|
3864
|
-
healthCheck;
|
|
3865
|
-
/** @see {@link HmrManager} */
|
|
3866
|
-
hmrManager;
|
|
3867
3730
|
/**
|
|
3868
3731
|
* Creates a new Seedcord instance
|
|
3869
3732
|
*
|
|
@@ -3877,25 +3740,26 @@ var Seedcord = class Seedcord extends Pluggable {
|
|
|
3877
3740
|
const startup = new _seedcord_services.CoordinatedStartup();
|
|
3878
3741
|
super(shutdown, startup);
|
|
3879
3742
|
this.config = config;
|
|
3743
|
+
(0, _seedcord_logger_node.installNodeDefaults)(config.logger);
|
|
3880
3744
|
(0, _seedcord_core_internal.setBotColor)(config.botColor);
|
|
3881
3745
|
this.shutdown = shutdown;
|
|
3882
3746
|
this.startup = startup;
|
|
3883
|
-
this.hmrManager = new HmrManager();
|
|
3747
|
+
this.hmrManager = new _seedcord_core_internal.HmrManager();
|
|
3884
3748
|
this.hmrManager.init();
|
|
3885
3749
|
this.bus = new Bus(this);
|
|
3886
3750
|
this.bot = new Bot(this);
|
|
3887
|
-
this.rateLimiter = new _seedcord_rate_limiter.MemoryRateLimiter();
|
|
3751
|
+
this.rateLimiter = config.store ?? new _seedcord_rate_limiter.MemoryRateLimiter();
|
|
3888
3752
|
this.healthCheck = new _seedcord_services.HealthCheck(this.shutdown, config.healthCheck);
|
|
3889
3753
|
this.registerStartupTasks();
|
|
3890
3754
|
}
|
|
3891
|
-
/**
|
|
3755
|
+
/** The bot's discord username, populated after login. */
|
|
3756
|
+
get username() {
|
|
3757
|
+
return this.bot.client.user?.username;
|
|
3758
|
+
}
|
|
3892
3759
|
static reset() {
|
|
3893
3760
|
Seedcord.isInstantiated = false;
|
|
3761
|
+
_seedcord_logger.LoggerChannelRegistry.instance.reset();
|
|
3894
3762
|
}
|
|
3895
|
-
/**
|
|
3896
|
-
* Registers default startup tasks
|
|
3897
|
-
* @internal
|
|
3898
|
-
*/
|
|
3899
3763
|
registerStartupTasks() {
|
|
3900
3764
|
if (envapt.Envapter.isDevelopment || envapt.Envapter.isTest) this.registerHmrAwareModules();
|
|
3901
3765
|
this.startup.addTask(_seedcord_services.StartupPhase.Configuration, "Bus Initialization", async () => {
|
|
@@ -3947,7 +3811,6 @@ exports.Emojis = Emojis;
|
|
|
3947
3811
|
exports.EventHandler = EventHandler;
|
|
3948
3812
|
exports.EventMiddleware = EventMiddleware;
|
|
3949
3813
|
exports.Gated = Gated;
|
|
3950
|
-
exports.HmrModuleHandler = HmrModuleHandler;
|
|
3951
3814
|
exports.IgnoreBots = IgnoreBots;
|
|
3952
3815
|
exports.InteractionHandler = InteractionHandler;
|
|
3953
3816
|
exports.InteractionMiddleware = InteractionMiddleware;
|
|
@@ -4006,6 +3869,20 @@ Object.keys(_seedcord_errors).forEach(function (k) {
|
|
|
4006
3869
|
});
|
|
4007
3870
|
});
|
|
4008
3871
|
|
|
3872
|
+
Object.keys(_seedcord_event_emitter).forEach(function (k) {
|
|
3873
|
+
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|
|
3874
|
+
enumerable: true,
|
|
3875
|
+
get: function () { return _seedcord_event_emitter[k]; }
|
|
3876
|
+
});
|
|
3877
|
+
});
|
|
3878
|
+
|
|
3879
|
+
Object.keys(_seedcord_logger).forEach(function (k) {
|
|
3880
|
+
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|
|
3881
|
+
enumerable: true,
|
|
3882
|
+
get: function () { return _seedcord_logger[k]; }
|
|
3883
|
+
});
|
|
3884
|
+
});
|
|
3885
|
+
|
|
4009
3886
|
Object.keys(_seedcord_rate_limiter).forEach(function (k) {
|
|
4010
3887
|
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|
|
4011
3888
|
enumerable: true,
|