seedcord 0.1.1 → 0.2.1
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/README.md +5 -0
- package/dist/index.cjs +237 -1120
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +16 -540
- package/dist/index.d.mts +16 -540
- package/dist/index.d.ts +16 -540
- package/dist/index.mjs +212 -1084
- package/dist/index.mjs.map +1 -1
- package/package.json +12 -11
package/dist/index.cjs
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
require('reflect-metadata');
|
|
4
|
-
var
|
|
4
|
+
var services = require('@seedcord/services');
|
|
5
|
+
var chalk2 = require('chalk');
|
|
5
6
|
var discord_js = require('discord.js');
|
|
6
7
|
var envapt = require('envapt');
|
|
7
|
-
var
|
|
8
|
-
var path = require('path');
|
|
9
|
-
var winston = require('winston');
|
|
8
|
+
var utils = require('@seedcord/utils');
|
|
10
9
|
var crypto2 = require('crypto');
|
|
11
10
|
var events = require('events');
|
|
12
|
-
var http = require('http');
|
|
13
11
|
|
|
14
12
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
15
13
|
|
|
@@ -31,12 +29,74 @@ function _interopNamespace(e) {
|
|
|
31
29
|
return Object.freeze(n);
|
|
32
30
|
}
|
|
33
31
|
|
|
34
|
-
var
|
|
35
|
-
var path__namespace = /*#__PURE__*/_interopNamespace(path);
|
|
32
|
+
var chalk2__default = /*#__PURE__*/_interopDefault(chalk2);
|
|
36
33
|
var crypto2__namespace = /*#__PURE__*/_interopNamespace(crypto2);
|
|
37
34
|
|
|
38
35
|
var __defProp = Object.defineProperty;
|
|
39
36
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
37
|
+
var Plugin = class {
|
|
38
|
+
static {
|
|
39
|
+
__name(this, "Plugin");
|
|
40
|
+
}
|
|
41
|
+
pluggable;
|
|
42
|
+
constructor(pluggable) {
|
|
43
|
+
this.pluggable = pluggable;
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
var Pluggable = class _Pluggable {
|
|
47
|
+
static {
|
|
48
|
+
__name(this, "Pluggable");
|
|
49
|
+
}
|
|
50
|
+
isInitialized = false;
|
|
51
|
+
shutdown;
|
|
52
|
+
startup;
|
|
53
|
+
static PLUGIN_INIT_TIMEOUT_MS = 15e3;
|
|
54
|
+
constructor(shutdown, startup) {
|
|
55
|
+
this.shutdown = shutdown;
|
|
56
|
+
this.startup = startup;
|
|
57
|
+
}
|
|
58
|
+
async init() {
|
|
59
|
+
if (this.isInitialized) return this;
|
|
60
|
+
await this.startup.run();
|
|
61
|
+
this.isInitialized = true;
|
|
62
|
+
return this;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Attaches a plugin to this instance
|
|
66
|
+
*
|
|
67
|
+
* Plugins provide external functionality and are initialized during the specified startup phase.
|
|
68
|
+
* The plugin instance becomes available as a property in `core` wherever it's available.
|
|
69
|
+
*
|
|
70
|
+
* Make sure to augment the {@link Core} interface with the plugin type to ensure TypeScript recognizes it and provides intellisense.
|
|
71
|
+
*
|
|
72
|
+
* @typeParam Key - The property name for accessing the plugin
|
|
73
|
+
* @typeParam Ctor - The plugin constructor type
|
|
74
|
+
* @param key - Property name to access the plugin instance
|
|
75
|
+
* @param Plugin - Plugin constructor class
|
|
76
|
+
* @param startupPhase - When during startup to initialize this plugin ({@link StartupPhase})
|
|
77
|
+
* @param args - Additional arguments to pass to the plugin constructor
|
|
78
|
+
* @returns This instance with the plugin attached as a typed property
|
|
79
|
+
* @throws An {@link Error} When called after initialization or if key already exists
|
|
80
|
+
* @example
|
|
81
|
+
* ```typescript
|
|
82
|
+
* seedcord.attach('db', Mongo, StartupPhase.Configuration, { uri: 'mongodb://...', name: 'seedcord', dir: ... })
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
85
|
+
attach(key, Plugin2, startupPhase, ...args) {
|
|
86
|
+
if (this.isInitialized) throw new Error("Cannot attach a plugin after initialization.");
|
|
87
|
+
if (this[key]) throw new Error(`Plugin with key "${key}" already exists.`);
|
|
88
|
+
const instance = new Plugin2(this, ...args);
|
|
89
|
+
const entry = {
|
|
90
|
+
[key]: instance
|
|
91
|
+
};
|
|
92
|
+
this.startup.addTask(startupPhase, `Plugin:${key}`, async () => {
|
|
93
|
+
instance.logger.info(chalk2__default.default.bold("Initializing"));
|
|
94
|
+
await instance.init();
|
|
95
|
+
instance.logger.info(chalk2__default.default.bold("Initialized"));
|
|
96
|
+
}, _Pluggable.PLUGIN_INIT_TIMEOUT_MS);
|
|
97
|
+
return Object.assign(this, entry);
|
|
98
|
+
}
|
|
99
|
+
};
|
|
40
100
|
function _ts_decorate(decorators, target, key, desc) {
|
|
41
101
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
42
102
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -48,54 +108,6 @@ function _ts_metadata(k, v) {
|
|
|
48
108
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
49
109
|
}
|
|
50
110
|
__name(_ts_metadata, "_ts_metadata");
|
|
51
|
-
var Globals = class extends envapt.Envapter {
|
|
52
|
-
static {
|
|
53
|
-
__name(this, "Globals");
|
|
54
|
-
}
|
|
55
|
-
static botToken;
|
|
56
|
-
// Healthcheck
|
|
57
|
-
static healthCheckPort;
|
|
58
|
-
static healthCheckPath;
|
|
59
|
-
// Coordinated Shutdown
|
|
60
|
-
static shutdownIsEnabled;
|
|
61
|
-
// Unknown Exception Webhook URL
|
|
62
|
-
static unknownExceptionWebhookUrl;
|
|
63
|
-
// Variables
|
|
64
|
-
/** Default color for bot embeds - can be overridden by setting Globals.botColor */
|
|
65
|
-
static botColor = this.isProduction ? "#fe565a" : "#3fa045";
|
|
66
|
-
};
|
|
67
|
-
_ts_decorate([
|
|
68
|
-
envapt.Envapt("DISCORD_BOT_TOKEN", {
|
|
69
|
-
fallback: void 0
|
|
70
|
-
}),
|
|
71
|
-
_ts_metadata("design:type", String)
|
|
72
|
-
], Globals, "botToken", void 0);
|
|
73
|
-
_ts_decorate([
|
|
74
|
-
envapt.Envapt("HEALTH_CHECK_PORT", {
|
|
75
|
-
fallback: 6956
|
|
76
|
-
}),
|
|
77
|
-
_ts_metadata("design:type", Number)
|
|
78
|
-
], Globals, "healthCheckPort", void 0);
|
|
79
|
-
_ts_decorate([
|
|
80
|
-
envapt.Envapt("HEALTH_CHECK_PATH", {
|
|
81
|
-
fallback: "/healthcheck"
|
|
82
|
-
}),
|
|
83
|
-
_ts_metadata("design:type", String)
|
|
84
|
-
], Globals, "healthCheckPath", void 0);
|
|
85
|
-
_ts_decorate([
|
|
86
|
-
envapt.Envapt("SHUTDOWN_IS_ENABLED", {
|
|
87
|
-
fallback: false
|
|
88
|
-
}),
|
|
89
|
-
_ts_metadata("design:type", Boolean)
|
|
90
|
-
], Globals, "shutdownIsEnabled", void 0);
|
|
91
|
-
_ts_decorate([
|
|
92
|
-
envapt.Envapt("UNKNOWN_EXCEPTION_WEBHOOK_URL", {
|
|
93
|
-
fallback: void 0
|
|
94
|
-
}),
|
|
95
|
-
_ts_metadata("design:type", String)
|
|
96
|
-
], Globals, "unknownExceptionWebhookUrl", void 0);
|
|
97
|
-
|
|
98
|
-
// src/interfaces/Components.ts
|
|
99
111
|
var BuilderTypes = {
|
|
100
112
|
command: discord_js.SlashCommandBuilder,
|
|
101
113
|
embed: discord_js.EmbedBuilder,
|
|
@@ -109,7 +121,13 @@ var BuilderTypes = {
|
|
|
109
121
|
modal: discord_js.ModalBuilder,
|
|
110
122
|
context_menu: discord_js.ContextMenuCommandBuilder,
|
|
111
123
|
subcommand: discord_js.SlashCommandSubcommandBuilder,
|
|
112
|
-
group: discord_js.SlashCommandSubcommandGroupBuilder
|
|
124
|
+
group: discord_js.SlashCommandSubcommandGroupBuilder,
|
|
125
|
+
container: discord_js.ContainerBuilder,
|
|
126
|
+
text_display: discord_js.TextDisplayBuilder,
|
|
127
|
+
file: discord_js.FileBuilder,
|
|
128
|
+
media: discord_js.MediaGalleryBuilder,
|
|
129
|
+
section: discord_js.SectionBuilder,
|
|
130
|
+
separator: discord_js.SeparatorBuilder
|
|
113
131
|
};
|
|
114
132
|
var RowTypes = {
|
|
115
133
|
button: discord_js.ActionRowBuilder,
|
|
@@ -165,7 +183,7 @@ var BuilderComponent = class extends BaseComponent {
|
|
|
165
183
|
constructor(type) {
|
|
166
184
|
const ComponentClass = BuilderTypes[type];
|
|
167
185
|
super(ComponentClass);
|
|
168
|
-
if (this.instance instanceof discord_js.EmbedBuilder) this.instance.setColor(
|
|
186
|
+
if (this.instance instanceof discord_js.EmbedBuilder) this.instance.setColor(this.botColor);
|
|
169
187
|
if (this.instance instanceof discord_js.SlashCommandBuilder || this.instance instanceof discord_js.ContextMenuCommandBuilder) {
|
|
170
188
|
this.instance.setContexts(discord_js.InteractionContextType.Guild);
|
|
171
189
|
}
|
|
@@ -174,6 +192,12 @@ var BuilderComponent = class extends BaseComponent {
|
|
|
174
192
|
return this.instance;
|
|
175
193
|
}
|
|
176
194
|
};
|
|
195
|
+
_ts_decorate([
|
|
196
|
+
envapt.Envapt("DEFAULT_BOT_COLOR", {
|
|
197
|
+
fallback: "Default"
|
|
198
|
+
}),
|
|
199
|
+
_ts_metadata("design:type", typeof ColorResolvable === "undefined" ? Object : ColorResolvable)
|
|
200
|
+
], BuilderComponent.prototype, "botColor", void 0);
|
|
177
201
|
var RowComponent = class extends BaseComponent {
|
|
178
202
|
static {
|
|
179
203
|
__name(this, "RowComponent");
|
|
@@ -248,387 +272,6 @@ var CustomError = class extends Error {
|
|
|
248
272
|
}
|
|
249
273
|
};
|
|
250
274
|
|
|
251
|
-
// src/bot/errors/Database.ts
|
|
252
|
-
var DatabaseError = class extends CustomError {
|
|
253
|
-
static {
|
|
254
|
-
__name(this, "DatabaseError");
|
|
255
|
-
}
|
|
256
|
-
uuid;
|
|
257
|
-
_emit = true;
|
|
258
|
-
/**
|
|
259
|
-
* Creates a new DatabaseError.
|
|
260
|
-
*
|
|
261
|
-
* @param message - The error message describing what went wrong
|
|
262
|
-
* @param uuid - A unique identifier for this specific error instance
|
|
263
|
-
*/
|
|
264
|
-
constructor(message, uuid) {
|
|
265
|
-
super(message), this.uuid = uuid;
|
|
266
|
-
this.name = "DatabaseError";
|
|
267
|
-
this.response.setTitle("Database Error").setDescription(`An error occurred while interacting with the database.
|
|
268
|
-
### UUID: \`${this.uuid}\``);
|
|
269
|
-
}
|
|
270
|
-
};
|
|
271
|
-
var Logger = class _Logger {
|
|
272
|
-
static {
|
|
273
|
-
__name(this, "Logger");
|
|
274
|
-
}
|
|
275
|
-
static instances = /* @__PURE__ */ new Map();
|
|
276
|
-
static instance(prefix) {
|
|
277
|
-
let instance = this.instances.get(prefix);
|
|
278
|
-
if (!instance) {
|
|
279
|
-
instance = new _Logger(prefix);
|
|
280
|
-
this.instances.set(prefix, instance);
|
|
281
|
-
}
|
|
282
|
-
return instance;
|
|
283
|
-
}
|
|
284
|
-
constructor(transportName) {
|
|
285
|
-
const consoleTransport = this.createConsoleTransport(transportName);
|
|
286
|
-
this.initializeLogger(consoleTransport);
|
|
287
|
-
}
|
|
288
|
-
getFormatCustomizations() {
|
|
289
|
-
const padding = 7;
|
|
290
|
-
return [
|
|
291
|
-
winston.format.errors({
|
|
292
|
-
stack: true
|
|
293
|
-
}),
|
|
294
|
-
winston.format.splat(),
|
|
295
|
-
winston.format.colorize({
|
|
296
|
-
level: true
|
|
297
|
-
}),
|
|
298
|
-
winston.format.timestamp({
|
|
299
|
-
format: "D MMM, hh:mm:ss a"
|
|
300
|
-
}),
|
|
301
|
-
winston.format.printf((info) => {
|
|
302
|
-
const ts = String(info.timestamp ?? "");
|
|
303
|
-
const lvl = String(info.level).padEnd(padding);
|
|
304
|
-
const lbl = String(info.label ?? "");
|
|
305
|
-
const msg = String(info.message ?? "");
|
|
306
|
-
const base = `${ts} [${lvl}]: ${lbl} - ${msg}`;
|
|
307
|
-
const splatSym = Symbol.for("splat");
|
|
308
|
-
const raw = info[splatSym];
|
|
309
|
-
const extras = Array.isArray(raw) ? raw : [];
|
|
310
|
-
const cleaned = extras.filter((x) => !(x instanceof Error)).filter((x) => {
|
|
311
|
-
if (!x) return false;
|
|
312
|
-
if (typeof x !== "object") return true;
|
|
313
|
-
return Object.keys(x).length > 0;
|
|
314
|
-
});
|
|
315
|
-
let rendered = base;
|
|
316
|
-
if (typeof info.stack === "string") {
|
|
317
|
-
rendered += `
|
|
318
|
-
${String(info.stack)}`;
|
|
319
|
-
}
|
|
320
|
-
if (cleaned.length) {
|
|
321
|
-
const parts = [];
|
|
322
|
-
for (const x of cleaned) {
|
|
323
|
-
if (typeof x === "string") parts.push(x);
|
|
324
|
-
else {
|
|
325
|
-
try {
|
|
326
|
-
parts.push(JSON.stringify(x, null, 2));
|
|
327
|
-
} catch {
|
|
328
|
-
parts.push(String(x));
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
rendered += `
|
|
333
|
-
${parts.join(" ")}`;
|
|
334
|
-
}
|
|
335
|
-
return rendered;
|
|
336
|
-
})
|
|
337
|
-
];
|
|
338
|
-
}
|
|
339
|
-
createConsoleTransport(transportName) {
|
|
340
|
-
return new winston.transports.Console({
|
|
341
|
-
format: winston.format.combine(winston.format.label({
|
|
342
|
-
label: transportName
|
|
343
|
-
}), ...this.getFormatCustomizations()),
|
|
344
|
-
level: Globals.isDevelopment ? "silly" : Globals.isStaging ? "debug" : "info"
|
|
345
|
-
});
|
|
346
|
-
}
|
|
347
|
-
initializeLogger(consoleTransport) {
|
|
348
|
-
const transportsArray = [
|
|
349
|
-
consoleTransport
|
|
350
|
-
];
|
|
351
|
-
if (Globals.isDevelopment) {
|
|
352
|
-
const maxSizeInMB = 10;
|
|
353
|
-
transportsArray.push(new winston.transports.File({
|
|
354
|
-
filename: "logs/application.log",
|
|
355
|
-
level: "debug",
|
|
356
|
-
format: winston.format.combine(winston.format.uncolorize(), winston.format.errors({
|
|
357
|
-
stack: true
|
|
358
|
-
}), winston.format.timestamp(), winston.format.json({
|
|
359
|
-
bigint: true,
|
|
360
|
-
space: 2
|
|
361
|
-
})),
|
|
362
|
-
maxsize: maxSizeInMB * 1024 * 1024,
|
|
363
|
-
maxFiles: 5,
|
|
364
|
-
tailable: true
|
|
365
|
-
}));
|
|
366
|
-
}
|
|
367
|
-
this.logger = winston.createLogger({
|
|
368
|
-
transports: transportsArray
|
|
369
|
-
});
|
|
370
|
-
}
|
|
371
|
-
/**
|
|
372
|
-
* Logs an error message with optional additional data.
|
|
373
|
-
*
|
|
374
|
-
* @param msg - The error message to log
|
|
375
|
-
* @param args - Additional data to include in the log entry
|
|
376
|
-
*/
|
|
377
|
-
error(msg, ...args) {
|
|
378
|
-
this.logger.error(msg, ...args);
|
|
379
|
-
}
|
|
380
|
-
/**
|
|
381
|
-
* Logs a warning message with optional additional data.
|
|
382
|
-
*
|
|
383
|
-
* @param msg - The warning message to log
|
|
384
|
-
* @param args - Additional data to include in the log entry
|
|
385
|
-
*/
|
|
386
|
-
warn(msg, ...args) {
|
|
387
|
-
this.logger.warn(msg, ...args);
|
|
388
|
-
}
|
|
389
|
-
/**
|
|
390
|
-
* Logs an informational message with optional additional data.
|
|
391
|
-
*
|
|
392
|
-
* @param msg - The informational message to log
|
|
393
|
-
* @param args - Additional data to include in the log entry
|
|
394
|
-
*/
|
|
395
|
-
info(msg, ...args) {
|
|
396
|
-
this.logger.info(msg, ...args);
|
|
397
|
-
}
|
|
398
|
-
/**
|
|
399
|
-
* Logs an HTTP-related message with optional additional data.
|
|
400
|
-
*
|
|
401
|
-
* @param msg - The HTTP message to log
|
|
402
|
-
* @param args - Additional data to include in the log entry
|
|
403
|
-
*/
|
|
404
|
-
http(msg, ...args) {
|
|
405
|
-
this.logger.http(msg, ...args);
|
|
406
|
-
}
|
|
407
|
-
/**
|
|
408
|
-
* Logs a verbose message with optional additional data.
|
|
409
|
-
*
|
|
410
|
-
* @param msg - The verbose message to log
|
|
411
|
-
* @param args - Additional data to include in the log entry
|
|
412
|
-
*/
|
|
413
|
-
verbose(msg, ...args) {
|
|
414
|
-
this.logger.verbose(msg, ...args);
|
|
415
|
-
}
|
|
416
|
-
/**
|
|
417
|
-
* Logs a debug message with optional additional data.
|
|
418
|
-
*
|
|
419
|
-
* @param msg - The debug message to log
|
|
420
|
-
* @param args - Additional data to include in the log entry
|
|
421
|
-
*/
|
|
422
|
-
debug(msg, ...args) {
|
|
423
|
-
this.logger.debug(msg, ...args);
|
|
424
|
-
}
|
|
425
|
-
/**
|
|
426
|
-
* Logs a silly/trace level message with optional additional data.
|
|
427
|
-
*
|
|
428
|
-
* @param msg - The silly message to log
|
|
429
|
-
* @param args - Additional data to include in the log entry
|
|
430
|
-
*/
|
|
431
|
-
silly(msg, ...args) {
|
|
432
|
-
this.logger.silly(msg, ...args);
|
|
433
|
-
}
|
|
434
|
-
/**
|
|
435
|
-
* Static method to log an error message with a specific prefix.
|
|
436
|
-
* Creates or retrieves a logger instance for the given prefix.
|
|
437
|
-
*
|
|
438
|
-
* @param prefix - The logger prefix/label to use
|
|
439
|
-
* @param msg - The error message to log
|
|
440
|
-
* @param args - Additional data to include in the log entry
|
|
441
|
-
*/
|
|
442
|
-
static Error(prefix, msg, ...args) {
|
|
443
|
-
const logger = this.instance(prefix);
|
|
444
|
-
logger.error(msg, ...args);
|
|
445
|
-
}
|
|
446
|
-
/**
|
|
447
|
-
* Static method to log an informational message with a specific prefix.
|
|
448
|
-
* Creates or retrieves a logger instance for the given prefix.
|
|
449
|
-
*
|
|
450
|
-
* @param prefix - The logger prefix/label to use
|
|
451
|
-
* @param msg - The informational message to log
|
|
452
|
-
* @param args - Additional data to include in the log entry
|
|
453
|
-
*/
|
|
454
|
-
static Info(prefix, msg, ...args) {
|
|
455
|
-
const logger = this.instance(prefix);
|
|
456
|
-
logger.info(msg, ...args);
|
|
457
|
-
}
|
|
458
|
-
/**
|
|
459
|
-
* Static method to log a warning message with a specific prefix.
|
|
460
|
-
* Creates or retrieves a logger instance for the given prefix.
|
|
461
|
-
*
|
|
462
|
-
* @param prefix - The logger prefix/label to use
|
|
463
|
-
* @param msg - The warning message to log
|
|
464
|
-
* @param args - Additional data to include in the log entry
|
|
465
|
-
*/
|
|
466
|
-
static Warn(prefix, msg, ...args) {
|
|
467
|
-
const logger = this.instance(prefix);
|
|
468
|
-
logger.warn(msg, ...args);
|
|
469
|
-
}
|
|
470
|
-
/**
|
|
471
|
-
* Static method to log a debug message with a specific prefix.
|
|
472
|
-
* Creates or retrieves a logger instance for the given prefix.
|
|
473
|
-
*
|
|
474
|
-
* @param prefix - The logger prefix/label to use
|
|
475
|
-
* @param msg - The debug message to log
|
|
476
|
-
* @param args - Additional data to include in the log entry
|
|
477
|
-
*/
|
|
478
|
-
static Debug(prefix, msg, ...args) {
|
|
479
|
-
const logger = this.instance(prefix);
|
|
480
|
-
logger.debug(msg, ...args);
|
|
481
|
-
}
|
|
482
|
-
/**
|
|
483
|
-
* Static method to log a silly/trace level message with a specific prefix.
|
|
484
|
-
* Creates or retrieves a logger instance for the given prefix.
|
|
485
|
-
*
|
|
486
|
-
* @param prefix - The logger prefix/label to use
|
|
487
|
-
* @param msg - The silly message to log
|
|
488
|
-
* @param args - Additional data to include in the log entry
|
|
489
|
-
*/
|
|
490
|
-
static Silly(prefix, msg, ...args) {
|
|
491
|
-
const logger = this.instance(prefix);
|
|
492
|
-
logger.silly(msg, ...args);
|
|
493
|
-
}
|
|
494
|
-
};
|
|
495
|
-
|
|
496
|
-
// src/library/Helpers.ts
|
|
497
|
-
function numberFixer(num, decimalPlaces) {
|
|
498
|
-
const factor = Math.pow(10, decimalPlaces);
|
|
499
|
-
return Math.round((num + Number.EPSILON) * factor) / factor;
|
|
500
|
-
}
|
|
501
|
-
__name(numberFixer, "numberFixer");
|
|
502
|
-
function percentage(num1, num2) {
|
|
503
|
-
return Number((num1 / num2 * 100).toFixed(2));
|
|
504
|
-
}
|
|
505
|
-
__name(percentage, "percentage");
|
|
506
|
-
function generateAsciiTable(data) {
|
|
507
|
-
if (data.length === 0) return "";
|
|
508
|
-
const firstRow = data[0];
|
|
509
|
-
if (!firstRow || firstRow.length === 0) return "";
|
|
510
|
-
let table = "";
|
|
511
|
-
const columnWidths = [];
|
|
512
|
-
for (let i = 0; i < firstRow.length; i++) {
|
|
513
|
-
let maxWidth = 0;
|
|
514
|
-
for (const row of data) {
|
|
515
|
-
const cell = row[i];
|
|
516
|
-
if (cell !== void 0) maxWidth = Math.max(maxWidth, cell.length);
|
|
517
|
-
}
|
|
518
|
-
columnWidths.push(maxWidth);
|
|
519
|
-
}
|
|
520
|
-
const createLine = /* @__PURE__ */ __name((char, left, intersect, right) => {
|
|
521
|
-
let line = left;
|
|
522
|
-
columnWidths.forEach((width, index) => {
|
|
523
|
-
line += char.repeat(width + 2);
|
|
524
|
-
if (index < columnWidths.length - 1) line += intersect;
|
|
525
|
-
else line += right;
|
|
526
|
-
});
|
|
527
|
-
line += "\n";
|
|
528
|
-
return line;
|
|
529
|
-
}, "createLine");
|
|
530
|
-
table += createLine("\u2550", "\u2554", "\u2566", "\u2557");
|
|
531
|
-
data.forEach((row, rowIndex) => {
|
|
532
|
-
table += "\u2551";
|
|
533
|
-
row.forEach((cell, columnIndex) => {
|
|
534
|
-
const columnWidth = columnWidths[columnIndex];
|
|
535
|
-
if (columnWidth !== void 0) table += ` ${cell.padEnd(columnWidth)} \u2551`;
|
|
536
|
-
});
|
|
537
|
-
table += "\n";
|
|
538
|
-
if (rowIndex < data.length - 1) table += createLine("\u2500", "\u2560", "\u256C", "\u2563");
|
|
539
|
-
else table += createLine("\u2550", "\u255A", "\u2569", "\u255D");
|
|
540
|
-
});
|
|
541
|
-
return table;
|
|
542
|
-
}
|
|
543
|
-
__name(generateAsciiTable, "generateAsciiTable");
|
|
544
|
-
function formatWord(word) {
|
|
545
|
-
return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
|
|
546
|
-
}
|
|
547
|
-
__name(formatWord, "formatWord");
|
|
548
|
-
function longestStringLength(arr) {
|
|
549
|
-
return Math.max(...arr.map((el) => el.toString().length));
|
|
550
|
-
}
|
|
551
|
-
__name(longestStringLength, "longestStringLength");
|
|
552
|
-
function currentTime() {
|
|
553
|
-
return Math.floor(Date.now() / 1e3);
|
|
554
|
-
}
|
|
555
|
-
__name(currentTime, "currentTime");
|
|
556
|
-
function ordinal(n) {
|
|
557
|
-
const s = [
|
|
558
|
-
"th",
|
|
559
|
-
"st",
|
|
560
|
-
"nd",
|
|
561
|
-
"rd"
|
|
562
|
-
];
|
|
563
|
-
const v = n % 100;
|
|
564
|
-
const index = (v - 20) % 10;
|
|
565
|
-
const suffix = s[index] ?? s[v] ?? s[0];
|
|
566
|
-
if (!suffix) return `${n}th`;
|
|
567
|
-
return `${n}${suffix}`;
|
|
568
|
-
}
|
|
569
|
-
__name(ordinal, "ordinal");
|
|
570
|
-
function prettyDifference(numBefore, numAfter) {
|
|
571
|
-
return (numAfter - numBefore > 0 ? `+${numAfter - numBefore}` : numAfter - numBefore).toString();
|
|
572
|
-
}
|
|
573
|
-
__name(prettyDifference, "prettyDifference");
|
|
574
|
-
function isTsOrJsFile(entry) {
|
|
575
|
-
return entry.isFile() && (entry.name.endsWith(".ts") || entry.name.endsWith(".js")) && !entry.name.endsWith(".d.ts") && !entry.name.endsWith(".map");
|
|
576
|
-
}
|
|
577
|
-
__name(isTsOrJsFile, "isTsOrJsFile");
|
|
578
|
-
async function traverseDirectory(dir, callback) {
|
|
579
|
-
let entries;
|
|
580
|
-
try {
|
|
581
|
-
entries = await promises.readdir(dir, {
|
|
582
|
-
withFileTypes: true
|
|
583
|
-
});
|
|
584
|
-
} catch {
|
|
585
|
-
Logger.Error("Failed to read directory", dir);
|
|
586
|
-
entries = [];
|
|
587
|
-
}
|
|
588
|
-
for (const entry of entries) {
|
|
589
|
-
const fullPath = path__namespace.join(dir, entry.name);
|
|
590
|
-
const relativePath = path__namespace.relative(process.cwd(), fullPath);
|
|
591
|
-
if (entry.isDirectory()) {
|
|
592
|
-
await traverseDirectory(fullPath, callback);
|
|
593
|
-
} else if (isTsOrJsFile(entry)) {
|
|
594
|
-
const imported = await import(fullPath);
|
|
595
|
-
await callback(fullPath, relativePath, imported);
|
|
596
|
-
}
|
|
597
|
-
}
|
|
598
|
-
}
|
|
599
|
-
__name(traverseDirectory, "traverseDirectory");
|
|
600
|
-
function throwCustomError(error, message, CustomError2) {
|
|
601
|
-
const uuid = crypto.randomUUID();
|
|
602
|
-
Logger.Error("Throwing Custom Error", error.name);
|
|
603
|
-
if (typeof CustomError2 === typeof DatabaseError) {
|
|
604
|
-
const errorMessage = error instanceof Error ? error.message : message;
|
|
605
|
-
throw new CustomError2(errorMessage, uuid);
|
|
606
|
-
} else {
|
|
607
|
-
if (error instanceof Error) {
|
|
608
|
-
throw new CustomError2(`${message}: ${error.message ? error.message : error.toString()}`);
|
|
609
|
-
} else {
|
|
610
|
-
throw new CustomError2(message);
|
|
611
|
-
}
|
|
612
|
-
}
|
|
613
|
-
}
|
|
614
|
-
__name(throwCustomError, "throwCustomError");
|
|
615
|
-
function prettify(key) {
|
|
616
|
-
return key.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/_/g, " ").trim();
|
|
617
|
-
}
|
|
618
|
-
__name(prettify, "prettify");
|
|
619
|
-
function fyShuffle(items) {
|
|
620
|
-
const array = items.slice();
|
|
621
|
-
for (let i = array.length - 1; i > 0; i--) {
|
|
622
|
-
const j = Math.floor(Math.random() * (i + 1));
|
|
623
|
-
[array[i], array[j]] = [
|
|
624
|
-
array[j],
|
|
625
|
-
array[i]
|
|
626
|
-
];
|
|
627
|
-
}
|
|
628
|
-
return array;
|
|
629
|
-
}
|
|
630
|
-
__name(fyShuffle, "fyShuffle");
|
|
631
|
-
|
|
632
275
|
// src/bot/decorators/CommandRegisterable.ts
|
|
633
276
|
var CommandMetadataKey = Symbol("command:metadata");
|
|
634
277
|
function RegisterCommand(scope, guilds = []) {
|
|
@@ -650,7 +293,7 @@ var CommandRegistry = class {
|
|
|
650
293
|
__name(this, "CommandRegistry");
|
|
651
294
|
}
|
|
652
295
|
core;
|
|
653
|
-
logger = new Logger("Commands");
|
|
296
|
+
logger = new services.Logger("Commands");
|
|
654
297
|
isInitialised = false;
|
|
655
298
|
globalCommands = [];
|
|
656
299
|
guildCommands = /* @__PURE__ */ new Map();
|
|
@@ -660,14 +303,14 @@ var CommandRegistry = class {
|
|
|
660
303
|
async init() {
|
|
661
304
|
if (this.isInitialised) return;
|
|
662
305
|
this.isInitialised = true;
|
|
663
|
-
this.logger.info(
|
|
306
|
+
this.logger.info(chalk2__default.default.bold(this.core.config.bot.commands.path));
|
|
664
307
|
await this.loadCommands(this.core.config.bot.commands.path);
|
|
665
|
-
this.logger.info(`${
|
|
308
|
+
this.logger.info(`${chalk2__default.default.bold.green("Loaded")}: ${chalk2__default.default.magenta.bold(this.globalCommands.length)} global, ${chalk2__default.default.magenta.bold(this.guildCommands.size)} guild groups`);
|
|
666
309
|
}
|
|
667
310
|
async loadCommands(dir) {
|
|
668
|
-
await traverseDirectory(dir, (_full, rel, mod) => {
|
|
311
|
+
await utils.traverseDirectory(dir, (_full, rel, mod) => {
|
|
669
312
|
for (const exported of Object.values(mod)) if (this.isCommandClass(exported)) this.registerCommand(exported, rel);
|
|
670
|
-
});
|
|
313
|
+
}, this.logger);
|
|
671
314
|
}
|
|
672
315
|
isCommandClass(obj) {
|
|
673
316
|
if (typeof obj !== "function") return false;
|
|
@@ -681,24 +324,24 @@ var CommandRegistry = class {
|
|
|
681
324
|
const commandType = comp instanceof discord_js.SlashCommandBuilder ? "slash command" : "context menu command";
|
|
682
325
|
if (meta.scope === "global") {
|
|
683
326
|
this.globalCommands.push(comp);
|
|
684
|
-
this.logger.info(`${
|
|
685
|
-
this.logger.info(` \u2192 Global ${commandType}: ${
|
|
327
|
+
this.logger.info(`${chalk2__default.default.italic("Registered")} ${chalk2__default.default.bold.yellow(ctor.name)} from ${chalk2__default.default.gray(rel)}`);
|
|
328
|
+
this.logger.info(` \u2192 Global ${commandType}: ${chalk2__default.default.bold.cyan(comp.name)}`);
|
|
686
329
|
} else {
|
|
687
330
|
for (const g of meta.guilds) {
|
|
688
331
|
const arr = this.guildCommands.get(g) ?? [];
|
|
689
332
|
arr.push(comp);
|
|
690
333
|
this.guildCommands.set(g, arr);
|
|
691
334
|
}
|
|
692
|
-
this.logger.info(`${
|
|
693
|
-
this.logger.info(` \u2192 Guild ${commandType}: ${
|
|
335
|
+
this.logger.info(`${chalk2__default.default.italic("Registered")} ${chalk2__default.default.bold.yellow(ctor.name)} from ${chalk2__default.default.gray(rel)}`);
|
|
336
|
+
this.logger.info(` \u2192 Guild ${commandType}: ${chalk2__default.default.bold.cyan(comp.name)} for ${chalk2__default.default.magenta.bold(meta.guilds.length)} guild(s)`);
|
|
694
337
|
}
|
|
695
338
|
}
|
|
696
339
|
async setCommands() {
|
|
697
340
|
if (this.globalCommands.length > 0) {
|
|
698
341
|
await this.core.bot.client.application?.commands.set(this.globalCommands);
|
|
699
342
|
const tag = this.globalCommands.length === 1 ? "command" : "commands";
|
|
700
|
-
this.logger.info(`${
|
|
701
|
-
this.logger.info(` \u2192 ${this.globalCommands.map((command) =>
|
|
343
|
+
this.logger.info(`${chalk2__default.default.bold.green("Configured")} ${chalk2__default.default.magenta.bold(this.globalCommands.length)} global ${tag}`);
|
|
344
|
+
this.logger.info(` \u2192 ${this.globalCommands.map((command) => chalk2__default.default.bold.cyan(command.name)).join(", ")}`);
|
|
702
345
|
}
|
|
703
346
|
for (const [guildId, commands] of this.guildCommands.entries()) {
|
|
704
347
|
const guild = this.core.bot.client.guilds.cache.get(guildId);
|
|
@@ -708,8 +351,8 @@ var CommandRegistry = class {
|
|
|
708
351
|
}
|
|
709
352
|
await guild.commands.set(commands);
|
|
710
353
|
const tag = commands.length === 1 ? "command" : "commands";
|
|
711
|
-
this.logger.info(`${
|
|
712
|
-
this.logger.info(` \u2192 ${commands.map((command) =>
|
|
354
|
+
this.logger.info(`${chalk2__default.default.bold.green("Configured")} ${chalk2__default.default.magenta.bold(commands.length)} ${tag} for guild ${chalk2__default.default.bold.yellow(guild.name)}`);
|
|
355
|
+
this.logger.info(` \u2192 ${commands.map((command) => chalk2__default.default.bold.cyan(command.name)).join(", ")}`);
|
|
713
356
|
}
|
|
714
357
|
}
|
|
715
358
|
};
|
|
@@ -814,7 +457,7 @@ var EventController = class {
|
|
|
814
457
|
__name(this, "EventController");
|
|
815
458
|
}
|
|
816
459
|
core;
|
|
817
|
-
logger = new Logger("Events");
|
|
460
|
+
logger = new services.Logger("Events");
|
|
818
461
|
isInitialized = false;
|
|
819
462
|
eventMap = /* @__PURE__ */ new Map();
|
|
820
463
|
constructor(core) {
|
|
@@ -826,24 +469,24 @@ var EventController = class {
|
|
|
826
469
|
}
|
|
827
470
|
this.isInitialized = true;
|
|
828
471
|
const handlersDir = this.core.config.bot.events.path;
|
|
829
|
-
this.logger.info(
|
|
472
|
+
this.logger.info(chalk2__default.default.bold(handlersDir));
|
|
830
473
|
await this.loadHandlers(handlersDir);
|
|
831
474
|
this.attachToClient();
|
|
832
475
|
const loadedEventsArray = [];
|
|
833
476
|
this.eventMap.forEach((handlers, eventName) => {
|
|
834
|
-
loadedEventsArray.push(`${
|
|
477
|
+
loadedEventsArray.push(`${chalk2__default.default.magenta.bold(handlers.length)} ${eventName}`);
|
|
835
478
|
});
|
|
836
|
-
this.logger.info(`${
|
|
479
|
+
this.logger.info(`${chalk2__default.default.bold.green("Loaded")}: ${this.eventMap.size > 0 ? loadedEventsArray.join(", ") : "none"}`);
|
|
837
480
|
}
|
|
838
481
|
async loadHandlers(dir) {
|
|
839
|
-
await traverseDirectory(dir, (_fullPath, relativePath, imported) => {
|
|
482
|
+
await utils.traverseDirectory(dir, (_fullPath, relativePath, imported) => {
|
|
840
483
|
for (const val of Object.values(imported)) {
|
|
841
484
|
if (this.isEventHandlerClass(val)) {
|
|
842
485
|
this.registerHandler(val);
|
|
843
|
-
this.logger.info(`${
|
|
486
|
+
this.logger.info(`${chalk2__default.default.italic("Registered")} ${chalk2__default.default.bold.yellow(val.name)} from ${chalk2__default.default.gray(relativePath)}`);
|
|
844
487
|
}
|
|
845
488
|
}
|
|
846
|
-
});
|
|
489
|
+
}, this.logger);
|
|
847
490
|
}
|
|
848
491
|
isEventHandlerClass(obj) {
|
|
849
492
|
if (typeof obj !== "function") return false;
|
|
@@ -861,7 +504,7 @@ var EventController = class {
|
|
|
861
504
|
}
|
|
862
505
|
attachToClient() {
|
|
863
506
|
for (const [eventName] of this.eventMap) {
|
|
864
|
-
this.logger.debug(`Attaching ${
|
|
507
|
+
this.logger.debug(`Attaching ${chalk2__default.default.bold.green(eventName)} to ${chalk2__default.default.bold.yellow(this.core.bot.client.user?.username)}`);
|
|
865
508
|
this.core.bot.client.on(eventName, (...args) => {
|
|
866
509
|
void (async () => {
|
|
867
510
|
await this.processEvent(eventName, args);
|
|
@@ -874,7 +517,7 @@ var EventController = class {
|
|
|
874
517
|
if (!handlerCtors || handlerCtors.length === 0) return;
|
|
875
518
|
for (const HandlerCtor of handlerCtors) {
|
|
876
519
|
try {
|
|
877
|
-
this.logger.debug(`Processing ${
|
|
520
|
+
this.logger.debug(`Processing ${chalk2__default.default.bold.green(eventName)} with ${chalk2__default.default.gray(HandlerCtor.name)}`);
|
|
878
521
|
const handler = new HandlerCtor(args, this.core);
|
|
879
522
|
if (handler.hasChecks()) {
|
|
880
523
|
await handler.runChecks();
|
|
@@ -985,11 +628,34 @@ function storeMetadata(symbol, routes, constructor) {
|
|
|
985
628
|
Reflect.defineMetadata(InteractionMetadataKey, true, constructor);
|
|
986
629
|
}
|
|
987
630
|
__name(storeMetadata, "storeMetadata");
|
|
631
|
+
|
|
632
|
+
// src/bot/errors/Database.ts
|
|
633
|
+
var DatabaseError = class extends CustomError {
|
|
634
|
+
static {
|
|
635
|
+
__name(this, "DatabaseError");
|
|
636
|
+
}
|
|
637
|
+
uuid;
|
|
638
|
+
_emit = true;
|
|
639
|
+
/**
|
|
640
|
+
* Creates a new DatabaseError.
|
|
641
|
+
*
|
|
642
|
+
* @param message - The error message describing what went wrong
|
|
643
|
+
* @param uuid - A unique identifier for this specific error instance
|
|
644
|
+
*/
|
|
645
|
+
constructor(message, uuid) {
|
|
646
|
+
super(message), this.uuid = uuid;
|
|
647
|
+
this.name = "DatabaseError";
|
|
648
|
+
this.response.setTitle("Database Error").setDescription(`An error occurred while interacting with the database.
|
|
649
|
+
### UUID: \`${this.uuid}\``);
|
|
650
|
+
}
|
|
651
|
+
};
|
|
652
|
+
|
|
653
|
+
// src/bot/utilities/ErrorHandlingUtils.ts
|
|
988
654
|
var ErrorHandlingUtils = class {
|
|
989
655
|
static {
|
|
990
656
|
__name(this, "ErrorHandlingUtils");
|
|
991
657
|
}
|
|
992
|
-
static logger = new Logger("Errors");
|
|
658
|
+
static logger = new services.Logger("Errors");
|
|
993
659
|
/**
|
|
994
660
|
* Processes an error and extracts the standardized response, if available.
|
|
995
661
|
*
|
|
@@ -1130,7 +796,7 @@ var InteractionController = class {
|
|
|
1130
796
|
__name(this, "InteractionController");
|
|
1131
797
|
}
|
|
1132
798
|
core;
|
|
1133
|
-
logger = new Logger("Interactions");
|
|
799
|
+
logger = new services.Logger("Interactions");
|
|
1134
800
|
isInitialized = false;
|
|
1135
801
|
slashMap = /* @__PURE__ */ new Map();
|
|
1136
802
|
buttonMap = /* @__PURE__ */ new Map();
|
|
@@ -1155,31 +821,31 @@ var InteractionController = class {
|
|
|
1155
821
|
if (this.isInitialized) return;
|
|
1156
822
|
this.isInitialized = true;
|
|
1157
823
|
const handlersDir = this.core.config.bot.interactions.path;
|
|
1158
|
-
this.logger.info(
|
|
824
|
+
this.logger.info(chalk2__default.default.bold(handlersDir));
|
|
1159
825
|
await this.loadHandlers(handlersDir);
|
|
1160
826
|
this.attachToClient();
|
|
1161
|
-
this.logger.info(`${
|
|
1162
|
-
this.logger.info(`\u2192 ${
|
|
1163
|
-
this.logger.info(`\u2192 ${
|
|
1164
|
-
this.logger.info(`\u2192 ${
|
|
1165
|
-
this.logger.info(`\u2192 ${
|
|
1166
|
-
this.logger.info(`\u2192 ${
|
|
1167
|
-
this.logger.info(`\u2192 ${
|
|
1168
|
-
this.logger.info(`\u2192 ${
|
|
1169
|
-
this.logger.info(`\u2192 ${
|
|
1170
|
-
this.logger.info(`\u2192 ${
|
|
1171
|
-
this.logger.info(`\u2192 ${
|
|
1172
|
-
this.logger.info(`\u2192 ${
|
|
827
|
+
this.logger.info(`${chalk2__default.default.bold.green("Loaded interaction handlers:")}`);
|
|
828
|
+
this.logger.info(`\u2192 ${chalk2__default.default.magenta.bold(this.slashMap.size)} slash commands`);
|
|
829
|
+
this.logger.info(`\u2192 ${chalk2__default.default.magenta.bold(this.buttonMap.size)} buttons`);
|
|
830
|
+
this.logger.info(`\u2192 ${chalk2__default.default.magenta.bold(this.modalMap.size)} modals`);
|
|
831
|
+
this.logger.info(`\u2192 ${chalk2__default.default.magenta.bold(this.stringSelectMap.size)} string selects`);
|
|
832
|
+
this.logger.info(`\u2192 ${chalk2__default.default.magenta.bold(this.userSelectMap.size)} user selects`);
|
|
833
|
+
this.logger.info(`\u2192 ${chalk2__default.default.magenta.bold(this.roleSelectMap.size)} role selects`);
|
|
834
|
+
this.logger.info(`\u2192 ${chalk2__default.default.magenta.bold(this.channelSelectMap.size)} channel selects`);
|
|
835
|
+
this.logger.info(`\u2192 ${chalk2__default.default.magenta.bold(this.mentionableSelectMap.size)} mentionable selects`);
|
|
836
|
+
this.logger.info(`\u2192 ${chalk2__default.default.magenta.bold(this.messageContextMenuMap.size)} message context menus`);
|
|
837
|
+
this.logger.info(`\u2192 ${chalk2__default.default.magenta.bold(this.userContextMenuMap.size)} user context menus`);
|
|
838
|
+
this.logger.info(`\u2192 ${chalk2__default.default.magenta.bold(this.autocompleteMap.size)} autocomplete`);
|
|
1173
839
|
}
|
|
1174
840
|
async loadHandlers(dir) {
|
|
1175
|
-
await traverseDirectory(dir, (_fullPath, relativePath, imported) => {
|
|
841
|
+
await utils.traverseDirectory(dir, (_fullPath, relativePath, imported) => {
|
|
1176
842
|
for (const val of Object.values(imported)) {
|
|
1177
843
|
if (this.isHandlerClass(val)) {
|
|
1178
844
|
this.registerHandler(val);
|
|
1179
|
-
this.logger.info(`${
|
|
845
|
+
this.logger.info(`${chalk2__default.default.italic("Registered")} ${chalk2__default.default.bold.yellow(val.name)} from ${chalk2__default.default.gray(relativePath)}`);
|
|
1180
846
|
}
|
|
1181
847
|
}
|
|
1182
|
-
});
|
|
848
|
+
}, this.logger);
|
|
1183
849
|
}
|
|
1184
850
|
isHandlerClass(obj) {
|
|
1185
851
|
if (typeof obj !== "function") return false;
|
|
@@ -1245,7 +911,7 @@ var InteractionController = class {
|
|
|
1245
911
|
attachToClient() {
|
|
1246
912
|
this.core.bot.client.on(discord_js.Events.InteractionCreate, (interaction) => {
|
|
1247
913
|
this.handleInteraction(interaction).catch((err) => {
|
|
1248
|
-
this.logger.error(`[${
|
|
914
|
+
this.logger.error(`[${chalk2__default.default.bold.red("UNHANDLED ERROR AT ROOT")}] ${err.name}`, err.stack);
|
|
1249
915
|
});
|
|
1250
916
|
});
|
|
1251
917
|
}
|
|
@@ -1274,10 +940,10 @@ var InteractionController = class {
|
|
|
1274
940
|
}
|
|
1275
941
|
let HandlerCtor = getHandler(key);
|
|
1276
942
|
if (!HandlerCtor) {
|
|
1277
|
-
this.logger.warn(`No handler found for key ${
|
|
943
|
+
this.logger.warn(`No handler found for key ${chalk2__default.default.bold.cyan(key)}. Falling back to UnhandledEvent.`);
|
|
1278
944
|
HandlerCtor = UnhandledEvent;
|
|
1279
945
|
}
|
|
1280
|
-
this.logger.debug(`Processing ${
|
|
946
|
+
this.logger.debug(`Processing ${chalk2__default.default.bold.green(key)} with ${chalk2__default.default.gray(HandlerCtor.name)}`);
|
|
1281
947
|
const handler = new HandlerCtor(interaction, this.core, args);
|
|
1282
948
|
if (handler.hasChecks()) await handler.runChecks();
|
|
1283
949
|
if (handler.shouldBreak()) return;
|
|
@@ -1381,13 +1047,13 @@ var EmojiInjector = class {
|
|
|
1381
1047
|
__name(this, "EmojiInjector");
|
|
1382
1048
|
}
|
|
1383
1049
|
core;
|
|
1384
|
-
logger = new Logger("Emojis");
|
|
1050
|
+
logger = new services.Logger("Emojis");
|
|
1385
1051
|
constructor(core) {
|
|
1386
1052
|
this.core = core;
|
|
1387
1053
|
}
|
|
1388
1054
|
async init() {
|
|
1389
1055
|
if (!this.core.config.bot.emojis || Object.keys(this.core.config.bot.emojis).length === 0) {
|
|
1390
|
-
this.logger.info(`${
|
|
1056
|
+
this.logger.info(`${chalk2__default.default.bold.green("Loaded")}: ${chalk2__default.default.magenta.bold("0")} emojis`);
|
|
1391
1057
|
return;
|
|
1392
1058
|
}
|
|
1393
1059
|
const configEmojis = this.core.config.bot.emojis;
|
|
@@ -1398,341 +1064,31 @@ var EmojiInjector = class {
|
|
|
1398
1064
|
if (emoji) {
|
|
1399
1065
|
configEmojis[key] = `<${emoji.identifier}>`;
|
|
1400
1066
|
foundCount++;
|
|
1067
|
+
this.logger.debug(`${chalk2__default.default.bold.green("Found")}: ${chalk2__default.default.magenta.bold(emojiName)} (${emoji.id})`);
|
|
1401
1068
|
}
|
|
1402
1069
|
});
|
|
1403
|
-
this.logger.info(`${
|
|
1404
|
-
}
|
|
1405
|
-
};
|
|
1406
|
-
var Plugin = class {
|
|
1407
|
-
static {
|
|
1408
|
-
__name(this, "Plugin");
|
|
1409
|
-
}
|
|
1410
|
-
pluggable;
|
|
1411
|
-
constructor(pluggable) {
|
|
1412
|
-
this.pluggable = pluggable;
|
|
1413
|
-
}
|
|
1414
|
-
};
|
|
1415
|
-
var Pluggable = class _Pluggable {
|
|
1416
|
-
static {
|
|
1417
|
-
__name(this, "Pluggable");
|
|
1418
|
-
}
|
|
1419
|
-
isInitialized = false;
|
|
1420
|
-
shutdown;
|
|
1421
|
-
startup;
|
|
1422
|
-
static PLUGIN_INIT_TIMEOUT_MS = 15e3;
|
|
1423
|
-
constructor(shutdown, startup) {
|
|
1424
|
-
this.shutdown = shutdown;
|
|
1425
|
-
this.startup = startup;
|
|
1426
|
-
}
|
|
1427
|
-
async init() {
|
|
1428
|
-
if (this.isInitialized) return this;
|
|
1429
|
-
await this.startup.run();
|
|
1430
|
-
this.isInitialized = true;
|
|
1431
|
-
return this;
|
|
1432
|
-
}
|
|
1433
|
-
/**
|
|
1434
|
-
* Attaches a plugin to this instance
|
|
1435
|
-
*
|
|
1436
|
-
* Plugins provide external functionality and are initialized during the specified startup phase.
|
|
1437
|
-
* The plugin instance becomes available as a property in `core` wherever it's available.
|
|
1438
|
-
*
|
|
1439
|
-
* Make sure to augment the {@link Core} interface with the plugin type to ensure TypeScript recognizes it and provides intellisense.
|
|
1440
|
-
*
|
|
1441
|
-
* @typeParam Key - The property name for accessing the plugin
|
|
1442
|
-
* @typeParam Ctor - The plugin constructor type
|
|
1443
|
-
* @param key - Property name to access the plugin instance
|
|
1444
|
-
* @param Plugin - Plugin constructor class
|
|
1445
|
-
* @param startupPhase - When during startup to initialize this plugin ({@link StartupPhase})
|
|
1446
|
-
* @param args - Additional arguments to pass to the plugin constructor
|
|
1447
|
-
* @returns This instance with the plugin attached as a typed property
|
|
1448
|
-
* @throws An {@link Error} When called after initialization or if key already exists
|
|
1449
|
-
* @example
|
|
1450
|
-
* ```typescript
|
|
1451
|
-
* seedcord.attach('db', Mongo, StartupPhase.Configuration, { uri: 'mongodb://...', dbName: 'seedcord' })
|
|
1452
|
-
* ```
|
|
1453
|
-
*/
|
|
1454
|
-
attach(key, Plugin2, startupPhase, ...args) {
|
|
1455
|
-
if (this.isInitialized) throw new Error("Cannot attach a plugin after initialization.");
|
|
1456
|
-
if (this[key]) throw new Error(`Plugin with key "${key}" already exists.`);
|
|
1457
|
-
const instance = new Plugin2(this, ...args);
|
|
1458
|
-
const entry = {
|
|
1459
|
-
[key]: instance
|
|
1460
|
-
};
|
|
1461
|
-
this.startup.addTask(startupPhase, `Plugin:${key}`, async () => {
|
|
1462
|
-
instance.logger.info(chalk6__default.default.bold("Initializing"));
|
|
1463
|
-
await instance.init();
|
|
1464
|
-
instance.logger.info(chalk6__default.default.bold("Initialized"));
|
|
1465
|
-
}, _Pluggable.PLUGIN_INIT_TIMEOUT_MS);
|
|
1466
|
-
return Object.assign(this, entry);
|
|
1467
|
-
}
|
|
1468
|
-
};
|
|
1469
|
-
var CoordinatedLifecycle = class {
|
|
1470
|
-
static {
|
|
1471
|
-
__name(this, "CoordinatedLifecycle");
|
|
1472
|
-
}
|
|
1473
|
-
phaseOrder;
|
|
1474
|
-
phaseEnum;
|
|
1475
|
-
logger;
|
|
1476
|
-
events = new events.EventEmitter();
|
|
1477
|
-
tasksMap = /* @__PURE__ */ new Map();
|
|
1478
|
-
constructor(loggerName, phaseOrder, phaseEnum) {
|
|
1479
|
-
this.phaseOrder = phaseOrder;
|
|
1480
|
-
this.phaseEnum = phaseEnum;
|
|
1481
|
-
this.logger = new Logger(loggerName);
|
|
1482
|
-
this.phaseOrder.forEach((phase) => this.tasksMap.set(phase, []));
|
|
1483
|
-
}
|
|
1484
|
-
/**
|
|
1485
|
-
* Adds a lifecycle task to a specific phase.
|
|
1486
|
-
*
|
|
1487
|
-
* Tasks are executed in phase order during lifecycle operations.
|
|
1488
|
-
* Each task has a timeout to prevent hanging operations.
|
|
1489
|
-
*
|
|
1490
|
-
* @param phase - The lifecycle phase to add the task to
|
|
1491
|
-
* @param taskName - Unique name for the task (used for logging and removal)
|
|
1492
|
-
* @param task - Async function to execute during the phase
|
|
1493
|
-
* @param timeoutMs - Maximum time allowed for task execution in milliseconds
|
|
1494
|
-
* @example
|
|
1495
|
-
* ```typescript
|
|
1496
|
-
* lifecycle.addTask(StartupPhase.Services, 'start-database', async () => {
|
|
1497
|
-
* await database.connect();
|
|
1498
|
-
* }, 10000);
|
|
1499
|
-
* ```
|
|
1500
|
-
*/
|
|
1501
|
-
addTask(phase, taskName, task, timeoutMs) {
|
|
1502
|
-
if (!this.canAddTask()) return;
|
|
1503
|
-
const tasks = this.tasksMap.get(phase);
|
|
1504
|
-
if (!tasks) throw new Error(`Unknown phase: ${phase}`);
|
|
1505
|
-
tasks.push({
|
|
1506
|
-
name: taskName,
|
|
1507
|
-
task,
|
|
1508
|
-
timeout: timeoutMs
|
|
1509
|
-
});
|
|
1510
|
-
this.logger.debug(`${chalk6__default.default.italic("Added")} ${this.getTaskType()} task ${chalk6__default.default.bold.cyan(taskName)} to phase ${chalk6__default.default.bold.magenta(this.phaseEnum[phase])}`);
|
|
1511
|
-
}
|
|
1512
|
-
/**
|
|
1513
|
-
* Removes a lifecycle task from a specific phase.
|
|
1514
|
-
*
|
|
1515
|
-
* @param phase - The lifecycle phase to remove the task from
|
|
1516
|
-
* @param taskName - Name of the task to remove
|
|
1517
|
-
* @returns True if the task was found and removed, false otherwise
|
|
1518
|
-
*/
|
|
1519
|
-
removeTask(phase, taskName) {
|
|
1520
|
-
if (!this.canRemoveTask()) return false;
|
|
1521
|
-
const tasks = this.tasksMap.get(phase);
|
|
1522
|
-
if (!tasks) return false;
|
|
1523
|
-
const initialLength = tasks.length;
|
|
1524
|
-
const filteredTasks = tasks.filter((task) => task.name !== taskName);
|
|
1525
|
-
this.tasksMap.set(phase, filteredTasks);
|
|
1526
|
-
const removed = initialLength !== filteredTasks.length;
|
|
1527
|
-
if (removed) {
|
|
1528
|
-
this.logger.debug(`${chalk6__default.default.italic("Removed")} ${this.getTaskType()} task ${chalk6__default.default.bold.cyan(taskName)} from phase ${chalk6__default.default.bold.magenta(this.phaseEnum[phase])}`);
|
|
1529
|
-
}
|
|
1530
|
-
return removed;
|
|
1531
|
-
}
|
|
1532
|
-
/**
|
|
1533
|
-
* Run all tasks in a specific phase
|
|
1534
|
-
*/
|
|
1535
|
-
async runPhase(phase) {
|
|
1536
|
-
const tasks = this.tasksMap.get(phase) ?? [];
|
|
1537
|
-
if (tasks.length === 0) {
|
|
1538
|
-
this.logger.warn(`No tasks to run in phase ${chalk6__default.default.bold.magenta(this.phaseEnum[phase])}`);
|
|
1539
|
-
return;
|
|
1540
|
-
}
|
|
1541
|
-
this.logger.info(`${chalk6__default.default.bold.yellow("Running")} ${this.getTaskType()} phase ${chalk6__default.default.bold.magenta(this.phaseEnum[phase])} with ${chalk6__default.default.bold.cyan(tasks.length)} tasks`);
|
|
1542
|
-
this.emit(`phase:${phase}:start`);
|
|
1543
|
-
const results = await this.executeTasksInPhase(phase, tasks);
|
|
1544
|
-
const failures = results.filter((r) => r.status === "rejected").length;
|
|
1545
|
-
if (failures > 0) {
|
|
1546
|
-
const errorMessage = `Phase ${chalk6__default.default.bold.magenta(this.phaseEnum[phase])} completed with ${chalk6__default.default.bold.red(failures)} failed tasks`;
|
|
1547
|
-
throw new Error(errorMessage);
|
|
1548
|
-
} else {
|
|
1549
|
-
this.logger.info(`Phase ${chalk6__default.default.bold.magenta(this.phaseEnum[phase])} ${chalk6__default.default.bold.green("completed successfully")}`);
|
|
1550
|
-
}
|
|
1551
|
-
this.emit(`phase:${phase}:complete`);
|
|
1552
|
-
}
|
|
1553
|
-
/**
|
|
1554
|
-
* Run a single task with timeout
|
|
1555
|
-
*/
|
|
1556
|
-
async runTaskWithTimeout(phase, task) {
|
|
1557
|
-
this.logger.info(`${chalk6__default.default.italic("Starting")} task ${chalk6__default.default.bold.cyan(task.name)} in phase ${chalk6__default.default.bold.magenta(this.phaseEnum[phase])}`);
|
|
1558
|
-
try {
|
|
1559
|
-
await Promise.race([
|
|
1560
|
-
task.task(),
|
|
1561
|
-
new Promise((_, reject) => {
|
|
1562
|
-
setTimeout(() => {
|
|
1563
|
-
reject(new Error(`Task '${task.name}' timed out after ${task.timeout}ms`));
|
|
1564
|
-
}, task.timeout);
|
|
1565
|
-
})
|
|
1566
|
-
]);
|
|
1567
|
-
this.logger.info(`${chalk6__default.default.italic("Completed")} task ${chalk6__default.default.bold.cyan(task.name)} in phase ${chalk6__default.default.bold.magenta(this.phaseEnum[phase])}`);
|
|
1568
|
-
} catch (error) {
|
|
1569
|
-
this.logger.error(`${chalk6__default.default.italic("Failed")} task ${chalk6__default.default.bold.cyan(task.name)} in phase ${chalk6__default.default.bold.magenta(this.phaseEnum[phase])}:`, error);
|
|
1570
|
-
throw error;
|
|
1571
|
-
}
|
|
1572
|
-
}
|
|
1573
|
-
/**
|
|
1574
|
-
* Subscribe to lifecycle events
|
|
1575
|
-
*/
|
|
1576
|
-
on(event, listener) {
|
|
1577
|
-
this.events.on(event, listener);
|
|
1578
|
-
}
|
|
1579
|
-
/**
|
|
1580
|
-
* Unsubscribe from lifecycle events
|
|
1581
|
-
*/
|
|
1582
|
-
off(event, listener) {
|
|
1583
|
-
this.events.off(event, listener);
|
|
1584
|
-
}
|
|
1585
|
-
emit(event, ...args) {
|
|
1586
|
-
return this.events.emit(event, ...args);
|
|
1587
|
-
}
|
|
1588
|
-
};
|
|
1589
|
-
|
|
1590
|
-
// src/services/Lifecycle/CoordinatedShutdown.ts
|
|
1591
|
-
var ShutdownPhase = /* @__PURE__ */ (function(ShutdownPhase2) {
|
|
1592
|
-
ShutdownPhase2[ShutdownPhase2["StopAcceptingRequests"] = 1] = "StopAcceptingRequests";
|
|
1593
|
-
ShutdownPhase2[ShutdownPhase2["StopServices"] = 2] = "StopServices";
|
|
1594
|
-
ShutdownPhase2[ShutdownPhase2["ExternalResources"] = 3] = "ExternalResources";
|
|
1595
|
-
ShutdownPhase2[ShutdownPhase2["DiscordCleanup"] = 4] = "DiscordCleanup";
|
|
1596
|
-
ShutdownPhase2[ShutdownPhase2["FinalCleanup"] = 5] = "FinalCleanup";
|
|
1597
|
-
return ShutdownPhase2;
|
|
1598
|
-
})({});
|
|
1599
|
-
var PHASE_ORDER = [
|
|
1600
|
-
1,
|
|
1601
|
-
2,
|
|
1602
|
-
3,
|
|
1603
|
-
4,
|
|
1604
|
-
5
|
|
1605
|
-
];
|
|
1606
|
-
var LOG_FLUSH_DELAY_MS = 500;
|
|
1607
|
-
var CoordinatedShutdown = class extends CoordinatedLifecycle {
|
|
1608
|
-
static {
|
|
1609
|
-
__name(this, "CoordinatedShutdown");
|
|
1610
|
-
}
|
|
1611
|
-
isShuttingDown = false;
|
|
1612
|
-
exitCode = 0;
|
|
1613
|
-
constructor() {
|
|
1614
|
-
super("CoordinatedShutdown", PHASE_ORDER, ShutdownPhase);
|
|
1615
|
-
this.registerSignalHandlers();
|
|
1616
|
-
}
|
|
1617
|
-
canAddTask() {
|
|
1618
|
-
return Globals.shutdownIsEnabled;
|
|
1619
|
-
}
|
|
1620
|
-
canRemoveTask() {
|
|
1621
|
-
return true;
|
|
1622
|
-
}
|
|
1623
|
-
getTaskType() {
|
|
1624
|
-
return "shutdown";
|
|
1625
|
-
}
|
|
1626
|
-
async executeTasksInPhase(phase, tasks) {
|
|
1627
|
-
const results = [];
|
|
1628
|
-
for (const task of tasks) {
|
|
1629
|
-
results.push(await Promise.resolve().then(() => this.runTaskWithTimeout(phase, task)).then(
|
|
1630
|
-
() => ({
|
|
1631
|
-
status: "fulfilled",
|
|
1632
|
-
value: void 0
|
|
1633
|
-
}),
|
|
1634
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
1635
|
-
(reason) => ({
|
|
1636
|
-
status: "rejected",
|
|
1637
|
-
reason
|
|
1638
|
-
})
|
|
1639
|
-
));
|
|
1640
|
-
}
|
|
1641
|
-
return results;
|
|
1642
|
-
}
|
|
1643
|
-
registerSignalHandlers() {
|
|
1644
|
-
if (!Globals.shutdownIsEnabled) return;
|
|
1645
|
-
process.on("SIGTERM", () => {
|
|
1646
|
-
this.logger.info(`Received ${chalk6__default.default.yellow.bold("SIGTERM")} signal`);
|
|
1647
|
-
void this.run(0);
|
|
1648
|
-
});
|
|
1649
|
-
process.on("SIGINT", () => {
|
|
1650
|
-
this.logger.info(`Received ${chalk6__default.default.yellow.bold("SIGINT")} signal`);
|
|
1651
|
-
void this.run(0);
|
|
1652
|
-
});
|
|
1653
|
-
}
|
|
1654
|
-
/**
|
|
1655
|
-
* Adds a task to a specific shutdown phase with timeout.
|
|
1656
|
-
*
|
|
1657
|
-
* @param phase - The shutdown phase from {@link ShutdownPhase}
|
|
1658
|
-
* @param taskName - Unique identifier for the task
|
|
1659
|
-
* @param task - Async function to execute
|
|
1660
|
-
* @param timeoutMs - Task timeout in milliseconds (default: 5000)
|
|
1661
|
-
*/
|
|
1662
|
-
addTask(phase, taskName, task, timeoutMs = 5e3) {
|
|
1663
|
-
super.addTask(phase, taskName, task, timeoutMs);
|
|
1664
|
-
}
|
|
1665
|
-
/**
|
|
1666
|
-
* Removes a task from a specific shutdown phase.
|
|
1667
|
-
*
|
|
1668
|
-
* @param phase - The shutdown phase to remove from
|
|
1669
|
-
* @param taskName - Name of the task to remove
|
|
1670
|
-
* @returns True if task was found and removed
|
|
1671
|
-
*/
|
|
1672
|
-
removeTask(phase, taskName) {
|
|
1673
|
-
return super.removeTask(phase, taskName);
|
|
1674
|
-
}
|
|
1675
|
-
/**
|
|
1676
|
-
* Executes the coordinated shutdown sequence.
|
|
1677
|
-
*
|
|
1678
|
-
* Runs all registered tasks across shutdown phases in reverse order.
|
|
1679
|
-
* Tasks within each phase are executed in parallel for faster shutdown.
|
|
1680
|
-
* Process exits with the specified code when complete.
|
|
1681
|
-
*
|
|
1682
|
-
* @param exitCode - Process exit code (default: 0)
|
|
1683
|
-
* @returns Promise that resolves when shutdown is complete
|
|
1684
|
-
* @example
|
|
1685
|
-
* ```typescript
|
|
1686
|
-
* shutdown.addTask(ShutdownPhase.Services, 'database', () => db.disconnect(), 5000);
|
|
1687
|
-
* await shutdown.run(0); // Graceful shutdown
|
|
1688
|
-
* ```
|
|
1689
|
-
*/
|
|
1690
|
-
async run(exitCode = 0) {
|
|
1691
|
-
if (this.isShuttingDown) {
|
|
1692
|
-
this.logger.warn("Shutdown sequence already in progress");
|
|
1693
|
-
return;
|
|
1694
|
-
}
|
|
1695
|
-
this.isShuttingDown = true;
|
|
1696
|
-
this.exitCode = exitCode;
|
|
1697
|
-
this.logger.info(`${chalk6__default.default.bold.yellow("Starting")} coordinated shutdown with exit code ${chalk6__default.default.bold.cyan(exitCode)}`);
|
|
1698
|
-
this.emit("shutdown:start");
|
|
1699
|
-
try {
|
|
1700
|
-
for (const phase of PHASE_ORDER) {
|
|
1701
|
-
await this.runPhase(phase);
|
|
1702
|
-
}
|
|
1703
|
-
this.logger.info(`${chalk6__default.default.bold.green("Coordinated shutdown completed")} successfully`);
|
|
1704
|
-
this.emit("shutdown:complete");
|
|
1705
|
-
} catch (error) {
|
|
1706
|
-
this.logger.error(`${chalk6__default.default.bold.red("Coordinated shutdown failed")}`);
|
|
1707
|
-
this.emit("shutdown:error", error);
|
|
1708
|
-
} finally {
|
|
1709
|
-
this.logger.info(`${chalk6__default.default.bold.red("Exiting")} process with code ${chalk6__default.default.bold.cyan(this.exitCode)}`);
|
|
1710
|
-
setTimeout(() => {
|
|
1711
|
-
process.exit(this.exitCode);
|
|
1712
|
-
}, LOG_FLUSH_DELAY_MS);
|
|
1713
|
-
}
|
|
1714
|
-
}
|
|
1715
|
-
/**
|
|
1716
|
-
* Subscribe to shutdown events
|
|
1717
|
-
*/
|
|
1718
|
-
on(event, listener) {
|
|
1719
|
-
super.on(event, listener);
|
|
1720
|
-
}
|
|
1721
|
-
/**
|
|
1722
|
-
* Unsubscribe from shutdown events
|
|
1723
|
-
*/
|
|
1724
|
-
off(event, listener) {
|
|
1725
|
-
super.off(event, listener);
|
|
1070
|
+
this.logger.info(`${chalk2__default.default.bold.green("Loaded")}: ${chalk2__default.default.magenta.bold(foundCount)} emojis`);
|
|
1726
1071
|
}
|
|
1727
1072
|
};
|
|
1728
1073
|
|
|
1729
1074
|
// src/bot/Bot.ts
|
|
1075
|
+
function _ts_decorate3(decorators, target, key, desc) {
|
|
1076
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1077
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1078
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
1079
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1080
|
+
}
|
|
1081
|
+
__name(_ts_decorate3, "_ts_decorate");
|
|
1082
|
+
function _ts_metadata3(k, v) {
|
|
1083
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
1084
|
+
}
|
|
1085
|
+
__name(_ts_metadata3, "_ts_metadata");
|
|
1730
1086
|
var Bot = class extends Plugin {
|
|
1731
1087
|
static {
|
|
1732
1088
|
__name(this, "Bot");
|
|
1733
1089
|
}
|
|
1734
1090
|
core;
|
|
1735
|
-
logger = new Logger("Bot");
|
|
1091
|
+
logger = new services.Logger("Bot");
|
|
1736
1092
|
isInitialized = false;
|
|
1737
1093
|
_client;
|
|
1738
1094
|
interactions;
|
|
@@ -1750,7 +1106,7 @@ var Bot = class extends Plugin {
|
|
|
1750
1106
|
this.events = new EventController(core);
|
|
1751
1107
|
this.commands = new CommandRegistry(this.core);
|
|
1752
1108
|
this.emojiInjector = new EmojiInjector(this.core);
|
|
1753
|
-
this.core.shutdown.addTask(ShutdownPhase.DiscordCleanup, "stop-bot", async () => await this.stop());
|
|
1109
|
+
this.core.shutdown.addTask(services.ShutdownPhase.DiscordCleanup, "stop-bot", async () => await this.stop());
|
|
1754
1110
|
}
|
|
1755
1111
|
/**
|
|
1756
1112
|
* Initializes Discord client and all controllers
|
|
@@ -1780,8 +1136,8 @@ var Bot = class extends Plugin {
|
|
|
1780
1136
|
* Logs the bot into Discord using the configured token
|
|
1781
1137
|
*/
|
|
1782
1138
|
async login() {
|
|
1783
|
-
await this._client.login(
|
|
1784
|
-
this.logger.info(`Logged in as ${
|
|
1139
|
+
await this._client.login(this.botToken);
|
|
1140
|
+
this.logger.info(`Logged in as ${chalk2__default.default.bold.magenta(this._client.user?.username)}!`);
|
|
1785
1141
|
return this;
|
|
1786
1142
|
}
|
|
1787
1143
|
/**
|
|
@@ -1789,12 +1145,21 @@ var Bot = class extends Plugin {
|
|
|
1789
1145
|
*/
|
|
1790
1146
|
async logout() {
|
|
1791
1147
|
await this._client.destroy();
|
|
1792
|
-
this.logger.info(
|
|
1148
|
+
this.logger.info(chalk2__default.default.bold.red("Logged out of Discord!"));
|
|
1793
1149
|
}
|
|
1794
1150
|
get client() {
|
|
1795
1151
|
return this._client;
|
|
1796
1152
|
}
|
|
1797
1153
|
};
|
|
1154
|
+
_ts_decorate3([
|
|
1155
|
+
envapt.Envapt("DISCORD_BOT_TOKEN", {
|
|
1156
|
+
converter(raw, _fallback) {
|
|
1157
|
+
if (typeof raw !== "string") throw new Error("Missing DISCORD_BOT_TOKEN");
|
|
1158
|
+
return raw;
|
|
1159
|
+
}
|
|
1160
|
+
}),
|
|
1161
|
+
_ts_metadata3("design:type", String)
|
|
1162
|
+
], Bot.prototype, "botToken", void 0);
|
|
1798
1163
|
|
|
1799
1164
|
// src/effects/decorators/RegisterEffect.ts
|
|
1800
1165
|
var EffectMetadataKey = Symbol("effect:metadata");
|
|
@@ -1837,19 +1202,23 @@ var WebhookLog = class extends EffectsHandler {
|
|
|
1837
1202
|
};
|
|
1838
1203
|
|
|
1839
1204
|
// src/effects/default/UnknownException.ts
|
|
1840
|
-
function
|
|
1205
|
+
function _ts_decorate4(decorators, target, key, desc) {
|
|
1841
1206
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1842
1207
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1843
1208
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
1844
1209
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1845
1210
|
}
|
|
1846
|
-
__name(
|
|
1847
|
-
|
|
1211
|
+
__name(_ts_decorate4, "_ts_decorate");
|
|
1212
|
+
function _ts_metadata4(k, v) {
|
|
1213
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
1214
|
+
}
|
|
1215
|
+
__name(_ts_metadata4, "_ts_metadata");
|
|
1216
|
+
var UnknownException = class _UnknownException extends WebhookLog {
|
|
1848
1217
|
static {
|
|
1849
1218
|
__name(this, "UnknownException");
|
|
1850
1219
|
}
|
|
1851
1220
|
webhook = new discord_js.WebhookClient({
|
|
1852
|
-
url:
|
|
1221
|
+
url: _UnknownException.unknownExceptionWebhookUrl
|
|
1853
1222
|
});
|
|
1854
1223
|
async execute() {
|
|
1855
1224
|
await this.webhook.send({
|
|
@@ -1861,7 +1230,16 @@ var UnknownException = class extends WebhookLog {
|
|
|
1861
1230
|
});
|
|
1862
1231
|
}
|
|
1863
1232
|
};
|
|
1864
|
-
|
|
1233
|
+
_ts_decorate4([
|
|
1234
|
+
envapt.Envapt("UNKNOWN_EXCEPTION_WEBHOOK_URL", {
|
|
1235
|
+
converter(raw, _fallback) {
|
|
1236
|
+
if (!raw) throw new Error("Missing UNKNOWN_EXCEPTION_WEBHOOK_URL");
|
|
1237
|
+
return raw;
|
|
1238
|
+
}
|
|
1239
|
+
}),
|
|
1240
|
+
_ts_metadata4("design:type", String)
|
|
1241
|
+
], UnknownException, "unknownExceptionWebhookUrl", void 0);
|
|
1242
|
+
UnknownException = _ts_decorate4([
|
|
1865
1243
|
RegisterEffect("unknownException")
|
|
1866
1244
|
], UnknownException);
|
|
1867
1245
|
var UnhandledErrorEmbed = class UnhandledErrorEmbed2 extends BuilderComponent {
|
|
@@ -1947,7 +1325,7 @@ var EffectsRegistry = class extends Plugin {
|
|
|
1947
1325
|
__name(this, "EffectsRegistry");
|
|
1948
1326
|
}
|
|
1949
1327
|
core;
|
|
1950
|
-
logger = new Logger("Effects");
|
|
1328
|
+
logger = new services.Logger("Effects");
|
|
1951
1329
|
isInitialized = false;
|
|
1952
1330
|
effectsMap = /* @__PURE__ */ new Map();
|
|
1953
1331
|
emitter = new EffectsEmitter();
|
|
@@ -1958,26 +1336,26 @@ var EffectsRegistry = class extends Plugin {
|
|
|
1958
1336
|
if (this.isInitialized) return;
|
|
1959
1337
|
this.isInitialized = true;
|
|
1960
1338
|
const effectsDir = this.core.config.effects.path;
|
|
1961
|
-
this.logger.info(
|
|
1339
|
+
this.logger.info(chalk2__default.default.bold(effectsDir));
|
|
1962
1340
|
this.registerEffect("unknownException", UnknownException);
|
|
1963
1341
|
await this.loadEffects(effectsDir);
|
|
1964
1342
|
this.attachEffects();
|
|
1965
1343
|
const totalEffects = Array.from(this.effectsMap.values()).reduce((acc, handlers) => acc + handlers.length, 0);
|
|
1966
|
-
this.logger.info(`${
|
|
1344
|
+
this.logger.info(`${chalk2__default.default.bold.green("Loaded")}: ${chalk2__default.default.bold.magenta(totalEffects)} side effects`);
|
|
1967
1345
|
}
|
|
1968
1346
|
async loadEffects(dir) {
|
|
1969
|
-
await traverseDirectory(dir, (_fullPath, relativePath, imported) => {
|
|
1347
|
+
await utils.traverseDirectory(dir, (_fullPath, relativePath, imported) => {
|
|
1970
1348
|
for (const exportName of Object.keys(imported)) {
|
|
1971
1349
|
const val = imported[exportName];
|
|
1972
1350
|
if (this.isEffectHandler(val)) {
|
|
1973
1351
|
const effectName = Reflect.getMetadata(EffectMetadataKey, val);
|
|
1974
1352
|
if (effectName) {
|
|
1975
1353
|
this.registerEffect(effectName, val);
|
|
1976
|
-
this.logger.info(`${
|
|
1354
|
+
this.logger.info(`${chalk2__default.default.italic("Registered")} ${chalk2__default.default.bold.yellow(val.name)} from ${chalk2__default.default.gray(relativePath)}`);
|
|
1977
1355
|
}
|
|
1978
1356
|
}
|
|
1979
1357
|
}
|
|
1980
|
-
});
|
|
1358
|
+
}, this.logger);
|
|
1981
1359
|
}
|
|
1982
1360
|
registerEffect(effectName, handler) {
|
|
1983
1361
|
let handlers = this.effectsMap.get(effectName);
|
|
@@ -2009,206 +1387,6 @@ var EffectsRegistry = class extends Plugin {
|
|
|
2009
1387
|
return this.emitter.emit(event, data);
|
|
2010
1388
|
}
|
|
2011
1389
|
};
|
|
2012
|
-
var HTTP_OK = 200;
|
|
2013
|
-
var HTTP_NOT_FOUND = 404;
|
|
2014
|
-
var HealthCheck = class extends Plugin {
|
|
2015
|
-
static {
|
|
2016
|
-
__name(this, "HealthCheck");
|
|
2017
|
-
}
|
|
2018
|
-
core;
|
|
2019
|
-
logger = new Logger("HealthCheck");
|
|
2020
|
-
port = Globals.healthCheckPort;
|
|
2021
|
-
path = Globals.healthCheckPath;
|
|
2022
|
-
server;
|
|
2023
|
-
constructor(core) {
|
|
2024
|
-
super(core), this.core = core;
|
|
2025
|
-
this.core.shutdown.addTask(ShutdownPhase.StopServices, "stop-healthcheck-server", async () => await this.stop());
|
|
2026
|
-
}
|
|
2027
|
-
/**
|
|
2028
|
-
* Starts the health check server.
|
|
2029
|
-
* @returns Promise that resolves when the server is listening
|
|
2030
|
-
*/
|
|
2031
|
-
async init() {
|
|
2032
|
-
return new Promise((resolve, reject) => {
|
|
2033
|
-
this.server = http.createServer((req, res) => {
|
|
2034
|
-
if (req.method === "GET" && req.url === this.path) {
|
|
2035
|
-
res.writeHead(HTTP_OK, {
|
|
2036
|
-
"Content-Type": "application/json"
|
|
2037
|
-
});
|
|
2038
|
-
res.end(JSON.stringify({
|
|
2039
|
-
status: "ok",
|
|
2040
|
-
timestamp: Date.now()
|
|
2041
|
-
}));
|
|
2042
|
-
} else {
|
|
2043
|
-
res.writeHead(HTTP_NOT_FOUND, {
|
|
2044
|
-
"Content-Type": "application/json"
|
|
2045
|
-
});
|
|
2046
|
-
res.end(JSON.stringify({
|
|
2047
|
-
status: "not found"
|
|
2048
|
-
}));
|
|
2049
|
-
}
|
|
2050
|
-
});
|
|
2051
|
-
this.server.on("error", reject);
|
|
2052
|
-
this.server.listen(this.port, () => {
|
|
2053
|
-
this.logger.info(`${chalk6__default.default.green.bold("\u2713")} Health check server listening on ${chalk6__default.default.cyan(`http://localhost:${this.port}${this.path}`)}`);
|
|
2054
|
-
resolve();
|
|
2055
|
-
});
|
|
2056
|
-
});
|
|
2057
|
-
}
|
|
2058
|
-
/**
|
|
2059
|
-
* Stops the health check server.
|
|
2060
|
-
*
|
|
2061
|
-
* @returns Promise that resolves when the server is closed
|
|
2062
|
-
*/
|
|
2063
|
-
stop() {
|
|
2064
|
-
return new Promise((shutdownResolve) => {
|
|
2065
|
-
this.server?.close(() => {
|
|
2066
|
-
this.logger.info(chalk6__default.default.bold.red("Health check server stopped"));
|
|
2067
|
-
shutdownResolve();
|
|
2068
|
-
});
|
|
2069
|
-
});
|
|
2070
|
-
}
|
|
2071
|
-
};
|
|
2072
|
-
var StartupPhase = /* @__PURE__ */ (function(StartupPhase2) {
|
|
2073
|
-
StartupPhase2[StartupPhase2["Validation"] = 1] = "Validation";
|
|
2074
|
-
StartupPhase2[StartupPhase2["Discovery"] = 2] = "Discovery";
|
|
2075
|
-
StartupPhase2[StartupPhase2["Registration"] = 3] = "Registration";
|
|
2076
|
-
StartupPhase2[StartupPhase2["Configuration"] = 4] = "Configuration";
|
|
2077
|
-
StartupPhase2[StartupPhase2["Instantiation"] = 5] = "Instantiation";
|
|
2078
|
-
StartupPhase2[StartupPhase2["Activation"] = 6] = "Activation";
|
|
2079
|
-
StartupPhase2[StartupPhase2["Ready"] = 7] = "Ready";
|
|
2080
|
-
return StartupPhase2;
|
|
2081
|
-
})({});
|
|
2082
|
-
var PHASE_ORDER2 = [
|
|
2083
|
-
1,
|
|
2084
|
-
2,
|
|
2085
|
-
3,
|
|
2086
|
-
4,
|
|
2087
|
-
5,
|
|
2088
|
-
6,
|
|
2089
|
-
7
|
|
2090
|
-
];
|
|
2091
|
-
var CoordinatedStartup = class extends CoordinatedLifecycle {
|
|
2092
|
-
static {
|
|
2093
|
-
__name(this, "CoordinatedStartup");
|
|
2094
|
-
}
|
|
2095
|
-
isStartingUp = false;
|
|
2096
|
-
hasStarted = false;
|
|
2097
|
-
constructor() {
|
|
2098
|
-
super("CoordinatedStartup", PHASE_ORDER2, StartupPhase);
|
|
2099
|
-
}
|
|
2100
|
-
/**
|
|
2101
|
-
* Adds a task to a specific startup phase with timeout.
|
|
2102
|
-
*
|
|
2103
|
-
* @param phase - The startup phase from {@link StartupPhase}
|
|
2104
|
-
* @param taskName - Unique identifier for the task
|
|
2105
|
-
* @param task - Async function to execute
|
|
2106
|
-
* @param timeoutMs - Task timeout in milliseconds (default: 10000)
|
|
2107
|
-
*/
|
|
2108
|
-
addTask(phase, taskName, task, timeoutMs = 1e4) {
|
|
2109
|
-
super.addTask(phase, taskName, task, timeoutMs);
|
|
2110
|
-
}
|
|
2111
|
-
canAddTask() {
|
|
2112
|
-
if (this.hasStarted) {
|
|
2113
|
-
throw new Error("Cannot add tasks after startup sequence has already completed");
|
|
2114
|
-
}
|
|
2115
|
-
if (this.isStartingUp) {
|
|
2116
|
-
throw new Error("Cannot add tasks while startup sequence is in progress");
|
|
2117
|
-
}
|
|
2118
|
-
return true;
|
|
2119
|
-
}
|
|
2120
|
-
canRemoveTask() {
|
|
2121
|
-
if (this.isStartingUp) {
|
|
2122
|
-
throw new Error("Cannot remove tasks while startup sequence is in progress");
|
|
2123
|
-
}
|
|
2124
|
-
return true;
|
|
2125
|
-
}
|
|
2126
|
-
getTaskType() {
|
|
2127
|
-
return "startup";
|
|
2128
|
-
}
|
|
2129
|
-
async executeTasksInPhase(phase, tasks) {
|
|
2130
|
-
const results = [];
|
|
2131
|
-
for (const task of tasks) {
|
|
2132
|
-
results.push(await Promise.resolve().then(() => this.runTaskWithTimeout(phase, task)).then(
|
|
2133
|
-
() => ({
|
|
2134
|
-
status: "fulfilled",
|
|
2135
|
-
value: void 0
|
|
2136
|
-
}),
|
|
2137
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
2138
|
-
(reason) => ({
|
|
2139
|
-
status: "rejected",
|
|
2140
|
-
reason
|
|
2141
|
-
})
|
|
2142
|
-
));
|
|
2143
|
-
}
|
|
2144
|
-
return results;
|
|
2145
|
-
}
|
|
2146
|
-
/**
|
|
2147
|
-
* Executes the coordinated startup sequence.
|
|
2148
|
-
*
|
|
2149
|
-
* Runs all registered tasks across startup phases in the correct order.
|
|
2150
|
-
* Each phase completes before the next phase begins. Tasks within a phase
|
|
2151
|
-
* are executed sequentially to maintain predictable initialization.
|
|
2152
|
-
*
|
|
2153
|
-
* @returns Promise that resolves when startup is complete
|
|
2154
|
-
* @throws An {@link Error} If startup fails or is called multiple times
|
|
2155
|
-
* @example
|
|
2156
|
-
* ```typescript
|
|
2157
|
-
* const startup = new CoordinatedStartup();
|
|
2158
|
-
* startup.addTask(StartupPhase.Services, 'database', () => db.connect(), 10000);
|
|
2159
|
-
* await startup.run();
|
|
2160
|
-
* ```
|
|
2161
|
-
*/
|
|
2162
|
-
async run() {
|
|
2163
|
-
if (this.hasStarted) {
|
|
2164
|
-
this.logger.warn("Startup sequence has already completed");
|
|
2165
|
-
return;
|
|
2166
|
-
}
|
|
2167
|
-
if (this.isStartingUp) {
|
|
2168
|
-
this.logger.warn("Startup sequence already in progress");
|
|
2169
|
-
return;
|
|
2170
|
-
}
|
|
2171
|
-
this.isStartingUp = true;
|
|
2172
|
-
this.logger.info(`${chalk6__default.default.bold.green("Starting")} coordinated startup sequence`);
|
|
2173
|
-
this.emit("startup:start");
|
|
2174
|
-
try {
|
|
2175
|
-
for (const phase of PHASE_ORDER2) await this.runPhase(phase);
|
|
2176
|
-
this.hasStarted = true;
|
|
2177
|
-
this.logger.info(`${chalk6__default.default.bold.green("Coordinated startup completed")} successfully`);
|
|
2178
|
-
this.emit("startup:complete");
|
|
2179
|
-
} catch (error) {
|
|
2180
|
-
this.logger.error(`${chalk6__default.default.bold.red("Coordinated startup failed")}`);
|
|
2181
|
-
this.emit("startup:error", error);
|
|
2182
|
-
throw error;
|
|
2183
|
-
} finally {
|
|
2184
|
-
this.isStartingUp = false;
|
|
2185
|
-
}
|
|
2186
|
-
}
|
|
2187
|
-
/**
|
|
2188
|
-
* Subscribe to startup events
|
|
2189
|
-
*/
|
|
2190
|
-
on(event, listener) {
|
|
2191
|
-
super.on(event, listener);
|
|
2192
|
-
}
|
|
2193
|
-
/**
|
|
2194
|
-
* Unsubscribe from startup events
|
|
2195
|
-
*/
|
|
2196
|
-
off(event, listener) {
|
|
2197
|
-
super.off(event, listener);
|
|
2198
|
-
}
|
|
2199
|
-
/**
|
|
2200
|
-
* Check if startup has completed
|
|
2201
|
-
*/
|
|
2202
|
-
get isReady() {
|
|
2203
|
-
return this.hasStarted;
|
|
2204
|
-
}
|
|
2205
|
-
/**
|
|
2206
|
-
* Check if startup is currently running
|
|
2207
|
-
*/
|
|
2208
|
-
get isRunning() {
|
|
2209
|
-
return this.isStartingUp;
|
|
2210
|
-
}
|
|
2211
|
-
};
|
|
2212
1390
|
|
|
2213
1391
|
// src/Seedcord.ts
|
|
2214
1392
|
var Seedcord = class _Seedcord extends Pluggable {
|
|
@@ -2234,8 +1412,8 @@ var Seedcord = class _Seedcord extends Pluggable {
|
|
|
2234
1412
|
* @throws An {@link Error} When attempting to create multiple instances (singleton)
|
|
2235
1413
|
*/
|
|
2236
1414
|
constructor(config) {
|
|
2237
|
-
const shutdown = new CoordinatedShutdown();
|
|
2238
|
-
const startup = new CoordinatedStartup();
|
|
1415
|
+
const shutdown = new services.CoordinatedShutdown();
|
|
1416
|
+
const startup = new services.CoordinatedStartup();
|
|
2239
1417
|
super(shutdown, startup), this.config = config;
|
|
2240
1418
|
this.shutdown = shutdown;
|
|
2241
1419
|
this.startup = startup;
|
|
@@ -2245,7 +1423,7 @@ var Seedcord = class _Seedcord extends Pluggable {
|
|
|
2245
1423
|
_Seedcord.isInstantiated = true;
|
|
2246
1424
|
this.effects = new EffectsRegistry(this);
|
|
2247
1425
|
this.bot = new Bot(this);
|
|
2248
|
-
this.healthCheck = new HealthCheck(this);
|
|
1426
|
+
this.healthCheck = new services.HealthCheck(this.shutdown);
|
|
2249
1427
|
this.registerStartupTasks();
|
|
2250
1428
|
}
|
|
2251
1429
|
/**
|
|
@@ -2253,20 +1431,20 @@ var Seedcord = class _Seedcord extends Pluggable {
|
|
|
2253
1431
|
* @internal
|
|
2254
1432
|
*/
|
|
2255
1433
|
registerStartupTasks() {
|
|
2256
|
-
this.startup.addTask(StartupPhase.Configuration, "Effect Initialization", async () => {
|
|
2257
|
-
this.effects.logger.info(
|
|
1434
|
+
this.startup.addTask(services.StartupPhase.Configuration, "Effect Initialization", async () => {
|
|
1435
|
+
this.effects.logger.info(chalk2__default.default.bold("Initializing"));
|
|
2258
1436
|
await this.effects.init();
|
|
2259
|
-
this.effects.logger.info(
|
|
1437
|
+
this.effects.logger.info(chalk2__default.default.bold("Initialized"));
|
|
2260
1438
|
});
|
|
2261
|
-
this.startup.addTask(StartupPhase.Instantiation, "Bot Initialization", async () => {
|
|
2262
|
-
this.bot.logger.info(
|
|
1439
|
+
this.startup.addTask(services.StartupPhase.Instantiation, "Bot Initialization", async () => {
|
|
1440
|
+
this.bot.logger.info(chalk2__default.default.bold("Initializing"));
|
|
2263
1441
|
await this.bot.init();
|
|
2264
|
-
this.bot.logger.info(
|
|
1442
|
+
this.bot.logger.info(chalk2__default.default.bold("Initialized"));
|
|
2265
1443
|
});
|
|
2266
|
-
this.startup.addTask(StartupPhase.Ready, "Health Check", async () => {
|
|
2267
|
-
this.healthCheck.logger.info(
|
|
1444
|
+
this.startup.addTask(services.StartupPhase.Ready, "Health Check", async () => {
|
|
1445
|
+
this.healthCheck.logger.info(chalk2__default.default.bold("Initializing"));
|
|
2268
1446
|
await this.healthCheck.init();
|
|
2269
|
-
this.healthCheck.logger.info(
|
|
1447
|
+
this.healthCheck.logger.info(chalk2__default.default.bold("Initialized"));
|
|
2270
1448
|
});
|
|
2271
1449
|
}
|
|
2272
1450
|
/**
|
|
@@ -2316,74 +1494,21 @@ function EventCatchable(log) {
|
|
|
2316
1494
|
};
|
|
2317
1495
|
}
|
|
2318
1496
|
__name(EventCatchable, "EventCatchable");
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
* Creates a new CooldownManager instance.
|
|
2331
|
-
*
|
|
2332
|
-
* @param opts - Configuration options for the cooldown behavior
|
|
2333
|
-
*/
|
|
2334
|
-
constructor(opts = {}) {
|
|
2335
|
-
this.window = opts.cooldown ?? 1e3;
|
|
2336
|
-
this.Err = opts.err ?? Error;
|
|
2337
|
-
this.msg = opts.message ?? "Cooldown active";
|
|
2338
|
-
}
|
|
2339
|
-
/**
|
|
2340
|
-
* Records usage timestamp for a key without any cooldown checks.
|
|
2341
|
-
*
|
|
2342
|
-
* @param key - The unique identifier for the cooldown entry
|
|
2343
|
-
*/
|
|
2344
|
-
set(key) {
|
|
2345
|
-
this.map.set(key, Date.now());
|
|
2346
|
-
}
|
|
2347
|
-
/**
|
|
2348
|
-
* Verifies cooldown status for a key and updates timestamp if not active.
|
|
2349
|
-
*
|
|
2350
|
-
* If the cooldown is still active, throws the configured error.
|
|
2351
|
-
* If not active, updates the timestamp and returns successfully.
|
|
2352
|
-
*
|
|
2353
|
-
* @param key - The unique identifier to check cooldown for
|
|
2354
|
-
* @throws An {@link Err} When the cooldown is still active for the given key
|
|
2355
|
-
*/
|
|
2356
|
-
check(key) {
|
|
2357
|
-
const now = Date.now();
|
|
2358
|
-
const last = this.map.get(key);
|
|
2359
|
-
const remaining = this.window - (now - (last ?? 0));
|
|
2360
|
-
if (Globals.isDevelopment && remaining > 0) {
|
|
2361
|
-
Logger.Debug("CooldownManager", `${key} - ${remaining}ms remaining`);
|
|
2362
|
-
}
|
|
2363
|
-
if (last !== void 0 && remaining > 0) {
|
|
2364
|
-
throw new this.Err(this.msg, remaining);
|
|
1497
|
+
function throwCustomError(error, message, CustomError2) {
|
|
1498
|
+
const uuid = crypto.randomUUID();
|
|
1499
|
+
services.Logger.Error("Throwing Custom Error", error.name);
|
|
1500
|
+
if (typeof CustomError2 === typeof DatabaseError) {
|
|
1501
|
+
const errorMessage = error instanceof Error ? error.message : message;
|
|
1502
|
+
throw new CustomError2(errorMessage, uuid);
|
|
1503
|
+
} else {
|
|
1504
|
+
if (error instanceof Error) {
|
|
1505
|
+
throw new CustomError2(`${message}: ${error.message ? error.message : error.toString()}`);
|
|
1506
|
+
} else {
|
|
1507
|
+
throw new CustomError2(message);
|
|
2365
1508
|
}
|
|
2366
|
-
this.map.set(key, now);
|
|
2367
|
-
}
|
|
2368
|
-
/**
|
|
2369
|
-
* Checks if a key is currently cooling down without updating timestamp.
|
|
2370
|
-
*
|
|
2371
|
-
* @param key - The unique identifier to check
|
|
2372
|
-
* @returns True if the key is still cooling down, false otherwise
|
|
2373
|
-
*/
|
|
2374
|
-
isActive(key) {
|
|
2375
|
-
const last = this.map.get(key);
|
|
2376
|
-
return last !== void 0 && Date.now() - last < this.window;
|
|
2377
1509
|
}
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
*
|
|
2381
|
-
* @param key - The unique identifier to remove (useful for manual resets)
|
|
2382
|
-
*/
|
|
2383
|
-
clear(key) {
|
|
2384
|
-
this.map.delete(key);
|
|
2385
|
-
}
|
|
2386
|
-
};
|
|
1510
|
+
}
|
|
1511
|
+
__name(throwCustomError, "throwCustomError");
|
|
2387
1512
|
|
|
2388
1513
|
exports.AutocompleteHandler = AutocompleteHandler;
|
|
2389
1514
|
exports.AutocompleteRoute = AutocompleteRoute;
|
|
@@ -2395,9 +1520,6 @@ exports.Catchable = Catchable;
|
|
|
2395
1520
|
exports.Checkable = Checkable;
|
|
2396
1521
|
exports.CommandMetadataKey = CommandMetadataKey;
|
|
2397
1522
|
exports.ContextMenuRoute = ContextMenuRoute;
|
|
2398
|
-
exports.CooldownManager = CooldownManager;
|
|
2399
|
-
exports.CoordinatedShutdown = CoordinatedShutdown;
|
|
2400
|
-
exports.CoordinatedStartup = CoordinatedStartup;
|
|
2401
1523
|
exports.CustomError = CustomError;
|
|
2402
1524
|
exports.DatabaseError = DatabaseError;
|
|
2403
1525
|
exports.EffectMetadataKey = EffectMetadataKey;
|
|
@@ -2407,13 +1529,10 @@ exports.EffectsRegistry = EffectsRegistry;
|
|
|
2407
1529
|
exports.EventCatchable = EventCatchable;
|
|
2408
1530
|
exports.EventHandler = EventHandler;
|
|
2409
1531
|
exports.EventMetadataKey = EventMetadataKey;
|
|
2410
|
-
exports.Globals = Globals;
|
|
2411
|
-
exports.HealthCheck = HealthCheck;
|
|
2412
1532
|
exports.InteractionHandler = InteractionHandler;
|
|
2413
1533
|
exports.InteractionMetadataKey = InteractionMetadataKey;
|
|
2414
1534
|
exports.InteractionMiddleware = InteractionMiddleware;
|
|
2415
1535
|
exports.InteractionRoutes = InteractionRoutes;
|
|
2416
|
-
exports.Logger = Logger;
|
|
2417
1536
|
exports.ModalComponent = ModalComponent;
|
|
2418
1537
|
exports.ModalRoute = ModalRoute;
|
|
2419
1538
|
exports.Pluggable = Pluggable;
|
|
@@ -2425,22 +1544,20 @@ exports.RowComponent = RowComponent;
|
|
|
2425
1544
|
exports.Seedcord = Seedcord;
|
|
2426
1545
|
exports.SelectMenuRoute = SelectMenuRoute;
|
|
2427
1546
|
exports.SelectMenuType = SelectMenuType;
|
|
2428
|
-
exports.ShutdownPhase = ShutdownPhase;
|
|
2429
1547
|
exports.SlashRoute = SlashRoute;
|
|
2430
|
-
exports.StartupPhase = StartupPhase;
|
|
2431
1548
|
exports.WebhookLog = WebhookLog;
|
|
2432
|
-
exports.currentTime = currentTime;
|
|
2433
|
-
exports.formatWord = formatWord;
|
|
2434
|
-
exports.fyShuffle = fyShuffle;
|
|
2435
|
-
exports.generateAsciiTable = generateAsciiTable;
|
|
2436
|
-
exports.isTsOrJsFile = isTsOrJsFile;
|
|
2437
|
-
exports.longestStringLength = longestStringLength;
|
|
2438
|
-
exports.numberFixer = numberFixer;
|
|
2439
|
-
exports.ordinal = ordinal;
|
|
2440
|
-
exports.percentage = percentage;
|
|
2441
|
-
exports.prettify = prettify;
|
|
2442
|
-
exports.prettyDifference = prettyDifference;
|
|
2443
1549
|
exports.throwCustomError = throwCustomError;
|
|
2444
|
-
|
|
1550
|
+
Object.keys(services).forEach(function (k) {
|
|
1551
|
+
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|
|
1552
|
+
enumerable: true,
|
|
1553
|
+
get: function () { return services[k]; }
|
|
1554
|
+
});
|
|
1555
|
+
});
|
|
1556
|
+
Object.keys(utils).forEach(function (k) {
|
|
1557
|
+
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|
|
1558
|
+
enumerable: true,
|
|
1559
|
+
get: function () { return utils[k]; }
|
|
1560
|
+
});
|
|
1561
|
+
});
|
|
2445
1562
|
//# sourceMappingURL=index.cjs.map
|
|
2446
1563
|
//# sourceMappingURL=index.cjs.map
|