vimcord 1.0.36 → 1.0.37
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 +395 -47
- package/dist/index.cjs +1234 -1018
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +741 -411
- package/dist/index.d.ts +741 -411
- package/dist/index.js +1209 -1003
- package/dist/index.js.map +1 -1
- package/dist/metafile-cjs.json +1 -1
- package/dist/metafile-esm.json +1 -1
- package/package.json +8 -8
package/dist/index.js
CHANGED
|
@@ -5,6 +5,9 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
|
|
|
5
5
|
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
6
6
|
});
|
|
7
7
|
|
|
8
|
+
// src/modules/validators/permissions.validator.ts
|
|
9
|
+
import { BaseInteraction } from "discord.js";
|
|
10
|
+
|
|
8
11
|
// src/types/command.base.ts
|
|
9
12
|
var CommandType = /* @__PURE__ */ ((CommandType2) => {
|
|
10
13
|
CommandType2[CommandType2["Slash"] = 0] = "Slash";
|
|
@@ -32,8 +35,7 @@ var RateLimitScope = /* @__PURE__ */ ((RateLimitScope2) => {
|
|
|
32
35
|
return RateLimitScope2;
|
|
33
36
|
})(RateLimitScope || {});
|
|
34
37
|
|
|
35
|
-
// src/validators/permissions.validator.ts
|
|
36
|
-
import { BaseInteraction } from "discord.js";
|
|
38
|
+
// src/modules/validators/permissions.validator.ts
|
|
37
39
|
function __existsAndTrue(value) {
|
|
38
40
|
return value !== void 0 && value;
|
|
39
41
|
}
|
|
@@ -132,8 +134,8 @@ function validateCommandPermissions(permissions, client, user, command) {
|
|
|
132
134
|
}
|
|
133
135
|
|
|
134
136
|
// src/builders/baseCommand.builder.ts
|
|
135
|
-
import { randomUUID } from "crypto";
|
|
136
137
|
import _ from "lodash";
|
|
138
|
+
import { randomUUID } from "crypto";
|
|
137
139
|
var BaseCommandBuilder = class {
|
|
138
140
|
uuid = randomUUID();
|
|
139
141
|
commandType;
|
|
@@ -423,55 +425,199 @@ var ContextCommandBuilder = class extends BaseCommandBuilder {
|
|
|
423
425
|
}
|
|
424
426
|
};
|
|
425
427
|
|
|
426
|
-
// src/
|
|
427
|
-
import
|
|
428
|
-
import
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
428
|
+
// src/builders/event.builder.ts
|
|
429
|
+
import { randomUUID as randomUUID2 } from "crypto";
|
|
430
|
+
import _3 from "lodash";
|
|
431
|
+
|
|
432
|
+
// src/tools/Logger.ts
|
|
433
|
+
import chalk from "chalk";
|
|
434
|
+
var LogLevel = /* @__PURE__ */ ((LogLevel2) => {
|
|
435
|
+
LogLevel2[LogLevel2["DEBUG"] = 0] = "DEBUG";
|
|
436
|
+
LogLevel2[LogLevel2["INFO"] = 1] = "INFO";
|
|
437
|
+
LogLevel2[LogLevel2["SUCCESS"] = 2] = "SUCCESS";
|
|
438
|
+
LogLevel2[LogLevel2["WARN"] = 3] = "WARN";
|
|
439
|
+
LogLevel2[LogLevel2["ERROR"] = 4] = "ERROR";
|
|
440
|
+
return LogLevel2;
|
|
441
|
+
})(LogLevel || {});
|
|
442
|
+
var LOGGER_COLORS = {
|
|
443
|
+
primary: "#5865F2",
|
|
444
|
+
success: "#57F287",
|
|
445
|
+
warn: "#FEE75C",
|
|
446
|
+
danger: "#ED4245",
|
|
447
|
+
muted: "#747F8D",
|
|
448
|
+
text: "#FFFFFF"
|
|
449
|
+
};
|
|
450
|
+
var Logger = class {
|
|
451
|
+
logPrefixEmoji;
|
|
452
|
+
logPrefix;
|
|
453
|
+
minLevel;
|
|
454
|
+
showTimestamp;
|
|
455
|
+
colorScheme;
|
|
456
|
+
constructor(options) {
|
|
457
|
+
const { prefixEmoji = null, prefix = null, minLevel = 0 /* DEBUG */, showTimestamp = true } = options || {};
|
|
458
|
+
this.logPrefixEmoji = prefixEmoji;
|
|
459
|
+
this.logPrefix = prefix;
|
|
460
|
+
this.minLevel = minLevel;
|
|
461
|
+
this.showTimestamp = showTimestamp;
|
|
462
|
+
this.colorScheme = {
|
|
463
|
+
...LOGGER_COLORS,
|
|
464
|
+
...options?.colors
|
|
465
|
+
};
|
|
445
466
|
}
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
467
|
+
formatTimestamp() {
|
|
468
|
+
if (!this.showTimestamp) return "";
|
|
469
|
+
const now = /* @__PURE__ */ new Date();
|
|
470
|
+
const time = now.toLocaleTimeString("en-US", {
|
|
471
|
+
hour12: false,
|
|
472
|
+
hour: "2-digit",
|
|
473
|
+
minute: "2-digit",
|
|
474
|
+
second: "2-digit"
|
|
475
|
+
});
|
|
476
|
+
return chalk.hex(this.colorScheme.muted)(`[${time}]`);
|
|
477
|
+
}
|
|
478
|
+
formatPrefix() {
|
|
479
|
+
if (!this.logPrefix) return "";
|
|
480
|
+
return chalk.bold.hex(this.colorScheme.primary)(
|
|
481
|
+
`${this.logPrefixEmoji ? `${this.logPrefixEmoji} ` : ""}${this.logPrefix}`
|
|
482
|
+
);
|
|
483
|
+
}
|
|
484
|
+
shouldLog(level) {
|
|
485
|
+
return level >= this.minLevel;
|
|
486
|
+
}
|
|
487
|
+
get prefixEmoji() {
|
|
488
|
+
return this.logPrefixEmoji;
|
|
489
|
+
}
|
|
490
|
+
get prefix() {
|
|
491
|
+
return this.logPrefix;
|
|
492
|
+
}
|
|
493
|
+
get colors() {
|
|
494
|
+
return this.colorScheme;
|
|
495
|
+
}
|
|
496
|
+
extend(extras) {
|
|
497
|
+
for (const [key, fn] of Object.entries(extras)) {
|
|
498
|
+
if (typeof fn === "function") {
|
|
499
|
+
this[key] = function(...args) {
|
|
500
|
+
return fn.call(this, ...args);
|
|
501
|
+
};
|
|
457
502
|
}
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
);
|
|
461
|
-
const filteredModules = modules.filter((m) => m.module);
|
|
462
|
-
if (!filteredModules.length) {
|
|
463
|
-
console.warn(`No valid modules were found in directory '${dir}'`);
|
|
503
|
+
}
|
|
504
|
+
return this;
|
|
464
505
|
}
|
|
465
|
-
|
|
466
|
-
|
|
506
|
+
setPrefix(prefix) {
|
|
507
|
+
this.logPrefix = prefix;
|
|
508
|
+
return this;
|
|
509
|
+
}
|
|
510
|
+
setPrefixEmoji(prefixEmoji) {
|
|
511
|
+
this.logPrefixEmoji = prefixEmoji;
|
|
512
|
+
return this;
|
|
513
|
+
}
|
|
514
|
+
setMinLevel(minLevel) {
|
|
515
|
+
this.minLevel = minLevel;
|
|
516
|
+
return this;
|
|
517
|
+
}
|
|
518
|
+
setShowTimestamp(show) {
|
|
519
|
+
this.showTimestamp = show;
|
|
520
|
+
return this;
|
|
521
|
+
}
|
|
522
|
+
setColors(colors) {
|
|
523
|
+
this.colorScheme = {
|
|
524
|
+
...LOGGER_COLORS,
|
|
525
|
+
...colors
|
|
526
|
+
};
|
|
527
|
+
return this;
|
|
528
|
+
}
|
|
529
|
+
log(message, ...args) {
|
|
530
|
+
console.log(this.formatTimestamp(), this.formatPrefix(), message, ...args);
|
|
531
|
+
}
|
|
532
|
+
debug(message, ...args) {
|
|
533
|
+
if (!this.shouldLog(0 /* DEBUG */)) return;
|
|
534
|
+
console.log(
|
|
535
|
+
this.formatTimestamp(),
|
|
536
|
+
this.formatPrefix(),
|
|
537
|
+
chalk.hex(this.colorScheme.muted)("DEBUG"),
|
|
538
|
+
chalk.dim(message),
|
|
539
|
+
...args
|
|
540
|
+
);
|
|
541
|
+
}
|
|
542
|
+
info(message, ...args) {
|
|
543
|
+
if (!this.shouldLog(1 /* INFO */)) return;
|
|
544
|
+
console.log(this.formatTimestamp(), this.formatPrefix(), chalk.hex("#87CEEB")("INFO"), message, ...args);
|
|
545
|
+
}
|
|
546
|
+
success(message, ...args) {
|
|
547
|
+
if (!this.shouldLog(2 /* SUCCESS */)) return;
|
|
548
|
+
console.log(
|
|
549
|
+
this.formatTimestamp(),
|
|
550
|
+
this.formatPrefix(),
|
|
551
|
+
chalk.bold.hex(this.colorScheme.success)("\u2713 SUCCESS"),
|
|
552
|
+
chalk.hex(this.colorScheme.success)(message),
|
|
553
|
+
...args
|
|
554
|
+
);
|
|
555
|
+
}
|
|
556
|
+
warn(message, ...args) {
|
|
557
|
+
if (!this.shouldLog(3 /* WARN */)) return;
|
|
558
|
+
console.warn(
|
|
559
|
+
this.formatTimestamp(),
|
|
560
|
+
this.formatPrefix(),
|
|
561
|
+
chalk.bold.hex(this.colorScheme.warn)("\u26A0 WARN"),
|
|
562
|
+
chalk.hex(this.colorScheme.warn)(message),
|
|
563
|
+
...args
|
|
564
|
+
);
|
|
565
|
+
}
|
|
566
|
+
error(message, error, ...args) {
|
|
567
|
+
if (!this.shouldLog(4 /* ERROR */)) return;
|
|
568
|
+
console.error(
|
|
569
|
+
this.formatTimestamp(),
|
|
570
|
+
this.formatPrefix(),
|
|
571
|
+
chalk.bold.hex(this.colorScheme.danger)("\u2715 ERROR"),
|
|
572
|
+
chalk.hex(this.colorScheme.danger)(message),
|
|
573
|
+
...args
|
|
574
|
+
);
|
|
575
|
+
if (error && error.stack) {
|
|
576
|
+
console.error(chalk.dim(error.stack));
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
loader(message) {
|
|
580
|
+
const frames = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
581
|
+
let i = 0;
|
|
582
|
+
const interval = setInterval(() => {
|
|
583
|
+
process.stdout.write(
|
|
584
|
+
`\r${this.formatTimestamp()} ${this.formatPrefix()} ${chalk.hex(this.colorScheme.warn)(frames[i])} ${message}`
|
|
585
|
+
);
|
|
586
|
+
i = (i + 1) % frames.length;
|
|
587
|
+
}, 100);
|
|
588
|
+
return (newMessage) => {
|
|
589
|
+
clearInterval(interval);
|
|
590
|
+
process.stdout.write(
|
|
591
|
+
`\r${this.formatTimestamp()} ${this.formatPrefix()} ${chalk.hex(this.colorScheme.success)("\u2713")} ${newMessage || message}
|
|
592
|
+
`
|
|
593
|
+
);
|
|
594
|
+
};
|
|
595
|
+
}
|
|
596
|
+
table(title, data) {
|
|
597
|
+
console.log(this.formatTimestamp(), this.formatPrefix(), chalk.bold(title));
|
|
598
|
+
Object.entries(data).forEach(([key, value]) => {
|
|
599
|
+
const formattedKey = chalk.hex(this.colorScheme.warn)(` ${key}`);
|
|
600
|
+
const formattedValue = chalk.hex(this.colorScheme.muted)(value);
|
|
601
|
+
console.log(`${formattedKey.padEnd(25)} ${formattedValue}`);
|
|
602
|
+
});
|
|
603
|
+
}
|
|
604
|
+
section(title) {
|
|
605
|
+
const line = "\u2500".repeat(Math.max(30, title.length + 4));
|
|
606
|
+
console.log(chalk.hex(this.colorScheme.muted)(`
|
|
607
|
+
\u250C\u2500${line}\u2500\u2510`));
|
|
608
|
+
console.log(
|
|
609
|
+
chalk.hex(this.colorScheme.muted)("\u2502 ") + chalk.bold.hex(this.colorScheme.text)(title.padEnd(line.length)) + chalk.hex(this.colorScheme.muted)(" \u2502")
|
|
610
|
+
);
|
|
611
|
+
console.log(chalk.hex(this.colorScheme.muted)(`\u2514\u2500${line}\u2500\u2518`));
|
|
612
|
+
}
|
|
613
|
+
};
|
|
614
|
+
var logger = new Logger();
|
|
467
615
|
|
|
468
616
|
// src/builders/event.builder.ts
|
|
469
|
-
import { randomUUID as randomUUID2 } from "crypto";
|
|
470
|
-
import _3 from "lodash";
|
|
471
617
|
var EventBuilder = class _EventBuilder {
|
|
472
618
|
uuid = randomUUID2();
|
|
473
619
|
event;
|
|
474
|
-
name =
|
|
620
|
+
name = this.uuid;
|
|
475
621
|
enabled;
|
|
476
622
|
once;
|
|
477
623
|
priority;
|
|
@@ -636,6 +782,7 @@ var EventBuilder = class _EventBuilder {
|
|
|
636
782
|
return;
|
|
637
783
|
}
|
|
638
784
|
if (this.isRateLimited()) {
|
|
785
|
+
logger.warn(`Event '${this.name}' (${this.event}) is rate limited`);
|
|
639
786
|
if (this.rateLimit?.onRateLimit) {
|
|
640
787
|
return await this.rateLimit.onRateLimit(...args);
|
|
641
788
|
}
|
|
@@ -656,7 +803,7 @@ var EventBuilder = class _EventBuilder {
|
|
|
656
803
|
if (this.onError) {
|
|
657
804
|
return await this.onError(err, ...args);
|
|
658
805
|
}
|
|
659
|
-
|
|
806
|
+
logger.error(`Event execution error '${this.name}' (${this.event}):`, err);
|
|
660
807
|
throw err;
|
|
661
808
|
}
|
|
662
809
|
}
|
|
@@ -822,22 +969,120 @@ var SlashCommandBuilder = class extends BaseCommandBuilder {
|
|
|
822
969
|
}
|
|
823
970
|
};
|
|
824
971
|
|
|
825
|
-
// src/
|
|
826
|
-
|
|
827
|
-
|
|
972
|
+
// src/modules/builtins/context-command.builtins.ts
|
|
973
|
+
var contextCommandHandler = new EventBuilder({
|
|
974
|
+
event: "interactionCreate",
|
|
975
|
+
name: "ContextCommandHandler",
|
|
976
|
+
async execute(client, interaction) {
|
|
977
|
+
if (!interaction.isContextMenuCommand()) return;
|
|
978
|
+
const command = client.commands.context.get(interaction.commandName);
|
|
979
|
+
if (!command) {
|
|
980
|
+
const content = `**${interaction.commandName}** is not a registered context command.`;
|
|
981
|
+
if (interaction.replied || interaction.deferred) {
|
|
982
|
+
return interaction.followUp({ content, flags: "Ephemeral" });
|
|
983
|
+
}
|
|
984
|
+
return interaction.reply({ content, flags: "Ephemeral" });
|
|
985
|
+
}
|
|
986
|
+
try {
|
|
987
|
+
return await command.run(client, client, interaction);
|
|
988
|
+
} catch (err) {
|
|
989
|
+
await client.error.handleCommandError(err, interaction.guild, interaction);
|
|
990
|
+
}
|
|
991
|
+
}
|
|
992
|
+
});
|
|
828
993
|
|
|
829
|
-
// src/
|
|
830
|
-
import
|
|
831
|
-
var
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
994
|
+
// src/modules/builtins/prefix-command.builtins.ts
|
|
995
|
+
import { userMention } from "discord.js";
|
|
996
|
+
var prefixCommandHandler = new EventBuilder({
|
|
997
|
+
event: "messageCreate",
|
|
998
|
+
name: "PrefixCommandHandler",
|
|
999
|
+
async execute(client, message) {
|
|
1000
|
+
if (message.author.bot || !message.guild) return;
|
|
1001
|
+
const config = client.config.prefixCommands;
|
|
1002
|
+
let activePrefix = config.defaultPrefix;
|
|
1003
|
+
if (config.guildPrefixResolver) {
|
|
1004
|
+
try {
|
|
1005
|
+
const customPrefix = await config.guildPrefixResolver(client, message.guild.id);
|
|
1006
|
+
if (customPrefix) activePrefix = customPrefix;
|
|
1007
|
+
} catch (err) {
|
|
1008
|
+
client.logger.error(`Error in guildPrefixResolver for guild ${message.guild.id}:`, err);
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
let prefixUsed;
|
|
1012
|
+
if (message.content.startsWith(activePrefix)) {
|
|
1013
|
+
prefixUsed = activePrefix;
|
|
1014
|
+
} else if (config.allowMentionAsPrefix) {
|
|
1015
|
+
const mention = userMention(client.user.id);
|
|
1016
|
+
if (message.content.startsWith(mention)) {
|
|
1017
|
+
prefixUsed = message.content.startsWith(`${mention} `) ? `${mention} ` : mention;
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
1020
|
+
if (!prefixUsed) return;
|
|
1021
|
+
const contentWithoutPrefix = message.content.slice(prefixUsed.length).trim();
|
|
1022
|
+
const args = contentWithoutPrefix.split(/\s+/);
|
|
1023
|
+
const trigger = args.shift();
|
|
1024
|
+
if (!trigger) return;
|
|
1025
|
+
const command = client.commands.prefix.get(trigger);
|
|
1026
|
+
if (!command) return;
|
|
1027
|
+
message.content = args.join(" ");
|
|
1028
|
+
try {
|
|
1029
|
+
return await command.run(client, client, message);
|
|
1030
|
+
} catch (err) {
|
|
1031
|
+
await client.error.handleCommandError(err, message.guild, message);
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
1034
|
+
});
|
|
1035
|
+
|
|
1036
|
+
// src/modules/builtins/slash-command.builtins.ts
|
|
1037
|
+
var slashCommandHandler = new EventBuilder({
|
|
1038
|
+
event: "interactionCreate",
|
|
1039
|
+
name: "SlashCommandHandler",
|
|
1040
|
+
async execute(client, interaction) {
|
|
1041
|
+
if (!interaction.isChatInputCommand()) return;
|
|
1042
|
+
const command = client.commands.slash.get(interaction.commandName);
|
|
1043
|
+
if (!command) {
|
|
1044
|
+
const content = `**/\`${interaction.commandName}\`** is not a registered command.`;
|
|
1045
|
+
if (interaction.replied || interaction.deferred) {
|
|
1046
|
+
return interaction.followUp({ content, flags: "Ephemeral" });
|
|
1047
|
+
}
|
|
1048
|
+
return interaction.reply({ content, flags: "Ephemeral" });
|
|
1049
|
+
}
|
|
1050
|
+
try {
|
|
1051
|
+
return await command.run(client, client, interaction);
|
|
1052
|
+
} catch (err) {
|
|
1053
|
+
await client.error.handleCommandError(err, interaction.guild, interaction);
|
|
1054
|
+
}
|
|
1055
|
+
}
|
|
1056
|
+
});
|
|
1057
|
+
|
|
1058
|
+
// src/tools/BetterEmbed.ts
|
|
1059
|
+
import {
|
|
1060
|
+
EmbedBuilder,
|
|
1061
|
+
GuildMember as GuildMember3,
|
|
1062
|
+
User as User3
|
|
1063
|
+
} from "discord.js";
|
|
1064
|
+
|
|
1065
|
+
// src/utils/config.factory.ts
|
|
1066
|
+
import _5 from "lodash";
|
|
1067
|
+
function createConfigFactory(defaultConfig6, validate) {
|
|
1068
|
+
return (options = {}, existing) => {
|
|
1069
|
+
const result = _5.merge({}, defaultConfig6, existing, options);
|
|
1070
|
+
validate?.(result);
|
|
1071
|
+
return result;
|
|
1072
|
+
};
|
|
1073
|
+
}
|
|
1074
|
+
|
|
1075
|
+
// src/configs/tools.config.ts
|
|
1076
|
+
var globalToolsConfig = {
|
|
1077
|
+
devMode: false,
|
|
1078
|
+
embedColor: [],
|
|
1079
|
+
embedColorDev: [],
|
|
1080
|
+
timeouts: {
|
|
1081
|
+
collectorTimeout: 6e4,
|
|
1082
|
+
collectorIdle: 6e4,
|
|
1083
|
+
pagination: 6e4,
|
|
1084
|
+
prompt: 3e4,
|
|
1085
|
+
modalSubmit: 6e4
|
|
841
1086
|
},
|
|
842
1087
|
collector: {
|
|
843
1088
|
notAParticipantMessage: "You are not allowed to use this.",
|
|
@@ -863,103 +1108,10 @@ var globalToolsConfig = {
|
|
|
863
1108
|
rejectLabel: "Cancel"
|
|
864
1109
|
}
|
|
865
1110
|
};
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
function createToolsConfig(options) {
|
|
870
|
-
return _5.merge(globalToolsConfig, options);
|
|
871
|
-
}
|
|
872
|
-
|
|
873
|
-
// src/configs/app.config.ts
|
|
874
|
-
import _6 from "lodash";
|
|
875
|
-
var defaultConfig = {
|
|
876
|
-
devMode: process.argv.includes("--dev"),
|
|
877
|
-
name: "Discord Bot",
|
|
878
|
-
appVersion: "1.0.0",
|
|
879
|
-
verbose: false,
|
|
880
|
-
disableBanner: false,
|
|
881
|
-
moduleSuffixes: {
|
|
882
|
-
slashCommand: "slash",
|
|
883
|
-
contextCommand: "ctx",
|
|
884
|
-
prefixCommand: "prefix",
|
|
885
|
-
event: "event"
|
|
886
|
-
}
|
|
887
|
-
};
|
|
888
|
-
function createAppConfig(options = {}) {
|
|
889
|
-
return _6.merge(defaultConfig, options);
|
|
890
|
-
}
|
|
891
|
-
|
|
892
|
-
// src/configs/staff.config.ts
|
|
893
|
-
import _7 from "lodash";
|
|
894
|
-
var defaultConfig2 = {
|
|
895
|
-
ownerId: null,
|
|
896
|
-
superUsers: [],
|
|
897
|
-
superUserRoles: [],
|
|
898
|
-
bypassers: [],
|
|
899
|
-
bypassesGuildAdmin: {
|
|
900
|
-
allBotStaff: false,
|
|
901
|
-
botOwner: false,
|
|
902
|
-
superUsers: false,
|
|
903
|
-
bypassers: false
|
|
904
|
-
},
|
|
905
|
-
guild: {
|
|
906
|
-
id: null,
|
|
907
|
-
inviteUrl: null,
|
|
908
|
-
channels: {}
|
|
909
|
-
}
|
|
910
|
-
};
|
|
911
|
-
function createStaffConfig(options = {}) {
|
|
912
|
-
return _7.merge(defaultConfig2, options);
|
|
913
|
-
}
|
|
914
|
-
|
|
915
|
-
// src/configs/slashCommand.config.ts
|
|
916
|
-
import _8 from "lodash";
|
|
917
|
-
var defaultConfig3 = {
|
|
918
|
-
logExecution: true
|
|
919
|
-
};
|
|
920
|
-
function createSlashCommandConfig(options = {}) {
|
|
921
|
-
return _8.merge(defaultConfig3, options);
|
|
922
|
-
}
|
|
923
|
-
|
|
924
|
-
// src/configs/prefixCommand.config.ts
|
|
925
|
-
import _9 from "lodash";
|
|
926
|
-
var defaultConfig4 = {
|
|
927
|
-
enabled: true,
|
|
928
|
-
defaultPrefix: "!",
|
|
929
|
-
allowMentionAsPrefix: true,
|
|
930
|
-
allowCaseInsensitiveCommandNames: true,
|
|
931
|
-
logExecution: true
|
|
932
|
-
};
|
|
933
|
-
function createPrefixCommandConfig(options = {}) {
|
|
934
|
-
return _9.merge(defaultConfig4, options);
|
|
935
|
-
}
|
|
936
|
-
|
|
937
|
-
// src/configs/contextCommand.config.ts
|
|
938
|
-
import _10 from "lodash";
|
|
939
|
-
var defaultConfig5 = {
|
|
940
|
-
enabled: true,
|
|
941
|
-
logExecution: true
|
|
1111
|
+
var createToolsConfig = createConfigFactory(globalToolsConfig);
|
|
1112
|
+
var defineGlobalToolsConfig = (options) => {
|
|
1113
|
+
Object.assign(globalToolsConfig, createToolsConfig(options, globalToolsConfig));
|
|
942
1114
|
};
|
|
943
|
-
function createContextCommandConfig(options = {}) {
|
|
944
|
-
return _10.merge(defaultConfig5, options);
|
|
945
|
-
}
|
|
946
|
-
|
|
947
|
-
// src/utils/sendCommandErrorEmbed.ts
|
|
948
|
-
import {
|
|
949
|
-
ActionRowBuilder as ActionRowBuilder2,
|
|
950
|
-
AttachmentBuilder,
|
|
951
|
-
ButtonBuilder,
|
|
952
|
-
ButtonStyle,
|
|
953
|
-
ComponentType,
|
|
954
|
-
Message as Message3
|
|
955
|
-
} from "discord.js";
|
|
956
|
-
|
|
957
|
-
// src/tools/BetterEmbed.ts
|
|
958
|
-
import {
|
|
959
|
-
EmbedBuilder,
|
|
960
|
-
GuildMember as GuildMember3,
|
|
961
|
-
User as User3
|
|
962
|
-
} from "discord.js";
|
|
963
1115
|
|
|
964
1116
|
// src/tools/dynaSend.ts
|
|
965
1117
|
import {
|
|
@@ -1415,7 +1567,15 @@ var BetterEmbed = class _BetterEmbed {
|
|
|
1415
1567
|
}
|
|
1416
1568
|
};
|
|
1417
1569
|
|
|
1418
|
-
// src/utils/
|
|
1570
|
+
// src/utils/command-error.utils.ts
|
|
1571
|
+
import {
|
|
1572
|
+
ActionRowBuilder as ActionRowBuilder2,
|
|
1573
|
+
AttachmentBuilder,
|
|
1574
|
+
ButtonBuilder,
|
|
1575
|
+
ButtonStyle,
|
|
1576
|
+
ComponentType,
|
|
1577
|
+
Message as Message3
|
|
1578
|
+
} from "discord.js";
|
|
1419
1579
|
async function sendCommandErrorEmbed(client, error, guild, messageOrInteraction) {
|
|
1420
1580
|
if (!client.features.enableCommandErrorMessage) return null;
|
|
1421
1581
|
const config = typeof client.features.enableCommandErrorMessage !== "boolean" ? client.features.enableCommandErrorMessage : void 0;
|
|
@@ -1440,7 +1600,8 @@ async function sendCommandErrorEmbed(client, error, guild, messageOrInteraction)
|
|
|
1440
1600
|
title: "Something went wrong",
|
|
1441
1601
|
description: "If you keep encountering this error, please report it."
|
|
1442
1602
|
});
|
|
1443
|
-
const msg = await
|
|
1603
|
+
const msg = await dynaSend(messageOrInteraction, {
|
|
1604
|
+
embeds: [embed_error],
|
|
1444
1605
|
components: [actionRow],
|
|
1445
1606
|
flags: config?.ephemeral ? "Ephemeral" : void 0,
|
|
1446
1607
|
deleteAfter: config?.deleteAfter
|
|
@@ -1461,7 +1622,8 @@ ${error.stack}`), {
|
|
|
1461
1622
|
});
|
|
1462
1623
|
collector.on("end", () => {
|
|
1463
1624
|
buttons.details.setDisabled(true);
|
|
1464
|
-
|
|
1625
|
+
dynaSend(messageOrInteraction, {
|
|
1626
|
+
embeds: [embed_error],
|
|
1465
1627
|
sendMethod: messageOrInteraction instanceof Message3 ? 5 /* MessageEdit */ : void 0,
|
|
1466
1628
|
components: [actionRow]
|
|
1467
1629
|
});
|
|
@@ -1469,529 +1631,326 @@ ${error.stack}`), {
|
|
|
1469
1631
|
return msg;
|
|
1470
1632
|
}
|
|
1471
1633
|
|
|
1472
|
-
// src/
|
|
1473
|
-
var
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
if (!interaction.isChatInputCommand()) return;
|
|
1478
|
-
const command = client.commands.slash.get(interaction.commandName);
|
|
1479
|
-
if (!command) {
|
|
1480
|
-
const content = `**/\`${interaction.commandName}\`** is not a registered command.`;
|
|
1481
|
-
if (interaction.replied || interaction.deferred) {
|
|
1482
|
-
return interaction.followUp({ content, flags: "Ephemeral" });
|
|
1483
|
-
}
|
|
1484
|
-
return interaction.reply({ content, flags: "Ephemeral" });
|
|
1485
|
-
}
|
|
1486
|
-
try {
|
|
1487
|
-
return await command.run(client, client, interaction);
|
|
1488
|
-
} catch (err) {
|
|
1489
|
-
await sendCommandErrorEmbed(client, err, interaction.guild, interaction);
|
|
1490
|
-
throw err;
|
|
1491
|
-
}
|
|
1634
|
+
// src/client/error-handler.ts
|
|
1635
|
+
var ErrorHandler = class {
|
|
1636
|
+
client;
|
|
1637
|
+
constructor(client) {
|
|
1638
|
+
this.client = client;
|
|
1492
1639
|
}
|
|
1493
|
-
|
|
1640
|
+
/** Handles command errors - sends error embed to user, then rethrows. */
|
|
1641
|
+
async handleCommandError(error, guild, messageOrInteraction) {
|
|
1642
|
+
await sendCommandErrorEmbed(this.client, error, guild, messageOrInteraction);
|
|
1643
|
+
throw error;
|
|
1644
|
+
}
|
|
1645
|
+
/** Handles internal Vimcord errors - logs with [Vimcord] prefix. */
|
|
1646
|
+
handleVimcordError(error, context) {
|
|
1647
|
+
this.client.logger.error(`[Vimcord] [${context}]`, error);
|
|
1648
|
+
}
|
|
1649
|
+
/** Sets up global process error handlers. */
|
|
1650
|
+
setupGlobalHandlers() {
|
|
1651
|
+
process.on("uncaughtException", (err) => this.handleVimcordError(err, "Uncaught Exception"));
|
|
1652
|
+
process.on("unhandledRejection", (err) => this.handleVimcordError(err, "Unhandled Rejection"));
|
|
1653
|
+
process.on("exit", (code) => this.client.logger.debug(`Process exited with code ${code}`));
|
|
1654
|
+
this.client.on("error", (err) => this.handleVimcordError(err, "Client Error"));
|
|
1655
|
+
this.client.on("shardError", (err) => this.handleVimcordError(err, "Client Shard Error"));
|
|
1656
|
+
}
|
|
1657
|
+
};
|
|
1494
1658
|
|
|
1495
|
-
// src/
|
|
1496
|
-
import
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
if (config.
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1659
|
+
// src/client/vimcord.logger.ts
|
|
1660
|
+
import chalk2 from "chalk";
|
|
1661
|
+
|
|
1662
|
+
// package.json
|
|
1663
|
+
var version = "1.0.37";
|
|
1664
|
+
|
|
1665
|
+
// src/client/vimcord.logger.ts
|
|
1666
|
+
var clientLoggerFactory = (client) => new Logger({ prefixEmoji: "\u26A1", prefix: `vimcord (i${client.clientId})` }).extend({
|
|
1667
|
+
clientBanner(client2) {
|
|
1668
|
+
if (client2.config.app.disableBanner) return;
|
|
1669
|
+
const border = "\u2550".repeat(50);
|
|
1670
|
+
console.log(chalk2.hex(this.colors.primary)(`
|
|
1671
|
+
\u2554${border}\u2557`));
|
|
1672
|
+
console.log(
|
|
1673
|
+
chalk2.hex(this.colors.primary)("\u2551") + chalk2.bold.hex(this.colors.text)(
|
|
1674
|
+
` \u{1F680} ${client2.config.app.name} v${client2.$version}`.padEnd(50 - (client2.$devMode ? 12 : 0))
|
|
1675
|
+
) + chalk2.hex(this.colors.primary)(`${client2.$devMode ? chalk2.hex(this.colors.warn)("devMode \u26A0\uFE0F ") : ""}\u2551`)
|
|
1676
|
+
);
|
|
1677
|
+
console.log(chalk2.hex(this.colors.primary)(`\u2551${"".padEnd(50)}\u2551`));
|
|
1678
|
+
console.log(
|
|
1679
|
+
chalk2.hex(this.colors.primary)("\u2551") + chalk2.hex(this.colors.muted)(
|
|
1680
|
+
` # Powered by Vimcord v${version}`.padEnd(50 - 3 - `${client2.clientId}`.length)
|
|
1681
|
+
) + chalk2.hex(this.colors.primary)(`${chalk2.hex(this.colors.muted)(`i${client2.clientId}`)} \u2551`)
|
|
1682
|
+
);
|
|
1683
|
+
console.log(chalk2.hex(this.colors.primary)(`\u255A${border}\u255D
|
|
1684
|
+
`));
|
|
1685
|
+
},
|
|
1686
|
+
clientReady(clientTag, guildCount) {
|
|
1687
|
+
console.log(
|
|
1688
|
+
this.formatTimestamp(),
|
|
1689
|
+
this.formatPrefix(),
|
|
1690
|
+
chalk2.hex(this.colors.success)("\u{1F916} READY"),
|
|
1691
|
+
chalk2.white(`Connected as ${chalk2.bold.hex(this.colors.primary)(clientTag)}`),
|
|
1692
|
+
chalk2.hex(this.colors.muted)(`\u2022 ${guildCount} guilds`)
|
|
1693
|
+
);
|
|
1694
|
+
},
|
|
1695
|
+
moduleLoaded(moduleName, count, ignoredCount) {
|
|
1696
|
+
const countText = count ? chalk2.hex(this.colors.muted)(`(${count} items)`) : "";
|
|
1697
|
+
console.log(
|
|
1698
|
+
this.formatTimestamp(),
|
|
1699
|
+
this.formatPrefix(),
|
|
1700
|
+
chalk2.hex("#9B59B6")("\u{1F4E6} MODULE"),
|
|
1701
|
+
chalk2.hex(this.colors.warn)(`${moduleName} loaded`),
|
|
1702
|
+
ignoredCount ? chalk2.hex(this.colors.muted)(`(${ignoredCount} ignored)`) : "",
|
|
1703
|
+
countText
|
|
1704
|
+
);
|
|
1705
|
+
},
|
|
1706
|
+
commandExecuted(commandName, username, guildName) {
|
|
1707
|
+
const location = guildName ? `in ${chalk2.hex(this.colors.muted)(guildName)}` : "in DMs";
|
|
1708
|
+
console.log(
|
|
1709
|
+
this.formatTimestamp(),
|
|
1710
|
+
this.formatPrefix(),
|
|
1711
|
+
chalk2.hex("#87CEEB")("\u{1F4DD} COMMAND"),
|
|
1712
|
+
chalk2.hex(this.colors.warn)(`/${commandName}`),
|
|
1713
|
+
chalk2.white(`used by ${chalk2.bold(username)}`),
|
|
1714
|
+
chalk2.hex(this.colors.muted)(location)
|
|
1715
|
+
);
|
|
1716
|
+
},
|
|
1717
|
+
database(action, details) {
|
|
1718
|
+
console.log(
|
|
1719
|
+
this.formatTimestamp(),
|
|
1720
|
+
this.formatPrefix(),
|
|
1721
|
+
chalk2.hex("#FF6B9D")("\u{1F5C4}\uFE0F DATABASE"),
|
|
1722
|
+
chalk2.white(action),
|
|
1723
|
+
details ? chalk2.hex(this.colors.muted)(details) : ""
|
|
1724
|
+
);
|
|
1535
1725
|
}
|
|
1536
1726
|
});
|
|
1537
1727
|
|
|
1538
|
-
// src/
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1728
|
+
// src/utils/process.utils.ts
|
|
1729
|
+
import { readFileSync } from "fs";
|
|
1730
|
+
import { join } from "path";
|
|
1731
|
+
function getPackageJson() {
|
|
1732
|
+
return JSON.parse(readFileSync(join(process.cwd(), "package.json"), "utf-8"));
|
|
1733
|
+
}
|
|
1734
|
+
function getDevMode() {
|
|
1735
|
+
return process.argv.includes("--dev");
|
|
1736
|
+
}
|
|
1737
|
+
|
|
1738
|
+
// src/configs/app.config.ts
|
|
1739
|
+
var defaultConfig = {
|
|
1740
|
+
name: "Discord Bot",
|
|
1741
|
+
version: getPackageJson()?.version ?? "1.0.0",
|
|
1742
|
+
devMode: getDevMode(),
|
|
1743
|
+
verbose: false,
|
|
1744
|
+
enableCLI: false,
|
|
1745
|
+
disableBanner: false
|
|
1746
|
+
};
|
|
1747
|
+
var createAppConfig = createConfigFactory(defaultConfig, (config) => {
|
|
1748
|
+
if (!config.name) throw new Error("App name is required");
|
|
1749
|
+
defineGlobalToolsConfig({ devMode: config.devMode });
|
|
1559
1750
|
});
|
|
1560
1751
|
|
|
1561
|
-
// src/
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
LogLevel2[LogLevel2["INFO"] = 1] = "INFO";
|
|
1566
|
-
LogLevel2[LogLevel2["SUCCESS"] = 2] = "SUCCESS";
|
|
1567
|
-
LogLevel2[LogLevel2["WARN"] = 3] = "WARN";
|
|
1568
|
-
LogLevel2[LogLevel2["ERROR"] = 4] = "ERROR";
|
|
1569
|
-
return LogLevel2;
|
|
1570
|
-
})(LogLevel || {});
|
|
1571
|
-
var LOGGER_COLORS = {
|
|
1572
|
-
primary: "#5865F2",
|
|
1573
|
-
success: "#57F287",
|
|
1574
|
-
warn: "#FEE75C",
|
|
1575
|
-
danger: "#ED4245",
|
|
1576
|
-
muted: "#747F8D",
|
|
1577
|
-
text: "#FFFFFF"
|
|
1752
|
+
// src/configs/contextCommand.config.ts
|
|
1753
|
+
var defaultConfig2 = {
|
|
1754
|
+
enabled: true,
|
|
1755
|
+
logExecution: true
|
|
1578
1756
|
};
|
|
1579
|
-
var
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
this.logPrefix = prefix;
|
|
1589
|
-
this.minLevel = minLevel;
|
|
1590
|
-
this.showTimestamp = showTimestamp;
|
|
1591
|
-
this.colorScheme = {
|
|
1592
|
-
...LOGGER_COLORS,
|
|
1593
|
-
...options?.colors
|
|
1594
|
-
};
|
|
1595
|
-
}
|
|
1596
|
-
formatTimestamp() {
|
|
1597
|
-
if (!this.showTimestamp) return "";
|
|
1598
|
-
const now = /* @__PURE__ */ new Date();
|
|
1599
|
-
const time = now.toLocaleTimeString("en-US", {
|
|
1600
|
-
hour12: false,
|
|
1601
|
-
hour: "2-digit",
|
|
1602
|
-
minute: "2-digit",
|
|
1603
|
-
second: "2-digit"
|
|
1604
|
-
});
|
|
1605
|
-
return chalk.hex(this.colorScheme.muted)(`[${time}]`);
|
|
1606
|
-
}
|
|
1607
|
-
formatPrefix() {
|
|
1608
|
-
if (!this.logPrefix) return "";
|
|
1609
|
-
return chalk.bold.hex(this.colorScheme.primary)(
|
|
1610
|
-
`${this.logPrefixEmoji ? `${this.logPrefixEmoji} ` : ""}${this.logPrefix}`
|
|
1611
|
-
);
|
|
1612
|
-
}
|
|
1613
|
-
shouldLog(level) {
|
|
1614
|
-
return level >= this.minLevel;
|
|
1615
|
-
}
|
|
1616
|
-
get prefixEmoji() {
|
|
1617
|
-
return this.logPrefixEmoji;
|
|
1618
|
-
}
|
|
1619
|
-
get prefix() {
|
|
1620
|
-
return this.logPrefix;
|
|
1621
|
-
}
|
|
1622
|
-
get colors() {
|
|
1623
|
-
return this.colorScheme;
|
|
1624
|
-
}
|
|
1625
|
-
extend(extras) {
|
|
1626
|
-
for (const [key, fn] of Object.entries(extras)) {
|
|
1627
|
-
if (typeof fn === "function") {
|
|
1628
|
-
this[key] = function(...args) {
|
|
1629
|
-
return fn.call(this, ...args);
|
|
1630
|
-
};
|
|
1631
|
-
}
|
|
1632
|
-
}
|
|
1633
|
-
return this;
|
|
1634
|
-
}
|
|
1635
|
-
setPrefix(prefix) {
|
|
1636
|
-
this.logPrefix = prefix;
|
|
1637
|
-
return this;
|
|
1638
|
-
}
|
|
1639
|
-
setPrefixEmoji(prefixEmoji) {
|
|
1640
|
-
this.logPrefixEmoji = prefixEmoji;
|
|
1641
|
-
return this;
|
|
1642
|
-
}
|
|
1643
|
-
setMinLevel(minLevel) {
|
|
1644
|
-
this.minLevel = minLevel;
|
|
1645
|
-
return this;
|
|
1646
|
-
}
|
|
1647
|
-
setShowTimestamp(show) {
|
|
1648
|
-
this.showTimestamp = show;
|
|
1649
|
-
return this;
|
|
1650
|
-
}
|
|
1651
|
-
setColors(colors) {
|
|
1652
|
-
this.colorScheme = {
|
|
1653
|
-
...LOGGER_COLORS,
|
|
1654
|
-
...colors
|
|
1655
|
-
};
|
|
1656
|
-
return this;
|
|
1657
|
-
}
|
|
1658
|
-
log(message, ...args) {
|
|
1659
|
-
console.log(this.formatTimestamp(), this.formatPrefix(), message, ...args);
|
|
1660
|
-
}
|
|
1661
|
-
debug(message, ...args) {
|
|
1662
|
-
if (!this.shouldLog(0 /* DEBUG */)) return;
|
|
1663
|
-
console.log(
|
|
1664
|
-
this.formatTimestamp(),
|
|
1665
|
-
this.formatPrefix(),
|
|
1666
|
-
chalk.hex(this.colorScheme.muted)("DEBUG"),
|
|
1667
|
-
chalk.dim(message),
|
|
1668
|
-
...args
|
|
1669
|
-
);
|
|
1670
|
-
}
|
|
1671
|
-
info(message, ...args) {
|
|
1672
|
-
if (!this.shouldLog(1 /* INFO */)) return;
|
|
1673
|
-
console.log(this.formatTimestamp(), this.formatPrefix(), chalk.hex("#87CEEB")("INFO"), message, ...args);
|
|
1674
|
-
}
|
|
1675
|
-
success(message, ...args) {
|
|
1676
|
-
if (!this.shouldLog(2 /* SUCCESS */)) return;
|
|
1677
|
-
console.log(
|
|
1678
|
-
this.formatTimestamp(),
|
|
1679
|
-
this.formatPrefix(),
|
|
1680
|
-
chalk.bold.hex(this.colorScheme.success)("\u2713 SUCCESS"),
|
|
1681
|
-
chalk.hex(this.colorScheme.success)(message),
|
|
1682
|
-
...args
|
|
1683
|
-
);
|
|
1684
|
-
}
|
|
1685
|
-
warn(message, ...args) {
|
|
1686
|
-
if (!this.shouldLog(3 /* WARN */)) return;
|
|
1687
|
-
console.warn(
|
|
1688
|
-
this.formatTimestamp(),
|
|
1689
|
-
this.formatPrefix(),
|
|
1690
|
-
chalk.bold.hex(this.colorScheme.warn)("\u26A0 WARN"),
|
|
1691
|
-
chalk.hex(this.colorScheme.warn)(message),
|
|
1692
|
-
...args
|
|
1693
|
-
);
|
|
1694
|
-
}
|
|
1695
|
-
error(message, error, ...args) {
|
|
1696
|
-
if (!this.shouldLog(4 /* ERROR */)) return;
|
|
1697
|
-
console.error(
|
|
1698
|
-
this.formatTimestamp(),
|
|
1699
|
-
this.formatPrefix(),
|
|
1700
|
-
chalk.bold.hex(this.colorScheme.danger)("\u2715 ERROR"),
|
|
1701
|
-
chalk.hex(this.colorScheme.danger)(message),
|
|
1702
|
-
...args
|
|
1703
|
-
);
|
|
1704
|
-
if (error && error.stack) {
|
|
1705
|
-
console.error(chalk.dim(error.stack));
|
|
1706
|
-
}
|
|
1707
|
-
}
|
|
1708
|
-
loader(message) {
|
|
1709
|
-
const frames = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
1710
|
-
let i = 0;
|
|
1711
|
-
const interval = setInterval(() => {
|
|
1712
|
-
process.stdout.write(
|
|
1713
|
-
`\r${this.formatTimestamp()} ${this.formatPrefix()} ${chalk.hex(this.colorScheme.warn)(frames[i])} ${message}`
|
|
1714
|
-
);
|
|
1715
|
-
i = (i + 1) % frames.length;
|
|
1716
|
-
}, 100);
|
|
1717
|
-
return (newMessage) => {
|
|
1718
|
-
clearInterval(interval);
|
|
1719
|
-
process.stdout.write(
|
|
1720
|
-
`\r${this.formatTimestamp()} ${this.formatPrefix()} ${chalk.hex(this.colorScheme.success)("\u2713")} ${newMessage || message}
|
|
1721
|
-
`
|
|
1722
|
-
);
|
|
1723
|
-
};
|
|
1724
|
-
}
|
|
1725
|
-
table(title, data) {
|
|
1726
|
-
console.log(this.formatTimestamp(), this.formatPrefix(), chalk.bold(title));
|
|
1727
|
-
Object.entries(data).forEach(([key, value]) => {
|
|
1728
|
-
const formattedKey = chalk.hex(this.colorScheme.warn)(` ${key}`);
|
|
1729
|
-
const formattedValue = chalk.hex(this.colorScheme.muted)(value);
|
|
1730
|
-
console.log(`${formattedKey.padEnd(25)} ${formattedValue}`);
|
|
1731
|
-
});
|
|
1732
|
-
}
|
|
1733
|
-
section(title) {
|
|
1734
|
-
const line = "\u2500".repeat(Math.max(30, title.length + 4));
|
|
1735
|
-
console.log(chalk.hex(this.colorScheme.muted)(`
|
|
1736
|
-
\u250C\u2500${line}\u2500\u2510`));
|
|
1737
|
-
console.log(
|
|
1738
|
-
chalk.hex(this.colorScheme.muted)("\u2502 ") + chalk.bold.hex(this.colorScheme.text)(title.padEnd(line.length)) + chalk.hex(this.colorScheme.muted)(" \u2502")
|
|
1739
|
-
);
|
|
1740
|
-
console.log(chalk.hex(this.colorScheme.muted)(`\u2514\u2500${line}\u2500\u2518`));
|
|
1741
|
-
}
|
|
1757
|
+
var createContextCommandConfig = createConfigFactory(defaultConfig2);
|
|
1758
|
+
|
|
1759
|
+
// src/configs/prefixCommand.config.ts
|
|
1760
|
+
var defaultConfig3 = {
|
|
1761
|
+
enabled: true,
|
|
1762
|
+
defaultPrefix: "!",
|
|
1763
|
+
allowMentionAsPrefix: true,
|
|
1764
|
+
allowCaseInsensitiveCommandNames: true,
|
|
1765
|
+
logExecution: true
|
|
1742
1766
|
};
|
|
1743
|
-
var
|
|
1767
|
+
var createPrefixCommandConfig = createConfigFactory(defaultConfig3);
|
|
1744
1768
|
|
|
1745
|
-
// src/
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
}
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
if (!message.guild) return null;
|
|
1768
|
-
const member = await fetchMember(message.guild, message.mentions.users.at(index)?.id ?? arg);
|
|
1769
|
-
return idOnly ? member?.id || null : member;
|
|
1770
|
-
case "channel":
|
|
1771
|
-
const channelMention = message.mentions.channels.at(index) || null;
|
|
1772
|
-
if (!channelMention && arg) {
|
|
1773
|
-
return idOnly ? arg : message.guild ? await fetchChannel(message.guild, arg) : message.client.channels.cache.get(__zero(arg)) ?? message.client.channels.fetch(__zero(arg));
|
|
1774
|
-
} else {
|
|
1775
|
-
return idOnly ? channelMention?.id || null : channelMention;
|
|
1776
|
-
}
|
|
1777
|
-
case "role":
|
|
1778
|
-
const roleMention = message.mentions.roles.at(index) || null;
|
|
1779
|
-
if (!roleMention && arg) {
|
|
1780
|
-
return idOnly ? arg : message.guild ? await fetchRole(message.guild, arg) : null;
|
|
1781
|
-
} else {
|
|
1782
|
-
return idOnly ? roleMention?.id || null : roleMention;
|
|
1783
|
-
}
|
|
1784
|
-
default:
|
|
1785
|
-
return null;
|
|
1786
|
-
}
|
|
1787
|
-
}
|
|
1788
|
-
function getFirstMentionId(options) {
|
|
1789
|
-
let mentionId = "";
|
|
1790
|
-
if (options.message) {
|
|
1791
|
-
switch (options.type) {
|
|
1792
|
-
case "user":
|
|
1793
|
-
mentionId = options.message.mentions.users.first()?.id || "";
|
|
1794
|
-
break;
|
|
1795
|
-
case "channel":
|
|
1796
|
-
mentionId = options.message.mentions.channels.first()?.id || "";
|
|
1797
|
-
break;
|
|
1798
|
-
case "role":
|
|
1799
|
-
mentionId = options.message.mentions.roles.first()?.id || "";
|
|
1800
|
-
break;
|
|
1801
|
-
}
|
|
1769
|
+
// src/configs/slashCommand.config.ts
|
|
1770
|
+
var defaultConfig4 = {
|
|
1771
|
+
logExecution: true
|
|
1772
|
+
};
|
|
1773
|
+
var createSlashCommandConfig = createConfigFactory(defaultConfig4);
|
|
1774
|
+
|
|
1775
|
+
// src/configs/staff.config.ts
|
|
1776
|
+
var defaultConfig5 = {
|
|
1777
|
+
ownerId: null,
|
|
1778
|
+
superUsers: [],
|
|
1779
|
+
superUserRoles: [],
|
|
1780
|
+
bypassers: [],
|
|
1781
|
+
bypassesGuildAdmin: {
|
|
1782
|
+
allBotStaff: false,
|
|
1783
|
+
botOwner: false,
|
|
1784
|
+
superUsers: false,
|
|
1785
|
+
bypassers: false
|
|
1786
|
+
},
|
|
1787
|
+
guild: {
|
|
1788
|
+
id: null,
|
|
1789
|
+
inviteUrl: null,
|
|
1790
|
+
channels: {}
|
|
1802
1791
|
}
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
}
|
|
1806
|
-
async function fetchUser(client, userId) {
|
|
1807
|
-
if (!userId) return null;
|
|
1808
|
-
return client.users.cache.get(__zero(userId)) || await client.users.fetch(__zero(userId)).catch(() => null);
|
|
1809
|
-
}
|
|
1810
|
-
async function fetchGuild(client, guildId) {
|
|
1811
|
-
if (!guildId) return null;
|
|
1812
|
-
return client.guilds.cache.get(__zero(guildId)) || await client.guilds.fetch(__zero(guildId)).catch(() => null);
|
|
1813
|
-
}
|
|
1814
|
-
async function fetchMember(guild, memberId) {
|
|
1815
|
-
if (!memberId) return null;
|
|
1816
|
-
return guild.members.cache.get(__zero(memberId)) || await guild.members.fetch(__zero(memberId)).catch(() => null);
|
|
1817
|
-
}
|
|
1818
|
-
async function fetchChannel(guild, channelId, type) {
|
|
1819
|
-
if (!channelId) return null;
|
|
1820
|
-
const channel = guild.channels.cache.get(__zero(channelId)) || await guild.channels.fetch(__zero(channelId)).catch(() => null);
|
|
1821
|
-
if (type && channel?.type !== type) return null;
|
|
1822
|
-
return channel;
|
|
1823
|
-
}
|
|
1824
|
-
async function fetchRole(guild, roleId) {
|
|
1825
|
-
if (!roleId) return null;
|
|
1826
|
-
return guild.roles.cache.get(__zero(roleId)) || await guild.roles.fetch(__zero(roleId)).catch(() => null) || null;
|
|
1827
|
-
}
|
|
1828
|
-
async function fetchMessage(channel, messageId) {
|
|
1829
|
-
if (!messageId) return null;
|
|
1830
|
-
return channel.messages.cache.get(__zero(messageId)) || await channel.messages.fetch(__zero(messageId)).catch(() => null) || null;
|
|
1831
|
-
}
|
|
1792
|
+
};
|
|
1793
|
+
var createStaffConfig = createConfigFactory(defaultConfig5);
|
|
1832
1794
|
|
|
1833
|
-
// src/
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1795
|
+
// src/client/vimcord.utils.ts
|
|
1796
|
+
var DEFAULT_MODULE_SUFFIXES = {
|
|
1797
|
+
slashCommands: ".slash",
|
|
1798
|
+
contextCommands: ".ctx",
|
|
1799
|
+
prefixCommands: ".prefix",
|
|
1800
|
+
events: ".event"
|
|
1801
|
+
};
|
|
1802
|
+
var configSetters = {
|
|
1803
|
+
app: createAppConfig,
|
|
1804
|
+
staff: createStaffConfig,
|
|
1805
|
+
slashCommands: createSlashCommandConfig,
|
|
1806
|
+
prefixCommands: createPrefixCommandConfig,
|
|
1807
|
+
contextCommands: createContextCommandConfig
|
|
1808
|
+
};
|
|
1809
|
+
var moduleImporters = {
|
|
1810
|
+
slashCommands: (client, options, set) => {
|
|
1811
|
+
const opt = options;
|
|
1812
|
+
const dir = Array.isArray(options) ? options : opt?.dir ?? [];
|
|
1813
|
+
const suffix = Array.isArray(options) ? DEFAULT_MODULE_SUFFIXES.slashCommands : opt?.suffix ?? DEFAULT_MODULE_SUFFIXES.slashCommands;
|
|
1814
|
+
return client.commands.slash.importFrom(dir, set, suffix);
|
|
1852
1815
|
},
|
|
1853
|
-
|
|
1854
|
-
|
|
1816
|
+
contextCommands: (client, options, set) => {
|
|
1817
|
+
const opt = options;
|
|
1818
|
+
const dir = Array.isArray(options) ? options : opt?.dir ?? [];
|
|
1819
|
+
const suffix = Array.isArray(options) ? DEFAULT_MODULE_SUFFIXES.contextCommands : opt?.suffix ?? DEFAULT_MODULE_SUFFIXES.contextCommands;
|
|
1820
|
+
return client.commands.context.importFrom(dir, set, suffix);
|
|
1821
|
+
},
|
|
1822
|
+
prefixCommands: (client, options, set) => {
|
|
1823
|
+
const opt = options;
|
|
1824
|
+
const dir = Array.isArray(options) ? options : opt?.dir ?? [];
|
|
1825
|
+
const suffix = Array.isArray(options) ? DEFAULT_MODULE_SUFFIXES.prefixCommands : opt?.suffix ?? DEFAULT_MODULE_SUFFIXES.prefixCommands;
|
|
1826
|
+
return client.commands.prefix.importFrom(dir, set, suffix);
|
|
1827
|
+
},
|
|
1828
|
+
events: (client, options, set) => {
|
|
1829
|
+
const opt = options;
|
|
1830
|
+
const dir = Array.isArray(options) ? options : opt?.dir ?? [];
|
|
1831
|
+
const suffix = Array.isArray(options) ? DEFAULT_MODULE_SUFFIXES.events : opt?.suffix ?? DEFAULT_MODULE_SUFFIXES.events;
|
|
1832
|
+
return client.events.importFrom(dir, set, suffix);
|
|
1855
1833
|
}
|
|
1856
1834
|
};
|
|
1857
|
-
function
|
|
1858
|
-
return
|
|
1835
|
+
function defineClientOptions(options) {
|
|
1836
|
+
return options;
|
|
1859
1837
|
}
|
|
1838
|
+
function defineVimcordFeatures(features) {
|
|
1839
|
+
return features;
|
|
1840
|
+
}
|
|
1841
|
+
function defineVimcordConfig(config) {
|
|
1842
|
+
return {
|
|
1843
|
+
app: createAppConfig(config.app),
|
|
1844
|
+
staff: createStaffConfig(config.staff),
|
|
1845
|
+
slashCommands: createSlashCommandConfig(config.slashCommands),
|
|
1846
|
+
prefixCommands: createPrefixCommandConfig(config.prefixCommands),
|
|
1847
|
+
contextCommands: createContextCommandConfig(config.contextCommands)
|
|
1848
|
+
};
|
|
1849
|
+
}
|
|
1850
|
+
var useClient = Vimcord.getInstance;
|
|
1851
|
+
var useReadyClient = Vimcord.getReadyInstance;
|
|
1852
|
+
var createClient = Vimcord.create;
|
|
1860
1853
|
|
|
1861
|
-
// src/modules/
|
|
1862
|
-
import
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
this.emitter.on("cleared", () => {
|
|
1880
|
-
if (this.client.config.app.verbose) {
|
|
1881
|
-
this.logger.debug("Status cleared");
|
|
1882
|
-
}
|
|
1883
|
-
});
|
|
1884
|
-
}
|
|
1885
|
-
clearData() {
|
|
1886
|
-
this.task?.stop();
|
|
1887
|
-
this.task = null;
|
|
1888
|
-
this.lastActivity = null;
|
|
1889
|
-
this.lastActivityIndex = 0;
|
|
1890
|
-
return this;
|
|
1891
|
-
}
|
|
1892
|
-
async getReadyClient() {
|
|
1893
|
-
const client = await this.client.waitForReady();
|
|
1894
|
-
if (!client.user) throw new Error("Cannot manage the client's activity when its user is not hydrated");
|
|
1895
|
-
return client;
|
|
1896
|
-
}
|
|
1897
|
-
async formatActivityName(name) {
|
|
1898
|
-
name = name.replace("$USER_COUNT", $2.format.number(this.client.users.cache.size)).replace("$GUILD_COUNT", $2.format.number(this.client.guilds.cache.size)).replace(
|
|
1899
|
-
"$INVITE",
|
|
1900
|
-
this.client.config.staff.guild.inviteUrl ? this.client.config.staff.guild.inviteUrl : "<STAFF_INVITE_URL_NOT_SET>"
|
|
1901
|
-
);
|
|
1902
|
-
if (name.includes("$STAFF_GUILD_MEMBER_COUNT")) {
|
|
1903
|
-
await fetchGuild(this.client, this.client.config.staff.guild.id).then((guild) => {
|
|
1904
|
-
if (!guild) return name = name.replace("$STAFF_GUILD_MEMBER_COUNT", "<STAFF_GUILD_NOT_FOUND>");
|
|
1905
|
-
name = name.replace("$STAFF_GUILD_MEMBER_COUNT", $2.format.number(guild.members.cache.size));
|
|
1906
|
-
}).catch((err) => this.logger.error("Failed to fetch the staff guild", err));
|
|
1907
|
-
}
|
|
1908
|
-
return name;
|
|
1909
|
-
}
|
|
1910
|
-
async setActivity(activity) {
|
|
1911
|
-
const client = await this.getReadyClient();
|
|
1912
|
-
activity.name = await this.formatActivityName(activity.name);
|
|
1913
|
-
client.user.setStatus(activity.status);
|
|
1914
|
-
client.user.setActivity({ name: activity.name, type: activity.type, url: activity.streamUrl });
|
|
1915
|
-
this.emitter.emit("changed", activity);
|
|
1916
|
-
}
|
|
1917
|
-
async statusRotationTask(clientStatus) {
|
|
1918
|
-
let activity;
|
|
1919
|
-
if (clientStatus.randomize && Array.isArray(clientStatus.activity)) {
|
|
1920
|
-
activity = $2.rnd.choice(clientStatus.activity, { not: this.lastActivity });
|
|
1921
|
-
this.lastActivity = activity;
|
|
1922
|
-
} else {
|
|
1923
|
-
const activityIndex = (this.lastActivityIndex + 1) % clientStatus.activity.length;
|
|
1924
|
-
this.lastActivityIndex = activityIndex;
|
|
1925
|
-
activity = clientStatus.activity[activityIndex];
|
|
1926
|
-
}
|
|
1927
|
-
await this.setActivity(activity);
|
|
1928
|
-
this.emitter.emit("rotation", activity);
|
|
1929
|
-
}
|
|
1930
|
-
async scheduleStatusRotation(clientStatus) {
|
|
1931
|
-
if (!clientStatus.interval) throw new Error("Cannot create client activity interval without interval time");
|
|
1932
|
-
this.task?.stop();
|
|
1933
|
-
this.task = null;
|
|
1934
|
-
this.task = new $2.Loop(() => this.statusRotationTask(clientStatus), $2.math.ms(clientStatus.interval), true);
|
|
1935
|
-
this.start();
|
|
1936
|
-
}
|
|
1937
|
-
start() {
|
|
1938
|
-
if (this.task) {
|
|
1939
|
-
this.task.start();
|
|
1940
|
-
this.emitter.emit("started", this.task);
|
|
1941
|
-
}
|
|
1942
|
-
return this;
|
|
1854
|
+
// src/modules/command.manager.ts
|
|
1855
|
+
import { Routes } from "discord.js";
|
|
1856
|
+
|
|
1857
|
+
// src/utils/import.utils.ts
|
|
1858
|
+
import path from "path";
|
|
1859
|
+
import { $ } from "qznt";
|
|
1860
|
+
function getProcessDir() {
|
|
1861
|
+
const mainPath = process.argv[1];
|
|
1862
|
+
if (!mainPath) return "";
|
|
1863
|
+
return path.dirname(mainPath);
|
|
1864
|
+
}
|
|
1865
|
+
async function importModulesFromDir(dir, suffix) {
|
|
1866
|
+
const cwd = getProcessDir();
|
|
1867
|
+
const MODULE_RELATIVE_PATH = path.join(cwd, dir);
|
|
1868
|
+
const MODULE_LOG_PATH = dir;
|
|
1869
|
+
const files = $.fs.readDir(MODULE_RELATIVE_PATH).filter((fn) => fn.endsWith(`${suffix ? `.${suffix}` : ""}.js`) || fn.endsWith(`${suffix ? `.${suffix}` : ""}.ts`));
|
|
1870
|
+
if (!files.length) {
|
|
1871
|
+
return [];
|
|
1943
1872
|
}
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1873
|
+
const modules = await Promise.all(
|
|
1874
|
+
files.map(async (fn) => {
|
|
1875
|
+
let _path = path.join(MODULE_RELATIVE_PATH, fn);
|
|
1876
|
+
let _logPath = `./${path.join(MODULE_LOG_PATH, fn)}`;
|
|
1877
|
+
let _module;
|
|
1878
|
+
try {
|
|
1879
|
+
delete __require.cache[__require.resolve(_path)];
|
|
1880
|
+
_module = __require(_path);
|
|
1881
|
+
} catch (err) {
|
|
1882
|
+
console.warn(`Failed to import module at '${_logPath}'`, err);
|
|
1883
|
+
_module = null;
|
|
1884
|
+
}
|
|
1885
|
+
return { module: _module, path: _logPath };
|
|
1886
|
+
})
|
|
1887
|
+
);
|
|
1888
|
+
const filteredModules = modules.filter((m) => m.module);
|
|
1889
|
+
if (!filteredModules.length) {
|
|
1890
|
+
console.warn(`No valid modules were found in directory '${dir}'`);
|
|
1950
1891
|
}
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
if (!clientStatus.interval) {
|
|
1960
|
-
await this.setActivity(Array.isArray(clientStatus.activity) ? clientStatus.activity[0] : clientStatus.activity);
|
|
1961
|
-
} else {
|
|
1962
|
-
await this.scheduleStatusRotation(clientStatus);
|
|
1963
|
-
}
|
|
1964
|
-
return this;
|
|
1892
|
+
return filteredModules;
|
|
1893
|
+
}
|
|
1894
|
+
|
|
1895
|
+
// src/modules/base-module.importer.ts
|
|
1896
|
+
var ModuleImporter = class {
|
|
1897
|
+
client;
|
|
1898
|
+
constructor(client) {
|
|
1899
|
+
this.client = client;
|
|
1965
1900
|
}
|
|
1966
|
-
async
|
|
1967
|
-
if (this.
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1901
|
+
async importFrom(dir, set = false, suffix) {
|
|
1902
|
+
if (set) this.items.clear();
|
|
1903
|
+
const dirs = Array.isArray(dir) ? dir : [dir];
|
|
1904
|
+
const modules = [];
|
|
1905
|
+
const effectiveSuffix = Array.isArray(suffix) ? suffix[0] : suffix ?? this.itemSuffix;
|
|
1906
|
+
for (const _dir of dirs) {
|
|
1907
|
+
const results = await importModulesFromDir(_dir, effectiveSuffix ?? void 0);
|
|
1908
|
+
modules.push(...results.map(({ module }) => module.default));
|
|
1972
1909
|
}
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
this.
|
|
1978
|
-
|
|
1979
|
-
this.emitter.emit("cleared");
|
|
1980
|
-
return this;
|
|
1910
|
+
for (const module of modules) {
|
|
1911
|
+
const name = this.getName(module);
|
|
1912
|
+
this.items.set(name, module);
|
|
1913
|
+
}
|
|
1914
|
+
this.client.logger.moduleLoaded(this.itemName, modules.length);
|
|
1915
|
+
return this.items;
|
|
1981
1916
|
}
|
|
1982
1917
|
};
|
|
1983
1918
|
|
|
1984
1919
|
// src/modules/command.manager.ts
|
|
1985
|
-
|
|
1986
|
-
var BaseCommandManager = class {
|
|
1920
|
+
var BaseCommandManager = class extends ModuleImporter {
|
|
1987
1921
|
type;
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1922
|
+
items = /* @__PURE__ */ new Map();
|
|
1923
|
+
itemSuffix;
|
|
1924
|
+
constructor(client, type, itemSuffix) {
|
|
1925
|
+
super(client);
|
|
1992
1926
|
this.type = type;
|
|
1993
|
-
|
|
1994
|
-
|
|
1927
|
+
switch (type) {
|
|
1928
|
+
case 0 /* Slash */:
|
|
1929
|
+
this.itemSuffix = itemSuffix ?? DEFAULT_MODULE_SUFFIXES.slashCommands;
|
|
1930
|
+
break;
|
|
1931
|
+
case 2 /* Context */:
|
|
1932
|
+
this.itemSuffix = itemSuffix ?? DEFAULT_MODULE_SUFFIXES.contextCommands;
|
|
1933
|
+
break;
|
|
1934
|
+
case 1 /* Prefix */:
|
|
1935
|
+
this.itemSuffix = itemSuffix ?? DEFAULT_MODULE_SUFFIXES.prefixCommands;
|
|
1936
|
+
break;
|
|
1937
|
+
}
|
|
1938
|
+
}
|
|
1939
|
+
get commands() {
|
|
1940
|
+
return this.items;
|
|
1941
|
+
}
|
|
1942
|
+
get itemName() {
|
|
1943
|
+
switch (this.type) {
|
|
1944
|
+
case 0 /* Slash */:
|
|
1945
|
+
return "Slash Commands";
|
|
1946
|
+
case 2 /* Context */:
|
|
1947
|
+
return "Context Commands";
|
|
1948
|
+
case 1 /* Prefix */:
|
|
1949
|
+
return "Prefix Commands";
|
|
1950
|
+
}
|
|
1951
|
+
}
|
|
1952
|
+
getName(module) {
|
|
1953
|
+
return "builder" in module ? module.builder.name : module.options.name;
|
|
1995
1954
|
}
|
|
1996
1955
|
/**
|
|
1997
1956
|
* Gets a command by name.
|
|
@@ -2000,7 +1959,7 @@ var BaseCommandManager = class {
|
|
|
2000
1959
|
if (this.type === 1 /* Prefix */) {
|
|
2001
1960
|
const config = this.client.config.prefixCommands;
|
|
2002
1961
|
const search = config.allowCaseInsensitiveCommandNames ? name.toLowerCase() : name;
|
|
2003
|
-
return Array.from(this.
|
|
1962
|
+
return Array.from(this.items.values()).find((cmd) => {
|
|
2004
1963
|
const commandName = "builder" in cmd ? cmd.builder.name : cmd.options.name;
|
|
2005
1964
|
const trigger = config.allowCaseInsensitiveCommandNames ? commandName.toLowerCase() : commandName;
|
|
2006
1965
|
if (trigger === search) return true;
|
|
@@ -2011,7 +1970,7 @@ var BaseCommandManager = class {
|
|
|
2011
1970
|
}
|
|
2012
1971
|
});
|
|
2013
1972
|
} else {
|
|
2014
|
-
return this.
|
|
1973
|
+
return this.items.get(name);
|
|
2015
1974
|
}
|
|
2016
1975
|
}
|
|
2017
1976
|
/**
|
|
@@ -2020,7 +1979,7 @@ var BaseCommandManager = class {
|
|
|
2020
1979
|
getAll(options = {}) {
|
|
2021
1980
|
const matchedCommands = /* @__PURE__ */ new Map();
|
|
2022
1981
|
const isDev = this.client.config.app.devMode;
|
|
2023
|
-
for (const cmd of this.
|
|
1982
|
+
for (const cmd of this.items.values()) {
|
|
2024
1983
|
const commandName = "builder" in cmd ? cmd.builder.name : cmd.options.name;
|
|
2025
1984
|
if (options.names || options.fuzzyNames) {
|
|
2026
1985
|
const nameMatched = options.names?.includes(commandName) || options.fuzzyNames?.some((fuzzy) => commandName.includes(fuzzy));
|
|
@@ -2047,7 +2006,7 @@ var BaseCommandManager = class {
|
|
|
2047
2006
|
*/
|
|
2048
2007
|
sortByCategory() {
|
|
2049
2008
|
const categories = /* @__PURE__ */ new Map();
|
|
2050
|
-
for (const cmd of this.
|
|
2009
|
+
for (const cmd of this.items.values()) {
|
|
2051
2010
|
const metadata = cmd.options.metadata;
|
|
2052
2011
|
if (!metadata?.category) continue;
|
|
2053
2012
|
let entry = categories.get(metadata.category);
|
|
@@ -2070,52 +2029,20 @@ var BaseCommandManager = class {
|
|
|
2070
2029
|
return cat;
|
|
2071
2030
|
});
|
|
2072
2031
|
}
|
|
2073
|
-
/**
|
|
2074
|
-
* Imports command modules from a directory.
|
|
2075
|
-
* @param dir Path of one or more folders.
|
|
2076
|
-
* @param set Replaces imported command modules with the ones found.
|
|
2077
|
-
*/
|
|
2078
|
-
async importFrom(dir, set = false) {
|
|
2079
|
-
if (set) this.commands.clear();
|
|
2080
|
-
const dirs = Array.isArray(dir) ? dir : [dir];
|
|
2081
|
-
const modules = [];
|
|
2082
|
-
for (const _dir of dirs) {
|
|
2083
|
-
const results = await importModulesFromDir(_dir, this.moduleSuffix);
|
|
2084
|
-
modules.push(...results.map(({ module }) => module.default));
|
|
2085
|
-
}
|
|
2086
|
-
for (const module of modules) {
|
|
2087
|
-
const commandName = "builder" in module ? module.builder.name : module.options.name;
|
|
2088
|
-
this.commands.set(commandName, module);
|
|
2089
|
-
}
|
|
2090
|
-
let moduleType;
|
|
2091
|
-
switch (this.type) {
|
|
2092
|
-
case 0 /* Slash */:
|
|
2093
|
-
moduleType = "Slash Commands";
|
|
2094
|
-
break;
|
|
2095
|
-
case 2 /* Context */:
|
|
2096
|
-
moduleType = "Context Commands";
|
|
2097
|
-
break;
|
|
2098
|
-
case 1 /* Prefix */:
|
|
2099
|
-
moduleType = "Prefix Commands";
|
|
2100
|
-
break;
|
|
2101
|
-
}
|
|
2102
|
-
this.client.logger.moduleLoaded(moduleType, modules.length);
|
|
2103
|
-
return this.commands;
|
|
2104
|
-
}
|
|
2105
2032
|
};
|
|
2106
2033
|
var SlashCommandManager = class extends BaseCommandManager {
|
|
2107
2034
|
constructor(client) {
|
|
2108
|
-
super(client, 0 /* Slash
|
|
2035
|
+
super(client, 0 /* Slash */);
|
|
2109
2036
|
}
|
|
2110
2037
|
};
|
|
2111
2038
|
var ContextCommandManager = class extends BaseCommandManager {
|
|
2112
2039
|
constructor(client) {
|
|
2113
|
-
super(client, 2 /* Context
|
|
2040
|
+
super(client, 2 /* Context */);
|
|
2114
2041
|
}
|
|
2115
2042
|
};
|
|
2116
2043
|
var PrefixCommandManager = class extends BaseCommandManager {
|
|
2117
2044
|
constructor(client) {
|
|
2118
|
-
super(client, 1 /* Prefix
|
|
2045
|
+
super(client, 1 /* Prefix */);
|
|
2119
2046
|
}
|
|
2120
2047
|
};
|
|
2121
2048
|
var CommandManager = class {
|
|
@@ -2133,7 +2060,7 @@ var CommandManager = class {
|
|
|
2133
2060
|
return [...this.slash.getAll(options), ...this.context.getAll(options)];
|
|
2134
2061
|
}
|
|
2135
2062
|
async registerGlobal(options = {}) {
|
|
2136
|
-
const client = await this.client.
|
|
2063
|
+
const client = await Vimcord.getReadyInstance(this.client.clientId);
|
|
2137
2064
|
if (!client.rest) {
|
|
2138
2065
|
console.error(`[CommandManager] \u2716 Failed to register app commands globally: REST is not initialized`);
|
|
2139
2066
|
return;
|
|
@@ -2157,7 +2084,7 @@ var CommandManager = class {
|
|
|
2157
2084
|
}
|
|
2158
2085
|
}
|
|
2159
2086
|
async unregisterGlobal() {
|
|
2160
|
-
const client = await this.client.
|
|
2087
|
+
const client = await Vimcord.getReadyInstance(this.client.clientId);
|
|
2161
2088
|
if (!client.rest) {
|
|
2162
2089
|
console.error(`[CommandManager] \u2716 Failed to remove app commands globally: REST is not initialized`);
|
|
2163
2090
|
return;
|
|
@@ -2170,7 +2097,7 @@ var CommandManager = class {
|
|
|
2170
2097
|
}
|
|
2171
2098
|
}
|
|
2172
2099
|
async registerGuild(options = {}) {
|
|
2173
|
-
const client = await this.client.
|
|
2100
|
+
const client = await Vimcord.getReadyInstance(this.client.clientId);
|
|
2174
2101
|
if (!client.rest) {
|
|
2175
2102
|
console.error(`[CommandManager] \u2716 Failed to register app commands by guild: REST is not initialized`);
|
|
2176
2103
|
return;
|
|
@@ -2202,7 +2129,7 @@ var CommandManager = class {
|
|
|
2202
2129
|
);
|
|
2203
2130
|
}
|
|
2204
2131
|
async unregisterGuild(options = {}) {
|
|
2205
|
-
const client = await this.client.
|
|
2132
|
+
const client = await Vimcord.getReadyInstance(this.client.clientId);
|
|
2206
2133
|
if (!client.rest) {
|
|
2207
2134
|
console.error(`[CommandManager] \u2716 Failed to register app commands by guild: REST is not initialized`);
|
|
2208
2135
|
return;
|
|
@@ -2219,12 +2146,13 @@ var CommandManager = class {
|
|
|
2219
2146
|
|
|
2220
2147
|
// src/modules/event.manager.ts
|
|
2221
2148
|
import { Events } from "discord.js";
|
|
2222
|
-
var EventManager = class {
|
|
2223
|
-
|
|
2224
|
-
|
|
2149
|
+
var EventManager = class extends ModuleImporter {
|
|
2150
|
+
items = /* @__PURE__ */ new Map();
|
|
2151
|
+
itemSuffix = "event";
|
|
2152
|
+
itemName = "Event Handlers";
|
|
2225
2153
|
logger;
|
|
2226
2154
|
constructor(client) {
|
|
2227
|
-
|
|
2155
|
+
super(client);
|
|
2228
2156
|
this.logger = new Logger({ prefixEmoji: "\u{1F4CB}", prefix: `EventManager (i${this.client.clientId})` });
|
|
2229
2157
|
for (const event of Object.values(Events)) {
|
|
2230
2158
|
client.on(
|
|
@@ -2233,105 +2161,361 @@ var EventManager = class {
|
|
|
2233
2161
|
);
|
|
2234
2162
|
}
|
|
2235
2163
|
}
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2164
|
+
getName(module) {
|
|
2165
|
+
return module.name;
|
|
2166
|
+
}
|
|
2167
|
+
register(...events) {
|
|
2168
|
+
for (const event of events) {
|
|
2169
|
+
this.items.set(event.name, event);
|
|
2170
|
+
if (this.client.config.app.verbose) {
|
|
2171
|
+
this.logger.debug(`'${event.name}' registered for EventType '${event.event}'`);
|
|
2172
|
+
}
|
|
2173
|
+
}
|
|
2174
|
+
}
|
|
2175
|
+
unregister(...names) {
|
|
2176
|
+
for (const name of names) {
|
|
2177
|
+
const event = this.items.get(name);
|
|
2178
|
+
if (!event) continue;
|
|
2179
|
+
this.items.delete(name);
|
|
2180
|
+
if (this.client.config.app.verbose) {
|
|
2181
|
+
this.logger.debug(`'${event.name}' unregistered for EventType '${event.event}'`);
|
|
2182
|
+
}
|
|
2183
|
+
}
|
|
2184
|
+
}
|
|
2185
|
+
clear() {
|
|
2186
|
+
this.items.forEach((e) => this.unregister(e.name));
|
|
2187
|
+
this.items.clear();
|
|
2188
|
+
}
|
|
2189
|
+
get(name) {
|
|
2190
|
+
return this.items.get(name);
|
|
2191
|
+
}
|
|
2192
|
+
getByTag(tag) {
|
|
2193
|
+
return Array.from(this.items.values()).filter((event) => event.metadata?.tags?.includes(tag));
|
|
2194
|
+
}
|
|
2195
|
+
getByCategory(category) {
|
|
2196
|
+
return Array.from(this.items.values()).filter((event) => event.metadata?.category?.includes(category));
|
|
2197
|
+
}
|
|
2198
|
+
getByEvent(eventType) {
|
|
2199
|
+
return Array.from(this.items.values()).filter((event) => event.event === eventType);
|
|
2200
|
+
}
|
|
2201
|
+
async executeEvents(eventType, ...args) {
|
|
2202
|
+
const events = this.getByEvent(eventType);
|
|
2203
|
+
if (!events.length) return;
|
|
2204
|
+
const sortedEvents = events.sort((a, b) => b.priority - a.priority);
|
|
2205
|
+
await Promise.all(
|
|
2206
|
+
sortedEvents.map(async (event) => {
|
|
2207
|
+
try {
|
|
2208
|
+
await event.execute?.(this.client, ...args);
|
|
2209
|
+
if (event.once) {
|
|
2210
|
+
this.unregister(event.name);
|
|
2211
|
+
}
|
|
2212
|
+
} catch (err) {
|
|
2213
|
+
this.logger.error(`'${event.name}' failed to execute`, err);
|
|
2214
|
+
}
|
|
2215
|
+
})
|
|
2216
|
+
);
|
|
2217
|
+
}
|
|
2218
|
+
};
|
|
2219
|
+
|
|
2220
|
+
// src/tools/utils.ts
|
|
2221
|
+
var MENTION_OR_SNOWFLAKE_REGEX = /<@[#&]?[\d]{6,}>|[\d]{6,}/;
|
|
2222
|
+
var fetchUserPromises = /* @__PURE__ */ new Map();
|
|
2223
|
+
var fetchGuildPromises = /* @__PURE__ */ new Map();
|
|
2224
|
+
var fetchMemberPromises = /* @__PURE__ */ new Map();
|
|
2225
|
+
var fetchChannelPromises = /* @__PURE__ */ new Map();
|
|
2226
|
+
var fetchMessagePromises = /* @__PURE__ */ new Map();
|
|
2227
|
+
var fetchRolePromises = /* @__PURE__ */ new Map();
|
|
2228
|
+
function createCachedFetch(cache, fetchFn, cacheKey) {
|
|
2229
|
+
const cached = cache.get(cacheKey);
|
|
2230
|
+
if (cached) return cached;
|
|
2231
|
+
const promise = fetchFn().finally(() => cache.delete(cacheKey));
|
|
2232
|
+
cache.set(cacheKey, promise);
|
|
2233
|
+
return promise;
|
|
2234
|
+
}
|
|
2235
|
+
function __zero(str) {
|
|
2236
|
+
return str?.length ? str : "0";
|
|
2237
|
+
}
|
|
2238
|
+
function isMentionOrSnowflake(str) {
|
|
2239
|
+
return str ? MENTION_OR_SNOWFLAKE_REGEX.test(str) : false;
|
|
2240
|
+
}
|
|
2241
|
+
function cleanMention(str) {
|
|
2242
|
+
return str ? str.replaceAll(/[<@#&>]/g, "").trim() : void 0;
|
|
2243
|
+
}
|
|
2244
|
+
async function getMessageMention(message, content, type, index = 0, idOnly) {
|
|
2245
|
+
const args = content?.split(" ");
|
|
2246
|
+
const arg = isMentionOrSnowflake(args?.[index]) ? cleanMention(args?.[index]) : void 0;
|
|
2247
|
+
switch (type) {
|
|
2248
|
+
case "user": {
|
|
2249
|
+
const userMention2 = message.mentions.users.at(index) || null;
|
|
2250
|
+
if (!userMention2 && arg) {
|
|
2251
|
+
return idOnly ? arg : await fetchUser(message.client, arg);
|
|
2252
|
+
}
|
|
2253
|
+
return idOnly ? userMention2?.id || null : userMention2;
|
|
2254
|
+
}
|
|
2255
|
+
case "member": {
|
|
2256
|
+
if (!message.guild) return null;
|
|
2257
|
+
const member = await fetchMember(message.guild, message.mentions.users.at(index)?.id ?? arg);
|
|
2258
|
+
return idOnly ? member?.id || null : member;
|
|
2259
|
+
}
|
|
2260
|
+
case "channel": {
|
|
2261
|
+
const channelMention = message.mentions.channels.at(index) || null;
|
|
2262
|
+
if (!channelMention && arg) {
|
|
2263
|
+
if (idOnly) return arg;
|
|
2264
|
+
const channel = message.guild ? await fetchChannel(message.guild, arg) : message.client.channels.cache.get(__zero(arg)) ?? message.client.channels.fetch(__zero(arg));
|
|
2265
|
+
return channel;
|
|
2266
|
+
}
|
|
2267
|
+
return idOnly ? channelMention?.id || null : channelMention;
|
|
2268
|
+
}
|
|
2269
|
+
case "role": {
|
|
2270
|
+
const roleMention = message.mentions.roles.at(index) || null;
|
|
2271
|
+
if (!roleMention && arg) {
|
|
2272
|
+
if (idOnly) return arg;
|
|
2273
|
+
return message.guild ? await fetchRole(message.guild, arg) : null;
|
|
2274
|
+
}
|
|
2275
|
+
return idOnly ? roleMention?.id || null : roleMention;
|
|
2276
|
+
}
|
|
2277
|
+
default:
|
|
2278
|
+
return null;
|
|
2279
|
+
}
|
|
2280
|
+
}
|
|
2281
|
+
function getFirstMentionId(options) {
|
|
2282
|
+
let mentionId = "";
|
|
2283
|
+
if (options.message) {
|
|
2284
|
+
switch (options.type) {
|
|
2285
|
+
case "user":
|
|
2286
|
+
mentionId = options.message.mentions.users.first()?.id || "";
|
|
2287
|
+
break;
|
|
2288
|
+
case "member":
|
|
2289
|
+
mentionId = options.message.mentions.members?.first()?.id || "";
|
|
2290
|
+
break;
|
|
2291
|
+
case "channel":
|
|
2292
|
+
mentionId = options.message.mentions.channels.first()?.id || "";
|
|
2293
|
+
break;
|
|
2294
|
+
case "role":
|
|
2295
|
+
mentionId = options.message.mentions.roles.first()?.id || "";
|
|
2296
|
+
break;
|
|
2297
|
+
}
|
|
2298
|
+
}
|
|
2299
|
+
const firstArg = options.content?.split(" ")[0] || "";
|
|
2300
|
+
return mentionId || isMentionOrSnowflake(firstArg) ? cleanMention(firstArg) : "";
|
|
2301
|
+
}
|
|
2302
|
+
async function fetchUser(client, userId) {
|
|
2303
|
+
if (!userId) return null;
|
|
2304
|
+
const key = `${client.user.id}-${userId}`;
|
|
2305
|
+
const cached = client.users.cache.get(__zero(userId));
|
|
2306
|
+
if (cached) return cached;
|
|
2307
|
+
return createCachedFetch(fetchUserPromises, () => client.users.fetch(__zero(userId)).catch(() => null), key);
|
|
2308
|
+
}
|
|
2309
|
+
async function fetchGuild(client, guildId) {
|
|
2310
|
+
if (!guildId) return null;
|
|
2311
|
+
const key = `${client.user.id}-${guildId}`;
|
|
2312
|
+
const cached = client.guilds.cache.get(__zero(guildId));
|
|
2313
|
+
if (cached) return cached;
|
|
2314
|
+
return createCachedFetch(fetchGuildPromises, () => client.guilds.fetch(__zero(guildId)).catch(() => null), key);
|
|
2315
|
+
}
|
|
2316
|
+
async function fetchMember(guild, memberId) {
|
|
2317
|
+
if (!memberId) return null;
|
|
2318
|
+
const key = `${guild.id}-${memberId}`;
|
|
2319
|
+
const cached = guild.members.cache.get(__zero(memberId));
|
|
2320
|
+
if (cached) return cached;
|
|
2321
|
+
return createCachedFetch(fetchMemberPromises, () => guild.members.fetch(__zero(memberId)).catch(() => null), key);
|
|
2322
|
+
}
|
|
2323
|
+
async function fetchChannel(guild, channelId, type) {
|
|
2324
|
+
if (!channelId) return null;
|
|
2325
|
+
const key = `${guild.id}-${channelId}`;
|
|
2326
|
+
const cached = guild.channels.cache.get(__zero(channelId)) ?? null;
|
|
2327
|
+
if (cached) {
|
|
2328
|
+
if (type && cached.type !== type) return null;
|
|
2329
|
+
return cached;
|
|
2330
|
+
}
|
|
2331
|
+
const channel = await createCachedFetch(
|
|
2332
|
+
fetchChannelPromises,
|
|
2333
|
+
() => guild.channels.fetch(__zero(channelId)).catch(() => null),
|
|
2334
|
+
key
|
|
2335
|
+
);
|
|
2336
|
+
if (type && channel?.type !== type) return null;
|
|
2337
|
+
return channel;
|
|
2338
|
+
}
|
|
2339
|
+
async function fetchMessage(channel, messageId) {
|
|
2340
|
+
if (!messageId) return null;
|
|
2341
|
+
const key = `${channel.guild.id}-${messageId}`;
|
|
2342
|
+
const cached = channel.messages.cache.get(__zero(messageId));
|
|
2343
|
+
if (cached) return cached;
|
|
2344
|
+
return createCachedFetch(fetchMessagePromises, () => channel.messages.fetch(__zero(messageId)).catch(() => null), key);
|
|
2345
|
+
}
|
|
2346
|
+
async function fetchRole(guild, roleId) {
|
|
2347
|
+
if (!roleId) return null;
|
|
2348
|
+
const key = `${guild.id}-${roleId}`;
|
|
2349
|
+
const cached = guild.roles.cache.get(__zero(roleId));
|
|
2350
|
+
if (cached) return cached;
|
|
2351
|
+
return createCachedFetch(fetchRolePromises, () => guild.roles.fetch(__zero(roleId)).catch(() => null), key);
|
|
2352
|
+
}
|
|
2353
|
+
|
|
2354
|
+
// src/types/status.ts
|
|
2355
|
+
import { ActivityType } from "discord.js";
|
|
2356
|
+
import _6 from "lodash";
|
|
2357
|
+
var StatusType = /* @__PURE__ */ ((StatusType2) => {
|
|
2358
|
+
StatusType2["DND"] = "dnd";
|
|
2359
|
+
StatusType2["Idle"] = "idle";
|
|
2360
|
+
StatusType2["Online"] = "online";
|
|
2361
|
+
StatusType2["Invisible"] = "invisible";
|
|
2362
|
+
return StatusType2;
|
|
2363
|
+
})(StatusType || {});
|
|
2364
|
+
var defaultPresence = {
|
|
2365
|
+
production: {
|
|
2366
|
+
interval: 6e4,
|
|
2367
|
+
randomize: false,
|
|
2368
|
+
activity: [
|
|
2369
|
+
{ status: "online" /* Online */, type: ActivityType.Custom, name: "Need help? Use /help or !help" },
|
|
2370
|
+
{ status: "online" /* Online */, type: ActivityType.Custom, name: "Join our community!" },
|
|
2371
|
+
{ status: "online" /* Online */, type: ActivityType.Watching, name: "\u2728 $GUILD_COUNT servers" }
|
|
2372
|
+
]
|
|
2373
|
+
},
|
|
2374
|
+
development: {
|
|
2375
|
+
activity: { status: "dnd" /* DND */, type: ActivityType.Custom, name: "In development!" }
|
|
2376
|
+
}
|
|
2377
|
+
};
|
|
2378
|
+
function createVimcordStatusConfig(options = {}) {
|
|
2379
|
+
return _6.merge(defaultPresence, options);
|
|
2380
|
+
}
|
|
2381
|
+
|
|
2382
|
+
// src/modules/status.manager.ts
|
|
2383
|
+
import EventEmitter from "events";
|
|
2384
|
+
import { $ as $2 } from "qznt";
|
|
2385
|
+
var StatusManager = class {
|
|
2386
|
+
client;
|
|
2387
|
+
logger;
|
|
2388
|
+
emitter = new EventEmitter();
|
|
2389
|
+
lastActivity = null;
|
|
2390
|
+
lastActivityIndex = 0;
|
|
2391
|
+
task = null;
|
|
2392
|
+
constructor(client) {
|
|
2393
|
+
this.client = client;
|
|
2394
|
+
this.logger = new Logger({ prefixEmoji: "\u{1F4AC}", prefix: `StatusManager (i${this.client.clientId})` });
|
|
2395
|
+
this.emitter.on("changed", (activity) => {
|
|
2396
|
+
if (this.client.config.app.verbose) {
|
|
2397
|
+
this.logger.debug(`Status changed to '${activity.name}'`);
|
|
2398
|
+
}
|
|
2399
|
+
});
|
|
2400
|
+
this.emitter.on("cleared", () => {
|
|
2401
|
+
if (this.client.config.app.verbose) {
|
|
2402
|
+
this.logger.debug("Status cleared");
|
|
2403
|
+
}
|
|
2404
|
+
});
|
|
2405
|
+
}
|
|
2406
|
+
clearData() {
|
|
2407
|
+
this.task?.stop();
|
|
2408
|
+
this.task = null;
|
|
2409
|
+
this.lastActivity = null;
|
|
2410
|
+
this.lastActivityIndex = 0;
|
|
2411
|
+
return this;
|
|
2412
|
+
}
|
|
2413
|
+
async getReadyClient() {
|
|
2414
|
+
const client = await Vimcord.getReadyInstance(this.client.clientId);
|
|
2415
|
+
if (!client.user) throw new Error("Cannot manage the client's activity when its user is not hydrated");
|
|
2416
|
+
return client;
|
|
2417
|
+
}
|
|
2418
|
+
async formatActivityName(name) {
|
|
2419
|
+
name = name.replace("$USER_COUNT", $2.format.number(this.client.users.cache.size)).replace("$GUILD_COUNT", $2.format.number(this.client.guilds.cache.size)).replace(
|
|
2420
|
+
"$INVITE",
|
|
2421
|
+
this.client.config.staff.guild.inviteUrl ? this.client.config.staff.guild.inviteUrl : "<STAFF_INVITE_URL_NOT_SET>"
|
|
2422
|
+
);
|
|
2423
|
+
if (name.includes("$STAFF_GUILD_MEMBER_COUNT")) {
|
|
2424
|
+
await fetchGuild(this.client, this.client.config.staff.guild.id).then((guild) => {
|
|
2425
|
+
if (!guild) return name = name.replace("$STAFF_GUILD_MEMBER_COUNT", "<STAFF_GUILD_NOT_FOUND>");
|
|
2426
|
+
name = name.replace("$STAFF_GUILD_MEMBER_COUNT", $2.format.number(guild.members.cache.size));
|
|
2427
|
+
}).catch((err) => this.logger.error("Failed to fetch the staff guild", err));
|
|
2428
|
+
}
|
|
2429
|
+
return name;
|
|
2430
|
+
}
|
|
2431
|
+
async setActivity(activity) {
|
|
2432
|
+
const client = await this.getReadyClient();
|
|
2433
|
+
activity.name = await this.formatActivityName(activity.name);
|
|
2434
|
+
client.user.setStatus(activity.status);
|
|
2435
|
+
client.user.setActivity({ name: activity.name, type: activity.type, url: activity.streamUrl });
|
|
2436
|
+
this.emitter.emit("changed", activity);
|
|
2243
2437
|
}
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
this.
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2438
|
+
async statusRotationTask(clientStatus) {
|
|
2439
|
+
let activity;
|
|
2440
|
+
if (clientStatus.randomize && Array.isArray(clientStatus.activity)) {
|
|
2441
|
+
activity = $2.rnd.choice(clientStatus.activity, { not: this.lastActivity });
|
|
2442
|
+
this.lastActivity = activity;
|
|
2443
|
+
} else {
|
|
2444
|
+
const activityIndex = (this.lastActivityIndex + 1) % clientStatus.activity.length;
|
|
2445
|
+
this.lastActivityIndex = activityIndex;
|
|
2446
|
+
activity = clientStatus.activity[activityIndex];
|
|
2252
2447
|
}
|
|
2448
|
+
await this.setActivity(activity);
|
|
2449
|
+
this.emitter.emit("rotation", activity);
|
|
2253
2450
|
}
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
this.
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
}
|
|
2261
|
-
getByTag(tag) {
|
|
2262
|
-
return Array.from(this.events.values()).filter((event) => event.metadata?.tags?.includes(tag));
|
|
2451
|
+
async scheduleStatusRotation(clientStatus) {
|
|
2452
|
+
if (!clientStatus.interval) throw new Error("Cannot create client activity interval without interval time");
|
|
2453
|
+
this.task?.stop();
|
|
2454
|
+
this.task = null;
|
|
2455
|
+
this.task = new $2.Loop(() => this.statusRotationTask(clientStatus), $2.math.ms(clientStatus.interval), true);
|
|
2456
|
+
this.start();
|
|
2263
2457
|
}
|
|
2264
|
-
|
|
2265
|
-
|
|
2458
|
+
start() {
|
|
2459
|
+
if (this.task) {
|
|
2460
|
+
this.task.start();
|
|
2461
|
+
this.emitter.emit("started", this.task);
|
|
2462
|
+
}
|
|
2463
|
+
return this;
|
|
2266
2464
|
}
|
|
2267
|
-
|
|
2268
|
-
|
|
2465
|
+
pause() {
|
|
2466
|
+
if (this.task) {
|
|
2467
|
+
this.task.stop();
|
|
2468
|
+
this.emitter.emit("paused", this.task);
|
|
2469
|
+
}
|
|
2470
|
+
return this;
|
|
2269
2471
|
}
|
|
2270
|
-
async
|
|
2271
|
-
const
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
})
|
|
2285
|
-
);
|
|
2472
|
+
async set(status) {
|
|
2473
|
+
const statusConfig = createVimcordStatusConfig(status);
|
|
2474
|
+
let clientStatus;
|
|
2475
|
+
if (this.client.config.app.devMode) {
|
|
2476
|
+
clientStatus = statusConfig.development;
|
|
2477
|
+
} else {
|
|
2478
|
+
clientStatus = statusConfig.production;
|
|
2479
|
+
}
|
|
2480
|
+
if (!clientStatus.interval) {
|
|
2481
|
+
await this.setActivity(Array.isArray(clientStatus.activity) ? clientStatus.activity[0] : clientStatus.activity);
|
|
2482
|
+
} else {
|
|
2483
|
+
await this.scheduleStatusRotation(clientStatus);
|
|
2484
|
+
}
|
|
2485
|
+
return this;
|
|
2286
2486
|
}
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
if (replaceAll) {
|
|
2294
|
-
this.clear();
|
|
2295
|
-
}
|
|
2296
|
-
let importedEvents = 0;
|
|
2297
|
-
let ignoredEvents = 0;
|
|
2298
|
-
for (const event of eventModules.flat()) {
|
|
2299
|
-
if (!event.module.default.enabled) {
|
|
2300
|
-
ignoredEvents++;
|
|
2301
|
-
} else {
|
|
2302
|
-
importedEvents++;
|
|
2303
|
-
}
|
|
2304
|
-
this.register(event.module.default);
|
|
2487
|
+
async destroy() {
|
|
2488
|
+
if (this.task) {
|
|
2489
|
+
this.task.stop();
|
|
2490
|
+
this.task = null;
|
|
2491
|
+
this.emitter.emit("destroyed");
|
|
2492
|
+
await this.clear();
|
|
2305
2493
|
}
|
|
2306
|
-
this
|
|
2307
|
-
|
|
2494
|
+
return this;
|
|
2495
|
+
}
|
|
2496
|
+
async clear() {
|
|
2497
|
+
const client = await this.getReadyClient();
|
|
2498
|
+
this.clearData();
|
|
2499
|
+
client.user.setActivity({ name: "" });
|
|
2500
|
+
this.emitter.emit("cleared");
|
|
2501
|
+
return this;
|
|
2308
2502
|
}
|
|
2309
2503
|
};
|
|
2310
2504
|
|
|
2311
|
-
//
|
|
2312
|
-
var version = "1.0.36";
|
|
2313
|
-
|
|
2314
|
-
// src/client.ts
|
|
2315
|
-
import { randomUUID as randomUUID3 } from "crypto";
|
|
2316
|
-
import { $ as $4 } from "qznt";
|
|
2317
|
-
|
|
2318
|
-
// src/utils/VimcordCLI.ts
|
|
2505
|
+
// src/utils/vimcord.cli.ts
|
|
2319
2506
|
import { createInterface } from "readline";
|
|
2320
2507
|
import { $ as $3 } from "qznt";
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
}
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
}
|
|
2332
|
-
|
|
2333
|
-
// src/utils/VimcordCLI.ts
|
|
2334
|
-
var VimcordCLI = class {
|
|
2508
|
+
var VimcordCLI = class _VimcordCLI {
|
|
2509
|
+
static mode = "off";
|
|
2510
|
+
static setMode(mode) {
|
|
2511
|
+
if (_VimcordCLI.mode === mode) return;
|
|
2512
|
+
_VimcordCLI.mode = mode;
|
|
2513
|
+
if (mode === "on") {
|
|
2514
|
+
CLI.logger.log(`~ Type ${CLI.options.prefix}help to view available commands`);
|
|
2515
|
+
} else {
|
|
2516
|
+
CLI.logger.log(`~ [MODE] Now set to "${mode}"`);
|
|
2517
|
+
}
|
|
2518
|
+
}
|
|
2335
2519
|
rl;
|
|
2336
2520
|
options;
|
|
2337
2521
|
commands = /* @__PURE__ */ new Map();
|
|
@@ -2344,6 +2528,7 @@ var VimcordCLI = class {
|
|
|
2344
2528
|
terminal: false
|
|
2345
2529
|
});
|
|
2346
2530
|
this.rl.on("line", (line) => {
|
|
2531
|
+
if (_VimcordCLI.mode !== "on") return;
|
|
2347
2532
|
const { isCommand, commandName, content, args } = this.parseLine(line);
|
|
2348
2533
|
if (!isCommand) return;
|
|
2349
2534
|
const command = this.commands.get(commandName);
|
|
@@ -2400,7 +2585,6 @@ var VimcordCLI = class {
|
|
|
2400
2585
|
return true;
|
|
2401
2586
|
}
|
|
2402
2587
|
};
|
|
2403
|
-
var initCalled = false;
|
|
2404
2588
|
var CLI = new VimcordCLI({ prefix: "/" });
|
|
2405
2589
|
CLI.addCommand("help", "View information about a command, or the available CLI options", (args) => {
|
|
2406
2590
|
const prefix = CLI.options.prefix;
|
|
@@ -2507,16 +2691,81 @@ CLI.addCommand("cmds", "List the loaded commands", async (args, content) => {
|
|
|
2507
2691
|
return CLI.logger.error(`'${mode}' is not a valid option. Valid options: [slash|prefix|ctx]`);
|
|
2508
2692
|
}
|
|
2509
2693
|
});
|
|
2510
|
-
function initCLI() {
|
|
2511
|
-
if (initCalled) return;
|
|
2512
|
-
CLI.logger.log(`~ Type ${CLI.options.prefix}help to view available commands`);
|
|
2513
|
-
initCalled = true;
|
|
2514
|
-
}
|
|
2515
2694
|
|
|
2516
|
-
// src/client.ts
|
|
2517
|
-
import
|
|
2695
|
+
// src/client/Vimcord.ts
|
|
2696
|
+
import { Client as Client2 } from "discord.js";
|
|
2697
|
+
import { configDotenv } from "dotenv";
|
|
2698
|
+
import { randomUUID as randomUUID3 } from "crypto";
|
|
2699
|
+
import EventEmitter2 from "events";
|
|
2700
|
+
import { $ as $4 } from "qznt";
|
|
2518
2701
|
var Vimcord = class _Vimcord extends Client2 {
|
|
2519
2702
|
static instances = /* @__PURE__ */ new Map();
|
|
2703
|
+
static emitter = new EventEmitter2();
|
|
2704
|
+
clientStartingPromise = null;
|
|
2705
|
+
static create(optionsOrConfig, features, config) {
|
|
2706
|
+
if ("options" in optionsOrConfig) {
|
|
2707
|
+
const { options, features: features2, config: config2 } = optionsOrConfig;
|
|
2708
|
+
return new _Vimcord(options, features2, config2);
|
|
2709
|
+
} else {
|
|
2710
|
+
return new _Vimcord(optionsOrConfig, features, config);
|
|
2711
|
+
}
|
|
2712
|
+
}
|
|
2713
|
+
/**
|
|
2714
|
+
* Returns an instance of Vimcord.
|
|
2715
|
+
* @param clientId [default: 0]
|
|
2716
|
+
*/
|
|
2717
|
+
static getInstance(clientId) {
|
|
2718
|
+
if (clientId === void 0) {
|
|
2719
|
+
return _Vimcord.instances.values().next().value;
|
|
2720
|
+
}
|
|
2721
|
+
return _Vimcord.instances.get(clientId);
|
|
2722
|
+
}
|
|
2723
|
+
/**
|
|
2724
|
+
* Waits for a Vimcord instance to be ready.
|
|
2725
|
+
* @param clientId [default: 0]
|
|
2726
|
+
* @param timeoutMs [default: 60000]
|
|
2727
|
+
*/
|
|
2728
|
+
static async getReadyInstance(clientId, timeoutMs = 6e4) {
|
|
2729
|
+
const client = _Vimcord.getInstance(clientId);
|
|
2730
|
+
if (client?.isReady()) {
|
|
2731
|
+
_Vimcord.emitter.emit("ready", client);
|
|
2732
|
+
return client;
|
|
2733
|
+
}
|
|
2734
|
+
if (client) {
|
|
2735
|
+
return new Promise((resolve, reject) => {
|
|
2736
|
+
const timeout = setTimeout(() => {
|
|
2737
|
+
_Vimcord.emitter.off("ready", listener);
|
|
2738
|
+
reject(new Error(`Client (i${clientId ?? 0}) timed out waiting for ready`));
|
|
2739
|
+
}, timeoutMs);
|
|
2740
|
+
const listener = (c) => {
|
|
2741
|
+
if (c.clientId === (clientId ?? 0)) {
|
|
2742
|
+
clearTimeout(timeout);
|
|
2743
|
+
_Vimcord.emitter.off("ready", listener);
|
|
2744
|
+
resolve(c);
|
|
2745
|
+
}
|
|
2746
|
+
};
|
|
2747
|
+
client.once("clientReady", () => {
|
|
2748
|
+
clearTimeout(timeout);
|
|
2749
|
+
_Vimcord.emitter.emit("ready", client);
|
|
2750
|
+
resolve(client);
|
|
2751
|
+
});
|
|
2752
|
+
});
|
|
2753
|
+
}
|
|
2754
|
+
return new Promise((resolve, reject) => {
|
|
2755
|
+
const timeout = setTimeout(() => {
|
|
2756
|
+
_Vimcord.emitter.off("ready", listener);
|
|
2757
|
+
reject(new Error(`Vimcord instance (i${clientId ?? 0}) failed to initialize within ${timeoutMs / 1e3}s.`));
|
|
2758
|
+
}, timeoutMs);
|
|
2759
|
+
const listener = (c) => {
|
|
2760
|
+
if (c.clientId === (clientId ?? 0)) {
|
|
2761
|
+
clearTimeout(timeout);
|
|
2762
|
+
_Vimcord.emitter.off("ready", listener);
|
|
2763
|
+
resolve(c);
|
|
2764
|
+
}
|
|
2765
|
+
};
|
|
2766
|
+
_Vimcord.emitter.on("ready", listener);
|
|
2767
|
+
});
|
|
2768
|
+
}
|
|
2520
2769
|
uuid = randomUUID3();
|
|
2521
2770
|
clientId = _Vimcord.instances.size;
|
|
2522
2771
|
clientOptions;
|
|
@@ -2526,229 +2775,181 @@ var Vimcord = class _Vimcord extends Client2 {
|
|
|
2526
2775
|
events;
|
|
2527
2776
|
commands;
|
|
2528
2777
|
db;
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
clientBanner(client) {
|
|
2532
|
-
if (client.config.app.disableBanner) return;
|
|
2533
|
-
const border = "\u2550".repeat(50);
|
|
2534
|
-
console.log(chalk2.hex(this.colors.primary)(`
|
|
2535
|
-
\u2554${border}\u2557`));
|
|
2536
|
-
console.log(
|
|
2537
|
-
chalk2.hex(this.colors.primary)("\u2551") + chalk2.bold.hex(this.colors.text)(
|
|
2538
|
-
` \u{1F680} ${client.config.app.name} v${client.config.app.appVersion}`.padEnd(
|
|
2539
|
-
50 - (client.config.app.devMode ? 12 : 0)
|
|
2540
|
-
)
|
|
2541
|
-
) + chalk2.hex(this.colors.primary)(
|
|
2542
|
-
`${client.config.app.devMode ? chalk2.hex(this.colors.warn)("devMode \u26A0\uFE0F ") : ""}\u2551`
|
|
2543
|
-
)
|
|
2544
|
-
);
|
|
2545
|
-
console.log(chalk2.hex(this.colors.primary)(`\u2551${"".padEnd(50)}\u2551`));
|
|
2546
|
-
console.log(
|
|
2547
|
-
chalk2.hex(this.colors.primary)("\u2551") + chalk2.hex(this.colors.muted)(
|
|
2548
|
-
` # Powered by Vimcord v${version}`.padEnd(50 - 3 - `${client.clientId}`.length)
|
|
2549
|
-
) + chalk2.hex(this.colors.primary)(`${chalk2.hex(this.colors.muted)(`i${client.clientId}`)} \u2551`)
|
|
2550
|
-
);
|
|
2551
|
-
console.log(chalk2.hex(this.colors.primary)(`\u255A${border}\u255D
|
|
2552
|
-
`));
|
|
2553
|
-
},
|
|
2554
|
-
clientReady(clientTag, guildCount) {
|
|
2555
|
-
console.log(
|
|
2556
|
-
this.formatTimestamp(),
|
|
2557
|
-
this.formatPrefix(),
|
|
2558
|
-
chalk2.hex(this.colors.success)("\u{1F916} READY"),
|
|
2559
|
-
chalk2.white(`Connected as ${chalk2.bold.hex(this.colors.primary)(clientTag)}`),
|
|
2560
|
-
chalk2.hex(this.colors.muted)(`\u2022 ${guildCount} guilds`)
|
|
2561
|
-
);
|
|
2562
|
-
},
|
|
2563
|
-
moduleLoaded(moduleName, count, ignoredCount) {
|
|
2564
|
-
const countText = count ? chalk2.hex(this.colors.muted)(`(${count} items)`) : "";
|
|
2565
|
-
console.log(
|
|
2566
|
-
this.formatTimestamp(),
|
|
2567
|
-
this.formatPrefix(),
|
|
2568
|
-
chalk2.hex("#9B59B6")("\u{1F4E6} MODULE"),
|
|
2569
|
-
chalk2.hex(this.colors.warn)(`${moduleName} loaded`),
|
|
2570
|
-
ignoredCount ? chalk2.hex(this.colors.muted)(`(${ignoredCount} ignored)`) : "",
|
|
2571
|
-
countText
|
|
2572
|
-
);
|
|
2573
|
-
},
|
|
2574
|
-
commandExecuted(commandName, username, guildName) {
|
|
2575
|
-
const location = guildName ? `in ${chalk2.hex(this.colors.muted)(guildName)}` : "in DMs";
|
|
2576
|
-
console.log(
|
|
2577
|
-
this.formatTimestamp(),
|
|
2578
|
-
this.formatPrefix(),
|
|
2579
|
-
chalk2.hex("#87CEEB")("\u{1F4DD} COMMAND"),
|
|
2580
|
-
chalk2.hex(this.colors.warn)(`/${commandName}`),
|
|
2581
|
-
chalk2.white(`used by ${chalk2.bold(username)}`),
|
|
2582
|
-
chalk2.hex(this.colors.muted)(location)
|
|
2583
|
-
);
|
|
2584
|
-
},
|
|
2585
|
-
database(action, details) {
|
|
2586
|
-
console.log(
|
|
2587
|
-
this.formatTimestamp(),
|
|
2588
|
-
this.formatPrefix(),
|
|
2589
|
-
chalk2.hex("#FF6B9D")("\u{1F5C4}\uFE0F DATABASE"),
|
|
2590
|
-
chalk2.white(action),
|
|
2591
|
-
details ? chalk2.hex(this.colors.muted)(details) : ""
|
|
2592
|
-
);
|
|
2593
|
-
}
|
|
2594
|
-
});
|
|
2595
|
-
clientStartingPromise = null;
|
|
2778
|
+
logger = clientLoggerFactory(this);
|
|
2779
|
+
error;
|
|
2596
2780
|
constructor(options, features = {}, config = {}) {
|
|
2597
2781
|
super(options);
|
|
2598
2782
|
this.clientOptions = options;
|
|
2599
2783
|
this.features = features;
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
dotEnv.config({ quiet: true, ...this.features.useEnv });
|
|
2603
|
-
} else {
|
|
2604
|
-
dotEnv.config({ quiet: true });
|
|
2605
|
-
}
|
|
2606
|
-
}
|
|
2784
|
+
this.config = defineVimcordConfig(config);
|
|
2785
|
+
this.error = new ErrorHandler(this);
|
|
2607
2786
|
if (this.features.useGlobalErrorHandlers) {
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
process.on("exit", (code) => this.logger.debug(`Process exited with code ${code}`));
|
|
2611
|
-
this.on("error", (err) => this.logger.error("Client Error", err));
|
|
2612
|
-
this.on("shardError", (err) => this.logger.error("Client Shard Error", err));
|
|
2613
|
-
}
|
|
2614
|
-
this.config = {
|
|
2615
|
-
app: createAppConfig(config.app),
|
|
2616
|
-
staff: createStaffConfig(config.staff),
|
|
2617
|
-
slashCommands: createSlashCommandConfig(config.slashCommands),
|
|
2618
|
-
prefixCommands: createPrefixCommandConfig(config.prefixCommands),
|
|
2619
|
-
contextCommands: createContextCommandConfig(config.contextCommands)
|
|
2620
|
-
};
|
|
2787
|
+
this.error.setupGlobalHandlers();
|
|
2788
|
+
}
|
|
2621
2789
|
this.status = new StatusManager(this);
|
|
2622
2790
|
this.events = new EventManager(this);
|
|
2623
2791
|
this.commands = new CommandManager(this);
|
|
2624
2792
|
this.logger.clientBanner(this);
|
|
2625
|
-
this.once("clientReady", (client) =>
|
|
2626
|
-
this.logger.clientReady(client.user.tag, client.guilds.cache.size);
|
|
2627
|
-
});
|
|
2793
|
+
this.once("clientReady", (client) => this.logger.clientReady(client.user.tag, client.guilds.cache.size));
|
|
2628
2794
|
_Vimcord.instances.set(this.clientId, this);
|
|
2629
|
-
|
|
2795
|
+
if (this.config.app.enableCLI) {
|
|
2796
|
+
VimcordCLI.setMode("on");
|
|
2797
|
+
}
|
|
2630
2798
|
}
|
|
2631
|
-
/**
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
features: this.features,
|
|
2636
|
-
config: this.config
|
|
2637
|
-
};
|
|
2799
|
+
/** Current app name */
|
|
2800
|
+
// prettier-ignore
|
|
2801
|
+
get $name() {
|
|
2802
|
+
return this.config.app.name;
|
|
2638
2803
|
}
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
return new _Vimcord(options, features, config);
|
|
2804
|
+
// prettier-ignore
|
|
2805
|
+
set $name(name) {
|
|
2806
|
+
this.config.app.name = name;
|
|
2643
2807
|
}
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
}
|
|
2649
|
-
return this;
|
|
2808
|
+
/** Current app version */
|
|
2809
|
+
// prettier-ignore
|
|
2810
|
+
get $version() {
|
|
2811
|
+
return this.config.app.version;
|
|
2650
2812
|
}
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2813
|
+
// prettier-ignore
|
|
2814
|
+
set $version(version2) {
|
|
2815
|
+
this.config.app.version = version2;
|
|
2654
2816
|
}
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2817
|
+
/** Current dev mode state */
|
|
2818
|
+
// prettier-ignore
|
|
2819
|
+
get $devMode() {
|
|
2820
|
+
return this.config.app.devMode;
|
|
2658
2821
|
}
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
2822
|
+
// prettier-ignore
|
|
2823
|
+
set $devMode(mode) {
|
|
2824
|
+
this.config.app.devMode = mode;
|
|
2662
2825
|
}
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2826
|
+
/** Current verbose mode state */
|
|
2827
|
+
// prettier-ignore
|
|
2828
|
+
get $verboseMode() {
|
|
2829
|
+
return this.config.app.verbose;
|
|
2666
2830
|
}
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2831
|
+
// prettier-ignore
|
|
2832
|
+
set $verboseMode(mode) {
|
|
2833
|
+
this.config.app.verbose = mode;
|
|
2670
2834
|
}
|
|
2671
|
-
|
|
2672
|
-
|
|
2673
|
-
return this;
|
|
2835
|
+
/** Returns the options, features, and config of this client. */
|
|
2836
|
+
toJSON() {
|
|
2837
|
+
return { options: this.clientOptions, features: this.features, config: this.config };
|
|
2674
2838
|
}
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2839
|
+
/** Makes a clone of this client. */
|
|
2840
|
+
clone() {
|
|
2841
|
+
const { options, features, config } = this.toJSON();
|
|
2842
|
+
return new _Vimcord(options, features, config);
|
|
2678
2843
|
}
|
|
2679
|
-
|
|
2680
|
-
|
|
2844
|
+
/**
|
|
2845
|
+
* Modifies a client config.
|
|
2846
|
+
* @param type The type of config to modify.
|
|
2847
|
+
* @param options The options to set for the config.
|
|
2848
|
+
*/
|
|
2849
|
+
configure(type, options = {}) {
|
|
2850
|
+
this.config[type] = configSetters[type](options, this.config[type]);
|
|
2681
2851
|
return this;
|
|
2682
2852
|
}
|
|
2683
|
-
|
|
2684
|
-
this.db = db;
|
|
2685
|
-
this.logger.database("Using", db.moduleName);
|
|
2686
|
-
return this.db.connect();
|
|
2687
|
-
}
|
|
2688
|
-
async waitForReady() {
|
|
2689
|
-
if (this.isReady()) return this;
|
|
2690
|
-
return new Promise((resolve, reject) => {
|
|
2691
|
-
const timeout = setTimeout(
|
|
2692
|
-
() => reject(new Error(`Client (i${this.clientId}) timed out waiting for ready`)),
|
|
2693
|
-
6e4
|
|
2694
|
-
);
|
|
2695
|
-
this.once("clientReady", () => {
|
|
2696
|
-
clearTimeout(timeout);
|
|
2697
|
-
resolve(this);
|
|
2698
|
-
});
|
|
2699
|
-
});
|
|
2700
|
-
}
|
|
2853
|
+
/** Builds the client by importing modules and registering builtin handlers. */
|
|
2701
2854
|
async build() {
|
|
2702
|
-
this.
|
|
2703
|
-
this.
|
|
2704
|
-
this.
|
|
2705
|
-
this.
|
|
2706
|
-
this.
|
|
2855
|
+
this.configure("app", this.config.app);
|
|
2856
|
+
this.configure("staff", this.config.staff);
|
|
2857
|
+
this.configure("slashCommands", this.config.slashCommands);
|
|
2858
|
+
this.configure("prefixCommands", this.config.prefixCommands);
|
|
2859
|
+
this.configure("contextCommands", this.config.contextCommands);
|
|
2707
2860
|
if (this.features.importModules) {
|
|
2708
2861
|
const importModules = this.features.importModules;
|
|
2709
2862
|
await Promise.all([
|
|
2710
|
-
importModules.events && this.
|
|
2711
|
-
importModules.slashCommands && this.
|
|
2712
|
-
importModules.prefixCommands && this.
|
|
2713
|
-
importModules.contextCommands && this.
|
|
2863
|
+
importModules.events && this.importModules("events", importModules.events),
|
|
2864
|
+
importModules.slashCommands && this.importModules("slashCommands", importModules.slashCommands),
|
|
2865
|
+
importModules.prefixCommands && this.importModules("prefixCommands", importModules.prefixCommands),
|
|
2866
|
+
importModules.contextCommands && this.importModules("contextCommands", importModules.contextCommands)
|
|
2714
2867
|
]);
|
|
2715
2868
|
}
|
|
2716
2869
|
if (this.features.useDefaultSlashCommandHandler) {
|
|
2717
|
-
this.events.register(
|
|
2870
|
+
this.events.register(slashCommandHandler);
|
|
2718
2871
|
}
|
|
2719
2872
|
if (this.features.useDefaultContextCommandHandler) {
|
|
2720
|
-
this.events.register(
|
|
2873
|
+
this.events.register(contextCommandHandler);
|
|
2721
2874
|
}
|
|
2722
2875
|
if (this.features.useDefaultPrefixCommandHandler) {
|
|
2723
|
-
this.events.register(
|
|
2876
|
+
this.events.register(prefixCommandHandler);
|
|
2724
2877
|
}
|
|
2725
2878
|
return this;
|
|
2726
2879
|
}
|
|
2727
|
-
|
|
2880
|
+
/**
|
|
2881
|
+
* Imports modules into the client.
|
|
2882
|
+
* @param type The type of modules to import.
|
|
2883
|
+
* @param options The options to import the module with.
|
|
2884
|
+
* @param set Replaces already imported modules with the ones found.
|
|
2885
|
+
*/
|
|
2886
|
+
async importModules(type, options, set) {
|
|
2887
|
+
await moduleImporters[type](this, options, set);
|
|
2888
|
+
return this;
|
|
2889
|
+
}
|
|
2890
|
+
/**
|
|
2891
|
+
* Allows Vimcord to handle environment variables using [dotenv](https://www.npmjs.com/package/dotenv).
|
|
2892
|
+
* @param options Options for dotenv
|
|
2893
|
+
* @see https://www.npmjs.com/package/dotenv
|
|
2894
|
+
*/
|
|
2895
|
+
useEnv(options) {
|
|
2896
|
+
this.logger.database("Using", "dotenv");
|
|
2897
|
+
configDotenv({ quiet: true, ...options });
|
|
2898
|
+
return this;
|
|
2899
|
+
}
|
|
2900
|
+
/**
|
|
2901
|
+
* Connects to a database.
|
|
2902
|
+
* @param db The database manager to use.
|
|
2903
|
+
*/
|
|
2904
|
+
async useDatabase(db) {
|
|
2905
|
+
this.db = db;
|
|
2906
|
+
this.logger.database("Using", db.moduleName);
|
|
2907
|
+
return this.db.connect();
|
|
2908
|
+
}
|
|
2909
|
+
/**
|
|
2910
|
+
* Fetches a user from the client, checking the cache first.
|
|
2911
|
+
* @param userId The ID of the user to fetch.
|
|
2912
|
+
*/
|
|
2913
|
+
async fetchUser(userId) {
|
|
2914
|
+
const client = await _Vimcord.getReadyInstance(this.clientId);
|
|
2915
|
+
return fetchUser(client, userId);
|
|
2916
|
+
}
|
|
2917
|
+
/**
|
|
2918
|
+
* Fetches a guild from the client, checking the cache first.
|
|
2919
|
+
* @param guildId The ID of the guild to fetch.
|
|
2920
|
+
*/
|
|
2921
|
+
async fetchGuild(guildId) {
|
|
2922
|
+
const client = await _Vimcord.getReadyInstance(this.clientId);
|
|
2923
|
+
return fetchGuild(client, guildId);
|
|
2924
|
+
}
|
|
2925
|
+
async start(tokenOrPreHook, callback) {
|
|
2728
2926
|
if (this.clientStartingPromise) return this.clientStartingPromise;
|
|
2729
|
-
const
|
|
2927
|
+
const execute = async () => {
|
|
2730
2928
|
let token = typeof tokenOrPreHook === "string" ? tokenOrPreHook : void 0;
|
|
2731
|
-
token ??= this
|
|
2929
|
+
token ??= this.$devMode ? process.env.TOKEN_DEV : process.env.TOKEN;
|
|
2732
2930
|
if (!token) {
|
|
2733
2931
|
throw new Error(
|
|
2734
|
-
`TOKEN Missing: ${this
|
|
2932
|
+
`TOKEN Missing: ${this.$devMode ? "devMode is enabled, but TOKEN_DEV is not set" : "TOKEN not set"}`
|
|
2735
2933
|
);
|
|
2736
2934
|
}
|
|
2737
2935
|
await this.build();
|
|
2738
2936
|
try {
|
|
2937
|
+
const stopLoader = this.logger.loader("Connecting to Discord...");
|
|
2938
|
+
const loginResult = await $4.async.retry(() => super.login(token), {
|
|
2939
|
+
retries: this.features.maxLoginAttempts ?? 3,
|
|
2940
|
+
delay: 1e3
|
|
2941
|
+
});
|
|
2942
|
+
stopLoader("Connected to Discord ");
|
|
2943
|
+
this.$verboseMode && this.logger.debug("Waiting for ready...");
|
|
2739
2944
|
if (typeof tokenOrPreHook === "function") {
|
|
2740
2945
|
await tokenOrPreHook(this);
|
|
2741
2946
|
} else {
|
|
2742
|
-
await
|
|
2947
|
+
await callback?.(this);
|
|
2743
2948
|
}
|
|
2744
|
-
const stopLoader = this.logger.loader("Connecting to Discord...");
|
|
2745
|
-
const loginResult = await $4.async.retry(() => super.login(token), this.features.loginAttempts ?? 3, 1e3);
|
|
2746
|
-
stopLoader("Connected to Discord ");
|
|
2747
|
-
this.config.app.verbose && this.logger.debug("\u23F3 Waiting for ready...");
|
|
2748
2949
|
return loginResult;
|
|
2749
2950
|
} catch (err) {
|
|
2750
2951
|
this.logger.error(
|
|
2751
|
-
`Failed to log into Discord after ${this.features.
|
|
2952
|
+
`Failed to log into Discord after ${this.features.maxLoginAttempts} attempt(s)`,
|
|
2752
2953
|
err
|
|
2753
2954
|
);
|
|
2754
2955
|
return null;
|
|
@@ -2756,29 +2957,27 @@ var Vimcord = class _Vimcord extends Client2 {
|
|
|
2756
2957
|
this.clientStartingPromise = null;
|
|
2757
2958
|
}
|
|
2758
2959
|
};
|
|
2759
|
-
this.clientStartingPromise =
|
|
2960
|
+
this.clientStartingPromise = execute();
|
|
2760
2961
|
return this.clientStartingPromise;
|
|
2761
2962
|
}
|
|
2963
|
+
/** Destroys the client and disconnects from Discord. */
|
|
2762
2964
|
async kill() {
|
|
2763
2965
|
await super.destroy();
|
|
2764
2966
|
_Vimcord.instances.delete(this.clientId);
|
|
2765
|
-
this.logger.debug("
|
|
2766
|
-
}
|
|
2767
|
-
/** Shortcut for {@link fetchUser tools.fetchUser} */
|
|
2768
|
-
async fetchUser(id) {
|
|
2769
|
-
const client = await this.waitForReady();
|
|
2770
|
-
return fetchUser(client, id);
|
|
2771
|
-
}
|
|
2772
|
-
/** Shortcut for {@link fetchGuild tools.fetchGuild} */
|
|
2773
|
-
async fetchGuild(id) {
|
|
2774
|
-
const client = await this.waitForReady();
|
|
2775
|
-
return fetchGuild(client, id);
|
|
2967
|
+
this.logger.debug("Logged out of Discord");
|
|
2776
2968
|
}
|
|
2777
2969
|
};
|
|
2778
2970
|
|
|
2779
|
-
// src/
|
|
2971
|
+
// src/db/mongo/mongo-schema.builder.ts
|
|
2972
|
+
import {
|
|
2973
|
+
Schema
|
|
2974
|
+
} from "mongoose";
|
|
2975
|
+
import { randomBytes } from "crypto";
|
|
2976
|
+
import { $ as $6 } from "qznt";
|
|
2977
|
+
|
|
2978
|
+
// src/db/mongo/mongo.database.ts
|
|
2780
2979
|
import mongoose, { ConnectionStates } from "mongoose";
|
|
2781
|
-
import
|
|
2980
|
+
import EventEmitter3 from "events";
|
|
2782
2981
|
import { $ as $5 } from "qznt";
|
|
2783
2982
|
try {
|
|
2784
2983
|
import("mongoose");
|
|
@@ -2787,7 +2986,7 @@ try {
|
|
|
2787
2986
|
}
|
|
2788
2987
|
var MongoDatabase = class _MongoDatabase {
|
|
2789
2988
|
static instances = /* @__PURE__ */ new Map();
|
|
2790
|
-
static emitter = new
|
|
2989
|
+
static emitter = new EventEmitter3();
|
|
2791
2990
|
moduleName = "MongoDatabase";
|
|
2792
2991
|
clientId;
|
|
2793
2992
|
client;
|
|
@@ -2872,10 +3071,9 @@ var MongoDatabase = class _MongoDatabase {
|
|
|
2872
3071
|
this.isConnecting = true;
|
|
2873
3072
|
try {
|
|
2874
3073
|
const stopLoader = this.client.logger.loader("Connecting to MongoDB...");
|
|
2875
|
-
await $5.async.retry(
|
|
2876
|
-
|
|
2877
|
-
|
|
2878
|
-
);
|
|
3074
|
+
await $5.async.retry(() => this.mongoose.connect(connectionUri, { autoIndex: true, ...connectionOptions }), {
|
|
3075
|
+
retries: maxRetries
|
|
3076
|
+
});
|
|
2879
3077
|
_MongoDatabase.emitter.emit("ready", this);
|
|
2880
3078
|
stopLoader("Connected to MongoDB ");
|
|
2881
3079
|
} catch (err) {
|
|
@@ -2906,12 +3104,7 @@ var MongoDatabase = class _MongoDatabase {
|
|
|
2906
3104
|
}
|
|
2907
3105
|
};
|
|
2908
3106
|
|
|
2909
|
-
// src/
|
|
2910
|
-
import {
|
|
2911
|
-
Schema
|
|
2912
|
-
} from "mongoose";
|
|
2913
|
-
import { randomBytes } from "crypto";
|
|
2914
|
-
import { $ as $6 } from "qznt";
|
|
3107
|
+
// src/db/mongo/mongo-schema.builder.ts
|
|
2915
3108
|
try {
|
|
2916
3109
|
import("mongoose");
|
|
2917
3110
|
} catch {
|
|
@@ -2997,10 +3190,13 @@ var MongoSchemaBuilder = class _MongoSchemaBuilder {
|
|
|
2997
3190
|
* @param maxRetries [default: 3]
|
|
2998
3191
|
*/
|
|
2999
3192
|
async execute(fn, maxRetries = 3) {
|
|
3000
|
-
return await $6.async.retry(
|
|
3001
|
-
|
|
3002
|
-
|
|
3003
|
-
|
|
3193
|
+
return await $6.async.retry(
|
|
3194
|
+
async () => {
|
|
3195
|
+
const model = await this.getModel();
|
|
3196
|
+
return await fn(model);
|
|
3197
|
+
},
|
|
3198
|
+
{ retries: maxRetries }
|
|
3199
|
+
);
|
|
3004
3200
|
}
|
|
3005
3201
|
async startSession(options) {
|
|
3006
3202
|
return await this.execute(async () => {
|
|
@@ -3630,7 +3826,7 @@ import {
|
|
|
3630
3826
|
EmbedBuilder as EmbedBuilder2,
|
|
3631
3827
|
StringSelectMenuBuilder as StringSelectMenuBuilder2
|
|
3632
3828
|
} from "discord.js";
|
|
3633
|
-
import
|
|
3829
|
+
import EventEmitter4 from "events";
|
|
3634
3830
|
var PaginationType = /* @__PURE__ */ ((PaginationType2) => {
|
|
3635
3831
|
PaginationType2[PaginationType2["Short"] = 0] = "Short";
|
|
3636
3832
|
PaginationType2[PaginationType2["ShortJump"] = 1] = "ShortJump";
|
|
@@ -3675,7 +3871,7 @@ var Paginator = class {
|
|
|
3675
3871
|
config;
|
|
3676
3872
|
data;
|
|
3677
3873
|
events;
|
|
3678
|
-
eventEmitter = new
|
|
3874
|
+
eventEmitter = new EventEmitter4();
|
|
3679
3875
|
constructor(options = {}) {
|
|
3680
3876
|
this.config = options.config ? createToolsConfig(options.config) : globalToolsConfig;
|
|
3681
3877
|
this.options = {
|
|
@@ -4291,9 +4487,6 @@ async function prompt(handler, options, sendOptions) {
|
|
|
4291
4487
|
return await p.awaitResponse();
|
|
4292
4488
|
}
|
|
4293
4489
|
export {
|
|
4294
|
-
BUILTIN_ContextCommandHandler,
|
|
4295
|
-
BUILTIN_PrefixCommandHandler,
|
|
4296
|
-
BUILTIN_SlashCommandHandler,
|
|
4297
4490
|
BaseCommandBuilder,
|
|
4298
4491
|
BaseCommandManager,
|
|
4299
4492
|
BetterCollector,
|
|
@@ -4306,13 +4499,16 @@ export {
|
|
|
4306
4499
|
CommandType,
|
|
4307
4500
|
ContextCommandBuilder,
|
|
4308
4501
|
ContextCommandManager,
|
|
4502
|
+
DEFAULT_MODULE_SUFFIXES,
|
|
4309
4503
|
DynaSend,
|
|
4504
|
+
ErrorHandler,
|
|
4310
4505
|
EventBuilder,
|
|
4311
4506
|
EventManager,
|
|
4312
4507
|
LOGGER_COLORS,
|
|
4313
4508
|
LogLevel,
|
|
4314
4509
|
Logger,
|
|
4315
4510
|
MissingPermissionReason,
|
|
4511
|
+
ModuleImporter,
|
|
4316
4512
|
MongoDatabase,
|
|
4317
4513
|
MongoSchemaBuilder,
|
|
4318
4514
|
PaginationTimeoutType,
|
|
@@ -4332,8 +4528,12 @@ export {
|
|
|
4332
4528
|
VimcordCLI,
|
|
4333
4529
|
__zero,
|
|
4334
4530
|
cleanMention,
|
|
4531
|
+
clientLoggerFactory,
|
|
4532
|
+
configSetters,
|
|
4533
|
+
contextCommandHandler,
|
|
4335
4534
|
createAppConfig,
|
|
4336
4535
|
createClient,
|
|
4536
|
+
createConfigFactory,
|
|
4337
4537
|
createContextCommandConfig,
|
|
4338
4538
|
createMongoPlugin,
|
|
4339
4539
|
createMongoSchema,
|
|
@@ -4342,7 +4542,10 @@ export {
|
|
|
4342
4542
|
createStaffConfig,
|
|
4343
4543
|
createToolsConfig,
|
|
4344
4544
|
createVimcordStatusConfig,
|
|
4545
|
+
defineClientOptions,
|
|
4345
4546
|
defineGlobalToolsConfig,
|
|
4547
|
+
defineVimcordConfig,
|
|
4548
|
+
defineVimcordFeatures,
|
|
4346
4549
|
dynaSend,
|
|
4347
4550
|
fetchChannel,
|
|
4348
4551
|
fetchGuild,
|
|
@@ -4350,17 +4553,20 @@ export {
|
|
|
4350
4553
|
fetchMessage,
|
|
4351
4554
|
fetchRole,
|
|
4352
4555
|
fetchUser,
|
|
4353
|
-
|
|
4556
|
+
getDevMode,
|
|
4354
4557
|
getFirstMentionId,
|
|
4355
4558
|
getMessageMention,
|
|
4559
|
+
getPackageJson,
|
|
4356
4560
|
getProcessDir,
|
|
4357
4561
|
globalToolsConfig,
|
|
4358
4562
|
importModulesFromDir,
|
|
4359
|
-
initCLI,
|
|
4360
4563
|
isMentionOrSnowflake,
|
|
4361
4564
|
logger,
|
|
4565
|
+
moduleImporters,
|
|
4566
|
+
prefixCommandHandler,
|
|
4362
4567
|
prompt,
|
|
4363
4568
|
sendCommandErrorEmbed,
|
|
4569
|
+
slashCommandHandler,
|
|
4364
4570
|
useClient,
|
|
4365
4571
|
useReadyClient,
|
|
4366
4572
|
validateCommandPermissions
|