vimcord 1.0.36 → 1.0.38
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 +1238 -1016
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +742 -411
- package/dist/index.d.ts +742 -411
- package/dist/index.js +1213 -1001
- 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,23 +969,121 @@ 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
|
-
|
|
841
|
-
|
|
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
|
|
1086
|
+
},
|
|
842
1087
|
collector: {
|
|
843
1088
|
notAParticipantMessage: "You are not allowed to use this.",
|
|
844
1089
|
userLockMessage: "Please wait until your current action is finished.",
|
|
@@ -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,332 @@ ${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.38";
|
|
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;
|
|
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: {}
|
|
1786
1791
|
}
|
|
1787
|
-
}
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1792
|
+
};
|
|
1793
|
+
var createStaffConfig = createConfigFactory(defaultConfig5);
|
|
1794
|
+
|
|
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
|
+
contextCommands: createContextCommandConfig,
|
|
1807
|
+
prefixCommands: createPrefixCommandConfig
|
|
1808
|
+
};
|
|
1809
|
+
var moduleImporters = {
|
|
1810
|
+
slashCommands: (client, options, set) => {
|
|
1811
|
+
const opt = options;
|
|
1812
|
+
const dir = Array.isArray(options) ? options : typeof options === "string" ? options : options?.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);
|
|
1815
|
+
},
|
|
1816
|
+
contextCommands: (client, options, set) => {
|
|
1817
|
+
const opt = options;
|
|
1818
|
+
const dir = Array.isArray(options) ? options : typeof options === "string" ? options : options?.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 : typeof options === "string" ? options : options?.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 : typeof options === "string" ? options : options?.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);
|
|
1802
1833
|
}
|
|
1803
|
-
|
|
1804
|
-
|
|
1834
|
+
};
|
|
1835
|
+
function defineClientOptions(options) {
|
|
1836
|
+
return options;
|
|
1805
1837
|
}
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
return client.users.cache.get(__zero(userId)) || await client.users.fetch(__zero(userId)).catch(() => null);
|
|
1838
|
+
function defineVimcordFeatures(features) {
|
|
1839
|
+
return features;
|
|
1809
1840
|
}
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
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
|
+
};
|
|
1813
1849
|
}
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
return guild.members.cache.get(__zero(memberId)) || await guild.members.fetch(__zero(memberId)).catch(() => null);
|
|
1850
|
+
function useClient(clientId) {
|
|
1851
|
+
return Vimcord.getInstance(clientId);
|
|
1817
1852
|
}
|
|
1818
|
-
|
|
1819
|
-
|
|
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;
|
|
1853
|
+
function useReadyClient(clientId, timeoutMs) {
|
|
1854
|
+
return Vimcord.getReadyInstance(clientId, timeoutMs);
|
|
1823
1855
|
}
|
|
1824
|
-
|
|
1825
|
-
|
|
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;
|
|
1856
|
+
function createClient(options, features, config) {
|
|
1857
|
+
return Vimcord.create(options, features, config);
|
|
1831
1858
|
}
|
|
1832
1859
|
|
|
1833
|
-
// src/
|
|
1834
|
-
import {
|
|
1835
|
-
import _11 from "lodash";
|
|
1836
|
-
var StatusType = /* @__PURE__ */ ((StatusType2) => {
|
|
1837
|
-
StatusType2["DND"] = "dnd";
|
|
1838
|
-
StatusType2["Idle"] = "idle";
|
|
1839
|
-
StatusType2["Online"] = "online";
|
|
1840
|
-
StatusType2["Invisible"] = "invisible";
|
|
1841
|
-
return StatusType2;
|
|
1842
|
-
})(StatusType || {});
|
|
1843
|
-
var defaultPresence = {
|
|
1844
|
-
production: {
|
|
1845
|
-
interval: 6e4,
|
|
1846
|
-
randomize: false,
|
|
1847
|
-
activity: [
|
|
1848
|
-
{ status: "online" /* Online */, type: ActivityType.Custom, name: "Need help? Use /help or !help" },
|
|
1849
|
-
{ status: "online" /* Online */, type: ActivityType.Custom, name: "Join our community!" },
|
|
1850
|
-
{ status: "online" /* Online */, type: ActivityType.Watching, name: "\u2728 $GUILD_COUNT servers" }
|
|
1851
|
-
]
|
|
1852
|
-
},
|
|
1853
|
-
development: {
|
|
1854
|
-
activity: { status: "dnd" /* DND */, type: ActivityType.Custom, name: "In development!" }
|
|
1855
|
-
}
|
|
1856
|
-
};
|
|
1857
|
-
function createVimcordStatusConfig(options = {}) {
|
|
1858
|
-
return _11.merge(defaultPresence, options);
|
|
1859
|
-
}
|
|
1860
|
+
// src/modules/command.manager.ts
|
|
1861
|
+
import { Routes } from "discord.js";
|
|
1860
1862
|
|
|
1861
|
-
// src/
|
|
1862
|
-
import
|
|
1863
|
-
import { $
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
this.logger.debug(`Status changed to '${activity.name}'`);
|
|
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;
|
|
1863
|
+
// src/utils/import.utils.ts
|
|
1864
|
+
import path from "path";
|
|
1865
|
+
import { $ } from "qznt";
|
|
1866
|
+
function getProcessDir() {
|
|
1867
|
+
const mainPath = process.argv[1];
|
|
1868
|
+
if (!mainPath) return "";
|
|
1869
|
+
return path.dirname(mainPath);
|
|
1870
|
+
}
|
|
1871
|
+
async function importModulesFromDir(dir, suffix) {
|
|
1872
|
+
const cwd = getProcessDir();
|
|
1873
|
+
const MODULE_RELATIVE_PATH = path.join(cwd, dir);
|
|
1874
|
+
const MODULE_LOG_PATH = dir;
|
|
1875
|
+
const files = $.fs.readDir(MODULE_RELATIVE_PATH).filter((fn) => fn.endsWith(`${suffix ? `${suffix}` : ""}.js`) || fn.endsWith(`${suffix ? `${suffix}` : ""}.ts`));
|
|
1876
|
+
if (!files.length) {
|
|
1877
|
+
return [];
|
|
1943
1878
|
}
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1879
|
+
const modules = await Promise.all(
|
|
1880
|
+
files.map(async (fn) => {
|
|
1881
|
+
let _path = path.join(MODULE_RELATIVE_PATH, fn);
|
|
1882
|
+
let _logPath = `./${path.join(MODULE_LOG_PATH, fn)}`;
|
|
1883
|
+
let _module;
|
|
1884
|
+
try {
|
|
1885
|
+
delete __require.cache[__require.resolve(_path)];
|
|
1886
|
+
_module = __require(_path);
|
|
1887
|
+
} catch (err) {
|
|
1888
|
+
console.warn(`Failed to import module at '${_logPath}'`, err);
|
|
1889
|
+
_module = null;
|
|
1890
|
+
}
|
|
1891
|
+
return { module: _module, path: _logPath };
|
|
1892
|
+
})
|
|
1893
|
+
);
|
|
1894
|
+
const filteredModules = modules.filter((m) => m.module);
|
|
1895
|
+
if (!filteredModules.length) {
|
|
1896
|
+
console.warn(`No valid modules were found in directory '${dir}'`);
|
|
1950
1897
|
}
|
|
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;
|
|
1898
|
+
return filteredModules;
|
|
1899
|
+
}
|
|
1900
|
+
|
|
1901
|
+
// src/modules/base-module.importer.ts
|
|
1902
|
+
var ModuleImporter = class {
|
|
1903
|
+
client;
|
|
1904
|
+
constructor(client) {
|
|
1905
|
+
this.client = client;
|
|
1965
1906
|
}
|
|
1966
|
-
async
|
|
1967
|
-
if (this.
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1907
|
+
async importFrom(dir, set = false, suffix) {
|
|
1908
|
+
if (set) this.items.clear();
|
|
1909
|
+
const dirs = Array.isArray(dir) ? dir : [dir];
|
|
1910
|
+
const modules = [];
|
|
1911
|
+
const effectiveSuffix = Array.isArray(suffix) ? suffix[0] : suffix ?? this.itemSuffix;
|
|
1912
|
+
for (const _dir of dirs) {
|
|
1913
|
+
const results = await importModulesFromDir(_dir, effectiveSuffix ?? void 0);
|
|
1914
|
+
modules.push(...results.map(({ module }) => module.default));
|
|
1972
1915
|
}
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
this.
|
|
1978
|
-
|
|
1979
|
-
this.emitter.emit("cleared");
|
|
1980
|
-
return this;
|
|
1916
|
+
for (const module of modules) {
|
|
1917
|
+
const name = this.getName(module);
|
|
1918
|
+
this.items.set(name, module);
|
|
1919
|
+
}
|
|
1920
|
+
this.client.logger.moduleLoaded(this.itemName, modules.length);
|
|
1921
|
+
return this.items;
|
|
1981
1922
|
}
|
|
1982
1923
|
};
|
|
1983
1924
|
|
|
1984
1925
|
// src/modules/command.manager.ts
|
|
1985
|
-
|
|
1986
|
-
var BaseCommandManager = class {
|
|
1926
|
+
var BaseCommandManager = class extends ModuleImporter {
|
|
1987
1927
|
type;
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1928
|
+
items = /* @__PURE__ */ new Map();
|
|
1929
|
+
itemSuffix;
|
|
1930
|
+
constructor(client, type, itemSuffix) {
|
|
1931
|
+
super(client);
|
|
1992
1932
|
this.type = type;
|
|
1993
|
-
|
|
1994
|
-
|
|
1933
|
+
switch (type) {
|
|
1934
|
+
case 0 /* Slash */:
|
|
1935
|
+
this.itemSuffix = itemSuffix ?? DEFAULT_MODULE_SUFFIXES.slashCommands;
|
|
1936
|
+
break;
|
|
1937
|
+
case 2 /* Context */:
|
|
1938
|
+
this.itemSuffix = itemSuffix ?? DEFAULT_MODULE_SUFFIXES.contextCommands;
|
|
1939
|
+
break;
|
|
1940
|
+
case 1 /* Prefix */:
|
|
1941
|
+
this.itemSuffix = itemSuffix ?? DEFAULT_MODULE_SUFFIXES.prefixCommands;
|
|
1942
|
+
break;
|
|
1943
|
+
}
|
|
1944
|
+
}
|
|
1945
|
+
get commands() {
|
|
1946
|
+
return this.items;
|
|
1947
|
+
}
|
|
1948
|
+
get itemName() {
|
|
1949
|
+
switch (this.type) {
|
|
1950
|
+
case 0 /* Slash */:
|
|
1951
|
+
return "Slash Commands";
|
|
1952
|
+
case 2 /* Context */:
|
|
1953
|
+
return "Context Commands";
|
|
1954
|
+
case 1 /* Prefix */:
|
|
1955
|
+
return "Prefix Commands";
|
|
1956
|
+
}
|
|
1957
|
+
}
|
|
1958
|
+
getName(module) {
|
|
1959
|
+
return "builder" in module ? module.builder.name : module.options.name;
|
|
1995
1960
|
}
|
|
1996
1961
|
/**
|
|
1997
1962
|
* Gets a command by name.
|
|
@@ -2000,7 +1965,7 @@ var BaseCommandManager = class {
|
|
|
2000
1965
|
if (this.type === 1 /* Prefix */) {
|
|
2001
1966
|
const config = this.client.config.prefixCommands;
|
|
2002
1967
|
const search = config.allowCaseInsensitiveCommandNames ? name.toLowerCase() : name;
|
|
2003
|
-
return Array.from(this.
|
|
1968
|
+
return Array.from(this.items.values()).find((cmd) => {
|
|
2004
1969
|
const commandName = "builder" in cmd ? cmd.builder.name : cmd.options.name;
|
|
2005
1970
|
const trigger = config.allowCaseInsensitiveCommandNames ? commandName.toLowerCase() : commandName;
|
|
2006
1971
|
if (trigger === search) return true;
|
|
@@ -2011,7 +1976,7 @@ var BaseCommandManager = class {
|
|
|
2011
1976
|
}
|
|
2012
1977
|
});
|
|
2013
1978
|
} else {
|
|
2014
|
-
return this.
|
|
1979
|
+
return this.items.get(name);
|
|
2015
1980
|
}
|
|
2016
1981
|
}
|
|
2017
1982
|
/**
|
|
@@ -2020,7 +1985,7 @@ var BaseCommandManager = class {
|
|
|
2020
1985
|
getAll(options = {}) {
|
|
2021
1986
|
const matchedCommands = /* @__PURE__ */ new Map();
|
|
2022
1987
|
const isDev = this.client.config.app.devMode;
|
|
2023
|
-
for (const cmd of this.
|
|
1988
|
+
for (const cmd of this.items.values()) {
|
|
2024
1989
|
const commandName = "builder" in cmd ? cmd.builder.name : cmd.options.name;
|
|
2025
1990
|
if (options.names || options.fuzzyNames) {
|
|
2026
1991
|
const nameMatched = options.names?.includes(commandName) || options.fuzzyNames?.some((fuzzy) => commandName.includes(fuzzy));
|
|
@@ -2047,7 +2012,7 @@ var BaseCommandManager = class {
|
|
|
2047
2012
|
*/
|
|
2048
2013
|
sortByCategory() {
|
|
2049
2014
|
const categories = /* @__PURE__ */ new Map();
|
|
2050
|
-
for (const cmd of this.
|
|
2015
|
+
for (const cmd of this.items.values()) {
|
|
2051
2016
|
const metadata = cmd.options.metadata;
|
|
2052
2017
|
if (!metadata?.category) continue;
|
|
2053
2018
|
let entry = categories.get(metadata.category);
|
|
@@ -2070,52 +2035,20 @@ var BaseCommandManager = class {
|
|
|
2070
2035
|
return cat;
|
|
2071
2036
|
});
|
|
2072
2037
|
}
|
|
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
2038
|
};
|
|
2106
2039
|
var SlashCommandManager = class extends BaseCommandManager {
|
|
2107
2040
|
constructor(client) {
|
|
2108
|
-
super(client, 0 /* Slash
|
|
2041
|
+
super(client, 0 /* Slash */);
|
|
2109
2042
|
}
|
|
2110
2043
|
};
|
|
2111
2044
|
var ContextCommandManager = class extends BaseCommandManager {
|
|
2112
2045
|
constructor(client) {
|
|
2113
|
-
super(client, 2 /* Context
|
|
2046
|
+
super(client, 2 /* Context */);
|
|
2114
2047
|
}
|
|
2115
2048
|
};
|
|
2116
2049
|
var PrefixCommandManager = class extends BaseCommandManager {
|
|
2117
2050
|
constructor(client) {
|
|
2118
|
-
super(client, 1 /* Prefix
|
|
2051
|
+
super(client, 1 /* Prefix */);
|
|
2119
2052
|
}
|
|
2120
2053
|
};
|
|
2121
2054
|
var CommandManager = class {
|
|
@@ -2133,7 +2066,7 @@ var CommandManager = class {
|
|
|
2133
2066
|
return [...this.slash.getAll(options), ...this.context.getAll(options)];
|
|
2134
2067
|
}
|
|
2135
2068
|
async registerGlobal(options = {}) {
|
|
2136
|
-
const client = await this.client.
|
|
2069
|
+
const client = await Vimcord.getReadyInstance(this.client.clientId);
|
|
2137
2070
|
if (!client.rest) {
|
|
2138
2071
|
console.error(`[CommandManager] \u2716 Failed to register app commands globally: REST is not initialized`);
|
|
2139
2072
|
return;
|
|
@@ -2157,7 +2090,7 @@ var CommandManager = class {
|
|
|
2157
2090
|
}
|
|
2158
2091
|
}
|
|
2159
2092
|
async unregisterGlobal() {
|
|
2160
|
-
const client = await this.client.
|
|
2093
|
+
const client = await Vimcord.getReadyInstance(this.client.clientId);
|
|
2161
2094
|
if (!client.rest) {
|
|
2162
2095
|
console.error(`[CommandManager] \u2716 Failed to remove app commands globally: REST is not initialized`);
|
|
2163
2096
|
return;
|
|
@@ -2170,7 +2103,7 @@ var CommandManager = class {
|
|
|
2170
2103
|
}
|
|
2171
2104
|
}
|
|
2172
2105
|
async registerGuild(options = {}) {
|
|
2173
|
-
const client = await this.client.
|
|
2106
|
+
const client = await Vimcord.getReadyInstance(this.client.clientId);
|
|
2174
2107
|
if (!client.rest) {
|
|
2175
2108
|
console.error(`[CommandManager] \u2716 Failed to register app commands by guild: REST is not initialized`);
|
|
2176
2109
|
return;
|
|
@@ -2202,7 +2135,7 @@ var CommandManager = class {
|
|
|
2202
2135
|
);
|
|
2203
2136
|
}
|
|
2204
2137
|
async unregisterGuild(options = {}) {
|
|
2205
|
-
const client = await this.client.
|
|
2138
|
+
const client = await Vimcord.getReadyInstance(this.client.clientId);
|
|
2206
2139
|
if (!client.rest) {
|
|
2207
2140
|
console.error(`[CommandManager] \u2716 Failed to register app commands by guild: REST is not initialized`);
|
|
2208
2141
|
return;
|
|
@@ -2219,12 +2152,13 @@ var CommandManager = class {
|
|
|
2219
2152
|
|
|
2220
2153
|
// src/modules/event.manager.ts
|
|
2221
2154
|
import { Events } from "discord.js";
|
|
2222
|
-
var EventManager = class {
|
|
2223
|
-
|
|
2224
|
-
|
|
2155
|
+
var EventManager = class extends ModuleImporter {
|
|
2156
|
+
items = /* @__PURE__ */ new Map();
|
|
2157
|
+
itemSuffix = "event";
|
|
2158
|
+
itemName = "Event Handlers";
|
|
2225
2159
|
logger;
|
|
2226
2160
|
constructor(client) {
|
|
2227
|
-
|
|
2161
|
+
super(client);
|
|
2228
2162
|
this.logger = new Logger({ prefixEmoji: "\u{1F4CB}", prefix: `EventManager (i${this.client.clientId})` });
|
|
2229
2163
|
for (const event of Object.values(Events)) {
|
|
2230
2164
|
client.on(
|
|
@@ -2233,105 +2167,361 @@ var EventManager = class {
|
|
|
2233
2167
|
);
|
|
2234
2168
|
}
|
|
2235
2169
|
}
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2170
|
+
getName(module) {
|
|
2171
|
+
return module.name;
|
|
2172
|
+
}
|
|
2173
|
+
register(...events) {
|
|
2174
|
+
for (const event of events) {
|
|
2175
|
+
this.items.set(event.name, event);
|
|
2176
|
+
if (this.client.config.app.verbose) {
|
|
2177
|
+
this.logger.debug(`'${event.name}' registered for EventType '${event.event}'`);
|
|
2178
|
+
}
|
|
2179
|
+
}
|
|
2180
|
+
}
|
|
2181
|
+
unregister(...names) {
|
|
2182
|
+
for (const name of names) {
|
|
2183
|
+
const event = this.items.get(name);
|
|
2184
|
+
if (!event) continue;
|
|
2185
|
+
this.items.delete(name);
|
|
2186
|
+
if (this.client.config.app.verbose) {
|
|
2187
|
+
this.logger.debug(`'${event.name}' unregistered for EventType '${event.event}'`);
|
|
2188
|
+
}
|
|
2189
|
+
}
|
|
2190
|
+
}
|
|
2191
|
+
clear() {
|
|
2192
|
+
this.items.forEach((e) => this.unregister(e.name));
|
|
2193
|
+
this.items.clear();
|
|
2194
|
+
}
|
|
2195
|
+
get(name) {
|
|
2196
|
+
return this.items.get(name);
|
|
2197
|
+
}
|
|
2198
|
+
getByTag(tag) {
|
|
2199
|
+
return Array.from(this.items.values()).filter((event) => event.metadata?.tags?.includes(tag));
|
|
2200
|
+
}
|
|
2201
|
+
getByCategory(category) {
|
|
2202
|
+
return Array.from(this.items.values()).filter((event) => event.metadata?.category?.includes(category));
|
|
2203
|
+
}
|
|
2204
|
+
getByEvent(eventType) {
|
|
2205
|
+
return Array.from(this.items.values()).filter((event) => event.event === eventType);
|
|
2206
|
+
}
|
|
2207
|
+
async executeEvents(eventType, ...args) {
|
|
2208
|
+
const events = this.getByEvent(eventType);
|
|
2209
|
+
if (!events.length) return;
|
|
2210
|
+
const sortedEvents = events.sort((a, b) => b.priority - a.priority);
|
|
2211
|
+
await Promise.all(
|
|
2212
|
+
sortedEvents.map(async (event) => {
|
|
2213
|
+
try {
|
|
2214
|
+
await event.execute?.(this.client, ...args);
|
|
2215
|
+
if (event.once) {
|
|
2216
|
+
this.unregister(event.name);
|
|
2217
|
+
}
|
|
2218
|
+
} catch (err) {
|
|
2219
|
+
this.logger.error(`'${event.name}' failed to execute`, err);
|
|
2220
|
+
}
|
|
2221
|
+
})
|
|
2222
|
+
);
|
|
2223
|
+
}
|
|
2224
|
+
};
|
|
2225
|
+
|
|
2226
|
+
// src/tools/utils.ts
|
|
2227
|
+
var MENTION_OR_SNOWFLAKE_REGEX = /<@[#&]?[\d]{6,}>|[\d]{6,}/;
|
|
2228
|
+
var fetchUserPromises = /* @__PURE__ */ new Map();
|
|
2229
|
+
var fetchGuildPromises = /* @__PURE__ */ new Map();
|
|
2230
|
+
var fetchMemberPromises = /* @__PURE__ */ new Map();
|
|
2231
|
+
var fetchChannelPromises = /* @__PURE__ */ new Map();
|
|
2232
|
+
var fetchMessagePromises = /* @__PURE__ */ new Map();
|
|
2233
|
+
var fetchRolePromises = /* @__PURE__ */ new Map();
|
|
2234
|
+
function createCachedFetch(cache, fetchFn, cacheKey) {
|
|
2235
|
+
const cached = cache.get(cacheKey);
|
|
2236
|
+
if (cached) return cached;
|
|
2237
|
+
const promise = fetchFn().finally(() => cache.delete(cacheKey));
|
|
2238
|
+
cache.set(cacheKey, promise);
|
|
2239
|
+
return promise;
|
|
2240
|
+
}
|
|
2241
|
+
function __zero(str) {
|
|
2242
|
+
return str?.length ? str : "0";
|
|
2243
|
+
}
|
|
2244
|
+
function isMentionOrSnowflake(str) {
|
|
2245
|
+
return str ? MENTION_OR_SNOWFLAKE_REGEX.test(str) : false;
|
|
2246
|
+
}
|
|
2247
|
+
function cleanMention(str) {
|
|
2248
|
+
return str ? str.replaceAll(/[<@#&>]/g, "").trim() : void 0;
|
|
2249
|
+
}
|
|
2250
|
+
async function getMessageMention(message, content, type, index = 0, idOnly) {
|
|
2251
|
+
const args = content?.split(" ");
|
|
2252
|
+
const arg = isMentionOrSnowflake(args?.[index]) ? cleanMention(args?.[index]) : void 0;
|
|
2253
|
+
switch (type) {
|
|
2254
|
+
case "user": {
|
|
2255
|
+
const userMention2 = message.mentions.users.at(index) || null;
|
|
2256
|
+
if (!userMention2 && arg) {
|
|
2257
|
+
return idOnly ? arg : await fetchUser(message.client, arg);
|
|
2258
|
+
}
|
|
2259
|
+
return idOnly ? userMention2?.id || null : userMention2;
|
|
2260
|
+
}
|
|
2261
|
+
case "member": {
|
|
2262
|
+
if (!message.guild) return null;
|
|
2263
|
+
const member = await fetchMember(message.guild, message.mentions.users.at(index)?.id ?? arg);
|
|
2264
|
+
return idOnly ? member?.id || null : member;
|
|
2265
|
+
}
|
|
2266
|
+
case "channel": {
|
|
2267
|
+
const channelMention = message.mentions.channels.at(index) || null;
|
|
2268
|
+
if (!channelMention && arg) {
|
|
2269
|
+
if (idOnly) return arg;
|
|
2270
|
+
const channel = message.guild ? await fetchChannel(message.guild, arg) : message.client.channels.cache.get(__zero(arg)) ?? message.client.channels.fetch(__zero(arg));
|
|
2271
|
+
return channel;
|
|
2272
|
+
}
|
|
2273
|
+
return idOnly ? channelMention?.id || null : channelMention;
|
|
2274
|
+
}
|
|
2275
|
+
case "role": {
|
|
2276
|
+
const roleMention = message.mentions.roles.at(index) || null;
|
|
2277
|
+
if (!roleMention && arg) {
|
|
2278
|
+
if (idOnly) return arg;
|
|
2279
|
+
return message.guild ? await fetchRole(message.guild, arg) : null;
|
|
2280
|
+
}
|
|
2281
|
+
return idOnly ? roleMention?.id || null : roleMention;
|
|
2282
|
+
}
|
|
2283
|
+
default:
|
|
2284
|
+
return null;
|
|
2285
|
+
}
|
|
2286
|
+
}
|
|
2287
|
+
function getFirstMentionId(options) {
|
|
2288
|
+
let mentionId = "";
|
|
2289
|
+
if (options.message) {
|
|
2290
|
+
switch (options.type) {
|
|
2291
|
+
case "user":
|
|
2292
|
+
mentionId = options.message.mentions.users.first()?.id || "";
|
|
2293
|
+
break;
|
|
2294
|
+
case "member":
|
|
2295
|
+
mentionId = options.message.mentions.members?.first()?.id || "";
|
|
2296
|
+
break;
|
|
2297
|
+
case "channel":
|
|
2298
|
+
mentionId = options.message.mentions.channels.first()?.id || "";
|
|
2299
|
+
break;
|
|
2300
|
+
case "role":
|
|
2301
|
+
mentionId = options.message.mentions.roles.first()?.id || "";
|
|
2302
|
+
break;
|
|
2303
|
+
}
|
|
2304
|
+
}
|
|
2305
|
+
const firstArg = options.content?.split(" ")[0] || "";
|
|
2306
|
+
return mentionId || isMentionOrSnowflake(firstArg) ? cleanMention(firstArg) : "";
|
|
2307
|
+
}
|
|
2308
|
+
async function fetchUser(client, userId) {
|
|
2309
|
+
if (!userId) return null;
|
|
2310
|
+
const key = `${client.user.id}-${userId}`;
|
|
2311
|
+
const cached = client.users.cache.get(__zero(userId));
|
|
2312
|
+
if (cached) return cached;
|
|
2313
|
+
return createCachedFetch(fetchUserPromises, () => client.users.fetch(__zero(userId)).catch(() => null), key);
|
|
2314
|
+
}
|
|
2315
|
+
async function fetchGuild(client, guildId) {
|
|
2316
|
+
if (!guildId) return null;
|
|
2317
|
+
const key = `${client.user.id}-${guildId}`;
|
|
2318
|
+
const cached = client.guilds.cache.get(__zero(guildId));
|
|
2319
|
+
if (cached) return cached;
|
|
2320
|
+
return createCachedFetch(fetchGuildPromises, () => client.guilds.fetch(__zero(guildId)).catch(() => null), key);
|
|
2321
|
+
}
|
|
2322
|
+
async function fetchMember(guild, memberId) {
|
|
2323
|
+
if (!memberId) return null;
|
|
2324
|
+
const key = `${guild.id}-${memberId}`;
|
|
2325
|
+
const cached = guild.members.cache.get(__zero(memberId));
|
|
2326
|
+
if (cached) return cached;
|
|
2327
|
+
return createCachedFetch(fetchMemberPromises, () => guild.members.fetch(__zero(memberId)).catch(() => null), key);
|
|
2328
|
+
}
|
|
2329
|
+
async function fetchChannel(guild, channelId, type) {
|
|
2330
|
+
if (!channelId) return null;
|
|
2331
|
+
const key = `${guild.id}-${channelId}`;
|
|
2332
|
+
const cached = guild.channels.cache.get(__zero(channelId)) ?? null;
|
|
2333
|
+
if (cached) {
|
|
2334
|
+
if (type && cached.type !== type) return null;
|
|
2335
|
+
return cached;
|
|
2336
|
+
}
|
|
2337
|
+
const channel = await createCachedFetch(
|
|
2338
|
+
fetchChannelPromises,
|
|
2339
|
+
() => guild.channels.fetch(__zero(channelId)).catch(() => null),
|
|
2340
|
+
key
|
|
2341
|
+
);
|
|
2342
|
+
if (type && channel?.type !== type) return null;
|
|
2343
|
+
return channel;
|
|
2344
|
+
}
|
|
2345
|
+
async function fetchMessage(channel, messageId) {
|
|
2346
|
+
if (!messageId) return null;
|
|
2347
|
+
const key = `${channel.guild.id}-${messageId}`;
|
|
2348
|
+
const cached = channel.messages.cache.get(__zero(messageId));
|
|
2349
|
+
if (cached) return cached;
|
|
2350
|
+
return createCachedFetch(fetchMessagePromises, () => channel.messages.fetch(__zero(messageId)).catch(() => null), key);
|
|
2351
|
+
}
|
|
2352
|
+
async function fetchRole(guild, roleId) {
|
|
2353
|
+
if (!roleId) return null;
|
|
2354
|
+
const key = `${guild.id}-${roleId}`;
|
|
2355
|
+
const cached = guild.roles.cache.get(__zero(roleId));
|
|
2356
|
+
if (cached) return cached;
|
|
2357
|
+
return createCachedFetch(fetchRolePromises, () => guild.roles.fetch(__zero(roleId)).catch(() => null), key);
|
|
2358
|
+
}
|
|
2359
|
+
|
|
2360
|
+
// src/types/status.ts
|
|
2361
|
+
import { ActivityType } from "discord.js";
|
|
2362
|
+
import _6 from "lodash";
|
|
2363
|
+
var StatusType = /* @__PURE__ */ ((StatusType2) => {
|
|
2364
|
+
StatusType2["DND"] = "dnd";
|
|
2365
|
+
StatusType2["Idle"] = "idle";
|
|
2366
|
+
StatusType2["Online"] = "online";
|
|
2367
|
+
StatusType2["Invisible"] = "invisible";
|
|
2368
|
+
return StatusType2;
|
|
2369
|
+
})(StatusType || {});
|
|
2370
|
+
var defaultPresence = {
|
|
2371
|
+
production: {
|
|
2372
|
+
interval: 6e4,
|
|
2373
|
+
randomize: false,
|
|
2374
|
+
activity: [
|
|
2375
|
+
{ status: "online" /* Online */, type: ActivityType.Custom, name: "Need help? Use /help or !help" },
|
|
2376
|
+
{ status: "online" /* Online */, type: ActivityType.Custom, name: "Join our community!" },
|
|
2377
|
+
{ status: "online" /* Online */, type: ActivityType.Watching, name: "\u2728 $GUILD_COUNT servers" }
|
|
2378
|
+
]
|
|
2379
|
+
},
|
|
2380
|
+
development: {
|
|
2381
|
+
activity: { status: "dnd" /* DND */, type: ActivityType.Custom, name: "In development!" }
|
|
2382
|
+
}
|
|
2383
|
+
};
|
|
2384
|
+
function createVimcordStatusConfig(options = {}) {
|
|
2385
|
+
return _6.merge(defaultPresence, options);
|
|
2386
|
+
}
|
|
2387
|
+
|
|
2388
|
+
// src/modules/status.manager.ts
|
|
2389
|
+
import EventEmitter from "events";
|
|
2390
|
+
import { $ as $2 } from "qznt";
|
|
2391
|
+
var StatusManager = class {
|
|
2392
|
+
client;
|
|
2393
|
+
logger;
|
|
2394
|
+
emitter = new EventEmitter();
|
|
2395
|
+
lastActivity = null;
|
|
2396
|
+
lastActivityIndex = 0;
|
|
2397
|
+
task = null;
|
|
2398
|
+
constructor(client) {
|
|
2399
|
+
this.client = client;
|
|
2400
|
+
this.logger = new Logger({ prefixEmoji: "\u{1F4AC}", prefix: `StatusManager (i${this.client.clientId})` });
|
|
2401
|
+
this.emitter.on("changed", (activity) => {
|
|
2402
|
+
if (this.client.config.app.verbose) {
|
|
2403
|
+
this.logger.debug(`Status changed to '${activity.name}'`);
|
|
2404
|
+
}
|
|
2405
|
+
});
|
|
2406
|
+
this.emitter.on("cleared", () => {
|
|
2407
|
+
if (this.client.config.app.verbose) {
|
|
2408
|
+
this.logger.debug("Status cleared");
|
|
2409
|
+
}
|
|
2410
|
+
});
|
|
2411
|
+
}
|
|
2412
|
+
clearData() {
|
|
2413
|
+
this.task?.stop();
|
|
2414
|
+
this.task = null;
|
|
2415
|
+
this.lastActivity = null;
|
|
2416
|
+
this.lastActivityIndex = 0;
|
|
2417
|
+
return this;
|
|
2418
|
+
}
|
|
2419
|
+
async getReadyClient() {
|
|
2420
|
+
const client = await Vimcord.getReadyInstance(this.client.clientId);
|
|
2421
|
+
if (!client.user) throw new Error("Cannot manage the client's activity when its user is not hydrated");
|
|
2422
|
+
return client;
|
|
2423
|
+
}
|
|
2424
|
+
async formatActivityName(name) {
|
|
2425
|
+
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(
|
|
2426
|
+
"$INVITE",
|
|
2427
|
+
this.client.config.staff.guild.inviteUrl ? this.client.config.staff.guild.inviteUrl : "<STAFF_INVITE_URL_NOT_SET>"
|
|
2428
|
+
);
|
|
2429
|
+
if (name.includes("$STAFF_GUILD_MEMBER_COUNT")) {
|
|
2430
|
+
await fetchGuild(this.client, this.client.config.staff.guild.id).then((guild) => {
|
|
2431
|
+
if (!guild) return name = name.replace("$STAFF_GUILD_MEMBER_COUNT", "<STAFF_GUILD_NOT_FOUND>");
|
|
2432
|
+
name = name.replace("$STAFF_GUILD_MEMBER_COUNT", $2.format.number(guild.members.cache.size));
|
|
2433
|
+
}).catch((err) => this.logger.error("Failed to fetch the staff guild", err));
|
|
2434
|
+
}
|
|
2435
|
+
return name;
|
|
2436
|
+
}
|
|
2437
|
+
async setActivity(activity) {
|
|
2438
|
+
const client = await this.getReadyClient();
|
|
2439
|
+
activity.name = await this.formatActivityName(activity.name);
|
|
2440
|
+
client.user.setStatus(activity.status);
|
|
2441
|
+
client.user.setActivity({ name: activity.name, type: activity.type, url: activity.streamUrl });
|
|
2442
|
+
this.emitter.emit("changed", activity);
|
|
2243
2443
|
}
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
this.
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2444
|
+
async statusRotationTask(clientStatus) {
|
|
2445
|
+
let activity;
|
|
2446
|
+
if (clientStatus.randomize && Array.isArray(clientStatus.activity)) {
|
|
2447
|
+
activity = $2.rnd.choice(clientStatus.activity, { not: this.lastActivity });
|
|
2448
|
+
this.lastActivity = activity;
|
|
2449
|
+
} else {
|
|
2450
|
+
const activityIndex = (this.lastActivityIndex + 1) % clientStatus.activity.length;
|
|
2451
|
+
this.lastActivityIndex = activityIndex;
|
|
2452
|
+
activity = clientStatus.activity[activityIndex];
|
|
2252
2453
|
}
|
|
2454
|
+
await this.setActivity(activity);
|
|
2455
|
+
this.emitter.emit("rotation", activity);
|
|
2253
2456
|
}
|
|
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));
|
|
2457
|
+
async scheduleStatusRotation(clientStatus) {
|
|
2458
|
+
if (!clientStatus.interval) throw new Error("Cannot create client activity interval without interval time");
|
|
2459
|
+
this.task?.stop();
|
|
2460
|
+
this.task = null;
|
|
2461
|
+
this.task = new $2.Loop(() => this.statusRotationTask(clientStatus), $2.math.ms(clientStatus.interval), true);
|
|
2462
|
+
this.start();
|
|
2263
2463
|
}
|
|
2264
|
-
|
|
2265
|
-
|
|
2464
|
+
start() {
|
|
2465
|
+
if (this.task) {
|
|
2466
|
+
this.task.start();
|
|
2467
|
+
this.emitter.emit("started", this.task);
|
|
2468
|
+
}
|
|
2469
|
+
return this;
|
|
2266
2470
|
}
|
|
2267
|
-
|
|
2268
|
-
|
|
2471
|
+
pause() {
|
|
2472
|
+
if (this.task) {
|
|
2473
|
+
this.task.stop();
|
|
2474
|
+
this.emitter.emit("paused", this.task);
|
|
2475
|
+
}
|
|
2476
|
+
return this;
|
|
2269
2477
|
}
|
|
2270
|
-
async
|
|
2271
|
-
const
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
})
|
|
2285
|
-
);
|
|
2478
|
+
async set(status) {
|
|
2479
|
+
const statusConfig = createVimcordStatusConfig(status);
|
|
2480
|
+
let clientStatus;
|
|
2481
|
+
if (this.client.config.app.devMode) {
|
|
2482
|
+
clientStatus = statusConfig.development;
|
|
2483
|
+
} else {
|
|
2484
|
+
clientStatus = statusConfig.production;
|
|
2485
|
+
}
|
|
2486
|
+
if (!clientStatus.interval) {
|
|
2487
|
+
await this.setActivity(Array.isArray(clientStatus.activity) ? clientStatus.activity[0] : clientStatus.activity);
|
|
2488
|
+
} else {
|
|
2489
|
+
await this.scheduleStatusRotation(clientStatus);
|
|
2490
|
+
}
|
|
2491
|
+
return this;
|
|
2286
2492
|
}
|
|
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);
|
|
2493
|
+
async destroy() {
|
|
2494
|
+
if (this.task) {
|
|
2495
|
+
this.task.stop();
|
|
2496
|
+
this.task = null;
|
|
2497
|
+
this.emitter.emit("destroyed");
|
|
2498
|
+
await this.clear();
|
|
2305
2499
|
}
|
|
2306
|
-
this
|
|
2307
|
-
|
|
2500
|
+
return this;
|
|
2501
|
+
}
|
|
2502
|
+
async clear() {
|
|
2503
|
+
const client = await this.getReadyClient();
|
|
2504
|
+
this.clearData();
|
|
2505
|
+
client.user.setActivity({ name: "" });
|
|
2506
|
+
this.emitter.emit("cleared");
|
|
2507
|
+
return this;
|
|
2308
2508
|
}
|
|
2309
2509
|
};
|
|
2310
2510
|
|
|
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
|
|
2511
|
+
// src/utils/vimcord.cli.ts
|
|
2319
2512
|
import { createInterface } from "readline";
|
|
2320
2513
|
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 {
|
|
2514
|
+
var VimcordCLI = class _VimcordCLI {
|
|
2515
|
+
static mode = "off";
|
|
2516
|
+
static setMode(mode) {
|
|
2517
|
+
if (_VimcordCLI.mode === mode) return;
|
|
2518
|
+
_VimcordCLI.mode = mode;
|
|
2519
|
+
if (mode === "on") {
|
|
2520
|
+
CLI.logger.log(`~ Type ${CLI.options.prefix}help to view available commands`);
|
|
2521
|
+
} else {
|
|
2522
|
+
CLI.logger.log(`~ [MODE] Now set to "${mode}"`);
|
|
2523
|
+
}
|
|
2524
|
+
}
|
|
2335
2525
|
rl;
|
|
2336
2526
|
options;
|
|
2337
2527
|
commands = /* @__PURE__ */ new Map();
|
|
@@ -2344,6 +2534,7 @@ var VimcordCLI = class {
|
|
|
2344
2534
|
terminal: false
|
|
2345
2535
|
});
|
|
2346
2536
|
this.rl.on("line", (line) => {
|
|
2537
|
+
if (_VimcordCLI.mode !== "on") return;
|
|
2347
2538
|
const { isCommand, commandName, content, args } = this.parseLine(line);
|
|
2348
2539
|
if (!isCommand) return;
|
|
2349
2540
|
const command = this.commands.get(commandName);
|
|
@@ -2400,7 +2591,6 @@ var VimcordCLI = class {
|
|
|
2400
2591
|
return true;
|
|
2401
2592
|
}
|
|
2402
2593
|
};
|
|
2403
|
-
var initCalled = false;
|
|
2404
2594
|
var CLI = new VimcordCLI({ prefix: "/" });
|
|
2405
2595
|
CLI.addCommand("help", "View information about a command, or the available CLI options", (args) => {
|
|
2406
2596
|
const prefix = CLI.options.prefix;
|
|
@@ -2507,16 +2697,81 @@ CLI.addCommand("cmds", "List the loaded commands", async (args, content) => {
|
|
|
2507
2697
|
return CLI.logger.error(`'${mode}' is not a valid option. Valid options: [slash|prefix|ctx]`);
|
|
2508
2698
|
}
|
|
2509
2699
|
});
|
|
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
2700
|
|
|
2516
|
-
// src/client.ts
|
|
2517
|
-
import
|
|
2701
|
+
// src/client/Vimcord.ts
|
|
2702
|
+
import { Client as Client2 } from "discord.js";
|
|
2703
|
+
import { configDotenv } from "dotenv";
|
|
2704
|
+
import { randomUUID as randomUUID3 } from "crypto";
|
|
2705
|
+
import EventEmitter2 from "events";
|
|
2706
|
+
import { $ as $4 } from "qznt";
|
|
2518
2707
|
var Vimcord = class _Vimcord extends Client2 {
|
|
2519
2708
|
static instances = /* @__PURE__ */ new Map();
|
|
2709
|
+
static emitter = new EventEmitter2();
|
|
2710
|
+
clientStartingPromise = null;
|
|
2711
|
+
static create(optionsOrConfig, features, config) {
|
|
2712
|
+
if ("options" in optionsOrConfig) {
|
|
2713
|
+
const { options, features: features2, config: config2 } = optionsOrConfig;
|
|
2714
|
+
return new _Vimcord(options, features2, config2);
|
|
2715
|
+
} else {
|
|
2716
|
+
return new _Vimcord(optionsOrConfig, features, config);
|
|
2717
|
+
}
|
|
2718
|
+
}
|
|
2719
|
+
/**
|
|
2720
|
+
* Returns an instance of Vimcord.
|
|
2721
|
+
* @param clientId [default: 0]
|
|
2722
|
+
*/
|
|
2723
|
+
static getInstance(clientId) {
|
|
2724
|
+
if (clientId === void 0) {
|
|
2725
|
+
return _Vimcord.instances.values().next().value;
|
|
2726
|
+
}
|
|
2727
|
+
return _Vimcord.instances.get(clientId);
|
|
2728
|
+
}
|
|
2729
|
+
/**
|
|
2730
|
+
* Waits for a Vimcord instance to be ready.
|
|
2731
|
+
* @param clientId [default: 0]
|
|
2732
|
+
* @param timeoutMs [default: 60000]
|
|
2733
|
+
*/
|
|
2734
|
+
static async getReadyInstance(clientId, timeoutMs = 6e4) {
|
|
2735
|
+
const client = _Vimcord.getInstance(clientId);
|
|
2736
|
+
if (client?.isReady()) {
|
|
2737
|
+
_Vimcord.emitter.emit("ready", client);
|
|
2738
|
+
return client;
|
|
2739
|
+
}
|
|
2740
|
+
if (client) {
|
|
2741
|
+
return new Promise((resolve, reject) => {
|
|
2742
|
+
const timeout = setTimeout(() => {
|
|
2743
|
+
_Vimcord.emitter.off("ready", listener);
|
|
2744
|
+
reject(new Error(`Client (i${clientId ?? 0}) timed out waiting for ready`));
|
|
2745
|
+
}, timeoutMs);
|
|
2746
|
+
const listener = (c) => {
|
|
2747
|
+
if (c.clientId === (clientId ?? 0)) {
|
|
2748
|
+
clearTimeout(timeout);
|
|
2749
|
+
_Vimcord.emitter.off("ready", listener);
|
|
2750
|
+
resolve(c);
|
|
2751
|
+
}
|
|
2752
|
+
};
|
|
2753
|
+
client.once("clientReady", () => {
|
|
2754
|
+
clearTimeout(timeout);
|
|
2755
|
+
_Vimcord.emitter.emit("ready", client);
|
|
2756
|
+
resolve(client);
|
|
2757
|
+
});
|
|
2758
|
+
});
|
|
2759
|
+
}
|
|
2760
|
+
return new Promise((resolve, reject) => {
|
|
2761
|
+
const timeout = setTimeout(() => {
|
|
2762
|
+
_Vimcord.emitter.off("ready", listener);
|
|
2763
|
+
reject(new Error(`Vimcord instance (i${clientId ?? 0}) failed to initialize within ${timeoutMs / 1e3}s.`));
|
|
2764
|
+
}, timeoutMs);
|
|
2765
|
+
const listener = (c) => {
|
|
2766
|
+
if (c.clientId === (clientId ?? 0)) {
|
|
2767
|
+
clearTimeout(timeout);
|
|
2768
|
+
_Vimcord.emitter.off("ready", listener);
|
|
2769
|
+
resolve(c);
|
|
2770
|
+
}
|
|
2771
|
+
};
|
|
2772
|
+
_Vimcord.emitter.on("ready", listener);
|
|
2773
|
+
});
|
|
2774
|
+
}
|
|
2520
2775
|
uuid = randomUUID3();
|
|
2521
2776
|
clientId = _Vimcord.instances.size;
|
|
2522
2777
|
clientOptions;
|
|
@@ -2526,229 +2781,181 @@ var Vimcord = class _Vimcord extends Client2 {
|
|
|
2526
2781
|
events;
|
|
2527
2782
|
commands;
|
|
2528
2783
|
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;
|
|
2784
|
+
logger = clientLoggerFactory(this);
|
|
2785
|
+
error;
|
|
2596
2786
|
constructor(options, features = {}, config = {}) {
|
|
2597
2787
|
super(options);
|
|
2598
2788
|
this.clientOptions = options;
|
|
2599
2789
|
this.features = features;
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
dotEnv.config({ quiet: true, ...this.features.useEnv });
|
|
2603
|
-
} else {
|
|
2604
|
-
dotEnv.config({ quiet: true });
|
|
2605
|
-
}
|
|
2606
|
-
}
|
|
2790
|
+
this.config = defineVimcordConfig(config);
|
|
2791
|
+
this.error = new ErrorHandler(this);
|
|
2607
2792
|
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
|
-
};
|
|
2793
|
+
this.error.setupGlobalHandlers();
|
|
2794
|
+
}
|
|
2621
2795
|
this.status = new StatusManager(this);
|
|
2622
2796
|
this.events = new EventManager(this);
|
|
2623
2797
|
this.commands = new CommandManager(this);
|
|
2624
2798
|
this.logger.clientBanner(this);
|
|
2625
|
-
this.once("clientReady", (client) =>
|
|
2626
|
-
this.logger.clientReady(client.user.tag, client.guilds.cache.size);
|
|
2627
|
-
});
|
|
2799
|
+
this.once("clientReady", (client) => this.logger.clientReady(client.user.tag, client.guilds.cache.size));
|
|
2628
2800
|
_Vimcord.instances.set(this.clientId, this);
|
|
2629
|
-
|
|
2801
|
+
if (this.config.app.enableCLI) {
|
|
2802
|
+
VimcordCLI.setMode("on");
|
|
2803
|
+
}
|
|
2630
2804
|
}
|
|
2631
|
-
/**
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
features: this.features,
|
|
2636
|
-
config: this.config
|
|
2637
|
-
};
|
|
2805
|
+
/** Current app name */
|
|
2806
|
+
// prettier-ignore
|
|
2807
|
+
get $name() {
|
|
2808
|
+
return this.config.app.name;
|
|
2638
2809
|
}
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
return new _Vimcord(options, features, config);
|
|
2810
|
+
// prettier-ignore
|
|
2811
|
+
set $name(name) {
|
|
2812
|
+
this.config.app.name = name;
|
|
2643
2813
|
}
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
}
|
|
2649
|
-
return this;
|
|
2814
|
+
/** Current app version */
|
|
2815
|
+
// prettier-ignore
|
|
2816
|
+
get $version() {
|
|
2817
|
+
return this.config.app.version;
|
|
2650
2818
|
}
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2819
|
+
// prettier-ignore
|
|
2820
|
+
set $version(version2) {
|
|
2821
|
+
this.config.app.version = version2;
|
|
2654
2822
|
}
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2823
|
+
/** Current dev mode state */
|
|
2824
|
+
// prettier-ignore
|
|
2825
|
+
get $devMode() {
|
|
2826
|
+
return this.config.app.devMode;
|
|
2658
2827
|
}
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
2828
|
+
// prettier-ignore
|
|
2829
|
+
set $devMode(mode) {
|
|
2830
|
+
this.config.app.devMode = mode;
|
|
2662
2831
|
}
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2832
|
+
/** Current verbose mode state */
|
|
2833
|
+
// prettier-ignore
|
|
2834
|
+
get $verboseMode() {
|
|
2835
|
+
return this.config.app.verbose;
|
|
2666
2836
|
}
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2837
|
+
// prettier-ignore
|
|
2838
|
+
set $verboseMode(mode) {
|
|
2839
|
+
this.config.app.verbose = mode;
|
|
2670
2840
|
}
|
|
2671
|
-
|
|
2672
|
-
|
|
2673
|
-
return this;
|
|
2841
|
+
/** Returns the options, features, and config of this client. */
|
|
2842
|
+
toJSON() {
|
|
2843
|
+
return { options: this.clientOptions, features: this.features, config: this.config };
|
|
2674
2844
|
}
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2845
|
+
/** Makes a clone of this client. */
|
|
2846
|
+
clone() {
|
|
2847
|
+
const { options, features, config } = this.toJSON();
|
|
2848
|
+
return new _Vimcord(options, features, config);
|
|
2678
2849
|
}
|
|
2679
|
-
|
|
2680
|
-
|
|
2850
|
+
/**
|
|
2851
|
+
* Modifies a client config.
|
|
2852
|
+
* @param type The type of config to modify.
|
|
2853
|
+
* @param options The options to set for the config.
|
|
2854
|
+
*/
|
|
2855
|
+
configure(type, options = {}) {
|
|
2856
|
+
this.config[type] = configSetters[type](options, this.config[type]);
|
|
2681
2857
|
return this;
|
|
2682
2858
|
}
|
|
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
|
-
}
|
|
2859
|
+
/** Builds the client by importing modules and registering builtin handlers. */
|
|
2701
2860
|
async build() {
|
|
2702
|
-
this.
|
|
2703
|
-
this.
|
|
2704
|
-
this.
|
|
2705
|
-
this.
|
|
2706
|
-
this.
|
|
2861
|
+
this.configure("app", this.config.app);
|
|
2862
|
+
this.configure("staff", this.config.staff);
|
|
2863
|
+
this.configure("slashCommands", this.config.slashCommands);
|
|
2864
|
+
this.configure("prefixCommands", this.config.prefixCommands);
|
|
2865
|
+
this.configure("contextCommands", this.config.contextCommands);
|
|
2707
2866
|
if (this.features.importModules) {
|
|
2708
2867
|
const importModules = this.features.importModules;
|
|
2709
2868
|
await Promise.all([
|
|
2710
|
-
importModules.events && this.
|
|
2711
|
-
importModules.slashCommands && this.
|
|
2712
|
-
importModules.prefixCommands && this.
|
|
2713
|
-
importModules.contextCommands && this.
|
|
2869
|
+
importModules.events && this.importModules("events", importModules.events),
|
|
2870
|
+
importModules.slashCommands && this.importModules("slashCommands", importModules.slashCommands),
|
|
2871
|
+
importModules.prefixCommands && this.importModules("prefixCommands", importModules.prefixCommands),
|
|
2872
|
+
importModules.contextCommands && this.importModules("contextCommands", importModules.contextCommands)
|
|
2714
2873
|
]);
|
|
2715
2874
|
}
|
|
2716
2875
|
if (this.features.useDefaultSlashCommandHandler) {
|
|
2717
|
-
this.events.register(
|
|
2876
|
+
this.events.register(slashCommandHandler);
|
|
2718
2877
|
}
|
|
2719
2878
|
if (this.features.useDefaultContextCommandHandler) {
|
|
2720
|
-
this.events.register(
|
|
2879
|
+
this.events.register(contextCommandHandler);
|
|
2721
2880
|
}
|
|
2722
2881
|
if (this.features.useDefaultPrefixCommandHandler) {
|
|
2723
|
-
this.events.register(
|
|
2882
|
+
this.events.register(prefixCommandHandler);
|
|
2724
2883
|
}
|
|
2725
2884
|
return this;
|
|
2726
2885
|
}
|
|
2727
|
-
|
|
2886
|
+
/**
|
|
2887
|
+
* Imports modules into the client.
|
|
2888
|
+
* @param type The type of modules to import.
|
|
2889
|
+
* @param options The options to import the module with.
|
|
2890
|
+
* @param set Replaces already imported modules with the ones found.
|
|
2891
|
+
*/
|
|
2892
|
+
async importModules(type, options, set) {
|
|
2893
|
+
await moduleImporters[type](this, options, set);
|
|
2894
|
+
return this;
|
|
2895
|
+
}
|
|
2896
|
+
/**
|
|
2897
|
+
* Allows Vimcord to handle environment variables using [dotenv](https://www.npmjs.com/package/dotenv).
|
|
2898
|
+
* @param options Options for dotenv
|
|
2899
|
+
* @see https://www.npmjs.com/package/dotenv
|
|
2900
|
+
*/
|
|
2901
|
+
useEnv(options) {
|
|
2902
|
+
this.logger.database("Using", "dotenv");
|
|
2903
|
+
configDotenv({ quiet: true, ...options });
|
|
2904
|
+
return this;
|
|
2905
|
+
}
|
|
2906
|
+
/**
|
|
2907
|
+
* Connects to a database.
|
|
2908
|
+
* @param db The database manager to use.
|
|
2909
|
+
*/
|
|
2910
|
+
async useDatabase(db) {
|
|
2911
|
+
this.db = db;
|
|
2912
|
+
this.logger.database("Using", db.moduleName);
|
|
2913
|
+
return this.db.connect();
|
|
2914
|
+
}
|
|
2915
|
+
/**
|
|
2916
|
+
* Fetches a user from the client, checking the cache first.
|
|
2917
|
+
* @param userId The ID of the user to fetch.
|
|
2918
|
+
*/
|
|
2919
|
+
async fetchUser(userId) {
|
|
2920
|
+
const client = await _Vimcord.getReadyInstance(this.clientId);
|
|
2921
|
+
return fetchUser(client, userId);
|
|
2922
|
+
}
|
|
2923
|
+
/**
|
|
2924
|
+
* Fetches a guild from the client, checking the cache first.
|
|
2925
|
+
* @param guildId The ID of the guild to fetch.
|
|
2926
|
+
*/
|
|
2927
|
+
async fetchGuild(guildId) {
|
|
2928
|
+
const client = await _Vimcord.getReadyInstance(this.clientId);
|
|
2929
|
+
return fetchGuild(client, guildId);
|
|
2930
|
+
}
|
|
2931
|
+
async start(tokenOrPreHook, callback) {
|
|
2728
2932
|
if (this.clientStartingPromise) return this.clientStartingPromise;
|
|
2729
|
-
const
|
|
2933
|
+
const execute = async () => {
|
|
2730
2934
|
let token = typeof tokenOrPreHook === "string" ? tokenOrPreHook : void 0;
|
|
2731
|
-
token ??= this
|
|
2935
|
+
token ??= this.$devMode ? process.env.TOKEN_DEV : process.env.TOKEN;
|
|
2732
2936
|
if (!token) {
|
|
2733
2937
|
throw new Error(
|
|
2734
|
-
`TOKEN Missing: ${this
|
|
2938
|
+
`TOKEN Missing: ${this.$devMode ? "devMode is enabled, but TOKEN_DEV is not set" : "TOKEN not set"}`
|
|
2735
2939
|
);
|
|
2736
2940
|
}
|
|
2737
2941
|
await this.build();
|
|
2738
2942
|
try {
|
|
2943
|
+
const stopLoader = this.logger.loader("Connecting to Discord...");
|
|
2944
|
+
const loginResult = await $4.async.retry(() => super.login(token), {
|
|
2945
|
+
retries: this.features.maxLoginAttempts ?? 3,
|
|
2946
|
+
delay: 1e3
|
|
2947
|
+
});
|
|
2948
|
+
stopLoader("Connected to Discord ");
|
|
2949
|
+
this.$verboseMode && this.logger.debug("Waiting for ready...");
|
|
2739
2950
|
if (typeof tokenOrPreHook === "function") {
|
|
2740
2951
|
await tokenOrPreHook(this);
|
|
2741
2952
|
} else {
|
|
2742
|
-
await
|
|
2953
|
+
await callback?.(this);
|
|
2743
2954
|
}
|
|
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
2955
|
return loginResult;
|
|
2749
2956
|
} catch (err) {
|
|
2750
2957
|
this.logger.error(
|
|
2751
|
-
`Failed to log into Discord after ${this.features.
|
|
2958
|
+
`Failed to log into Discord after ${this.features.maxLoginAttempts} attempt(s)`,
|
|
2752
2959
|
err
|
|
2753
2960
|
);
|
|
2754
2961
|
return null;
|
|
@@ -2756,29 +2963,27 @@ var Vimcord = class _Vimcord extends Client2 {
|
|
|
2756
2963
|
this.clientStartingPromise = null;
|
|
2757
2964
|
}
|
|
2758
2965
|
};
|
|
2759
|
-
this.clientStartingPromise =
|
|
2966
|
+
this.clientStartingPromise = execute();
|
|
2760
2967
|
return this.clientStartingPromise;
|
|
2761
2968
|
}
|
|
2969
|
+
/** Destroys the client and disconnects from Discord. */
|
|
2762
2970
|
async kill() {
|
|
2763
2971
|
await super.destroy();
|
|
2764
2972
|
_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);
|
|
2973
|
+
this.logger.debug("Logged out of Discord");
|
|
2776
2974
|
}
|
|
2777
2975
|
};
|
|
2778
2976
|
|
|
2779
|
-
// src/
|
|
2977
|
+
// src/db/mongo/mongo-schema.builder.ts
|
|
2978
|
+
import {
|
|
2979
|
+
Schema
|
|
2980
|
+
} from "mongoose";
|
|
2981
|
+
import { randomBytes } from "crypto";
|
|
2982
|
+
import { $ as $6 } from "qznt";
|
|
2983
|
+
|
|
2984
|
+
// src/db/mongo/mongo.database.ts
|
|
2780
2985
|
import mongoose, { ConnectionStates } from "mongoose";
|
|
2781
|
-
import
|
|
2986
|
+
import EventEmitter3 from "events";
|
|
2782
2987
|
import { $ as $5 } from "qznt";
|
|
2783
2988
|
try {
|
|
2784
2989
|
import("mongoose");
|
|
@@ -2787,7 +2992,7 @@ try {
|
|
|
2787
2992
|
}
|
|
2788
2993
|
var MongoDatabase = class _MongoDatabase {
|
|
2789
2994
|
static instances = /* @__PURE__ */ new Map();
|
|
2790
|
-
static emitter = new
|
|
2995
|
+
static emitter = new EventEmitter3();
|
|
2791
2996
|
moduleName = "MongoDatabase";
|
|
2792
2997
|
clientId;
|
|
2793
2998
|
client;
|
|
@@ -2872,10 +3077,9 @@ var MongoDatabase = class _MongoDatabase {
|
|
|
2872
3077
|
this.isConnecting = true;
|
|
2873
3078
|
try {
|
|
2874
3079
|
const stopLoader = this.client.logger.loader("Connecting to MongoDB...");
|
|
2875
|
-
await $5.async.retry(
|
|
2876
|
-
|
|
2877
|
-
|
|
2878
|
-
);
|
|
3080
|
+
await $5.async.retry(() => this.mongoose.connect(connectionUri, { autoIndex: true, ...connectionOptions }), {
|
|
3081
|
+
retries: maxRetries
|
|
3082
|
+
});
|
|
2879
3083
|
_MongoDatabase.emitter.emit("ready", this);
|
|
2880
3084
|
stopLoader("Connected to MongoDB ");
|
|
2881
3085
|
} catch (err) {
|
|
@@ -2906,12 +3110,7 @@ var MongoDatabase = class _MongoDatabase {
|
|
|
2906
3110
|
}
|
|
2907
3111
|
};
|
|
2908
3112
|
|
|
2909
|
-
// src/
|
|
2910
|
-
import {
|
|
2911
|
-
Schema
|
|
2912
|
-
} from "mongoose";
|
|
2913
|
-
import { randomBytes } from "crypto";
|
|
2914
|
-
import { $ as $6 } from "qznt";
|
|
3113
|
+
// src/db/mongo/mongo-schema.builder.ts
|
|
2915
3114
|
try {
|
|
2916
3115
|
import("mongoose");
|
|
2917
3116
|
} catch {
|
|
@@ -2997,10 +3196,13 @@ var MongoSchemaBuilder = class _MongoSchemaBuilder {
|
|
|
2997
3196
|
* @param maxRetries [default: 3]
|
|
2998
3197
|
*/
|
|
2999
3198
|
async execute(fn, maxRetries = 3) {
|
|
3000
|
-
return await $6.async.retry(
|
|
3001
|
-
|
|
3002
|
-
|
|
3003
|
-
|
|
3199
|
+
return await $6.async.retry(
|
|
3200
|
+
async () => {
|
|
3201
|
+
const model = await this.getModel();
|
|
3202
|
+
return await fn(model);
|
|
3203
|
+
},
|
|
3204
|
+
{ retries: maxRetries }
|
|
3205
|
+
);
|
|
3004
3206
|
}
|
|
3005
3207
|
async startSession(options) {
|
|
3006
3208
|
return await this.execute(async () => {
|
|
@@ -3630,7 +3832,7 @@ import {
|
|
|
3630
3832
|
EmbedBuilder as EmbedBuilder2,
|
|
3631
3833
|
StringSelectMenuBuilder as StringSelectMenuBuilder2
|
|
3632
3834
|
} from "discord.js";
|
|
3633
|
-
import
|
|
3835
|
+
import EventEmitter4 from "events";
|
|
3634
3836
|
var PaginationType = /* @__PURE__ */ ((PaginationType2) => {
|
|
3635
3837
|
PaginationType2[PaginationType2["Short"] = 0] = "Short";
|
|
3636
3838
|
PaginationType2[PaginationType2["ShortJump"] = 1] = "ShortJump";
|
|
@@ -3675,7 +3877,7 @@ var Paginator = class {
|
|
|
3675
3877
|
config;
|
|
3676
3878
|
data;
|
|
3677
3879
|
events;
|
|
3678
|
-
eventEmitter = new
|
|
3880
|
+
eventEmitter = new EventEmitter4();
|
|
3679
3881
|
constructor(options = {}) {
|
|
3680
3882
|
this.config = options.config ? createToolsConfig(options.config) : globalToolsConfig;
|
|
3681
3883
|
this.options = {
|
|
@@ -4291,9 +4493,6 @@ async function prompt(handler, options, sendOptions) {
|
|
|
4291
4493
|
return await p.awaitResponse();
|
|
4292
4494
|
}
|
|
4293
4495
|
export {
|
|
4294
|
-
BUILTIN_ContextCommandHandler,
|
|
4295
|
-
BUILTIN_PrefixCommandHandler,
|
|
4296
|
-
BUILTIN_SlashCommandHandler,
|
|
4297
4496
|
BaseCommandBuilder,
|
|
4298
4497
|
BaseCommandManager,
|
|
4299
4498
|
BetterCollector,
|
|
@@ -4306,13 +4505,16 @@ export {
|
|
|
4306
4505
|
CommandType,
|
|
4307
4506
|
ContextCommandBuilder,
|
|
4308
4507
|
ContextCommandManager,
|
|
4508
|
+
DEFAULT_MODULE_SUFFIXES,
|
|
4309
4509
|
DynaSend,
|
|
4510
|
+
ErrorHandler,
|
|
4310
4511
|
EventBuilder,
|
|
4311
4512
|
EventManager,
|
|
4312
4513
|
LOGGER_COLORS,
|
|
4313
4514
|
LogLevel,
|
|
4314
4515
|
Logger,
|
|
4315
4516
|
MissingPermissionReason,
|
|
4517
|
+
ModuleImporter,
|
|
4316
4518
|
MongoDatabase,
|
|
4317
4519
|
MongoSchemaBuilder,
|
|
4318
4520
|
PaginationTimeoutType,
|
|
@@ -4332,8 +4534,12 @@ export {
|
|
|
4332
4534
|
VimcordCLI,
|
|
4333
4535
|
__zero,
|
|
4334
4536
|
cleanMention,
|
|
4537
|
+
clientLoggerFactory,
|
|
4538
|
+
configSetters,
|
|
4539
|
+
contextCommandHandler,
|
|
4335
4540
|
createAppConfig,
|
|
4336
4541
|
createClient,
|
|
4542
|
+
createConfigFactory,
|
|
4337
4543
|
createContextCommandConfig,
|
|
4338
4544
|
createMongoPlugin,
|
|
4339
4545
|
createMongoSchema,
|
|
@@ -4342,7 +4548,10 @@ export {
|
|
|
4342
4548
|
createStaffConfig,
|
|
4343
4549
|
createToolsConfig,
|
|
4344
4550
|
createVimcordStatusConfig,
|
|
4551
|
+
defineClientOptions,
|
|
4345
4552
|
defineGlobalToolsConfig,
|
|
4553
|
+
defineVimcordConfig,
|
|
4554
|
+
defineVimcordFeatures,
|
|
4346
4555
|
dynaSend,
|
|
4347
4556
|
fetchChannel,
|
|
4348
4557
|
fetchGuild,
|
|
@@ -4350,17 +4559,20 @@ export {
|
|
|
4350
4559
|
fetchMessage,
|
|
4351
4560
|
fetchRole,
|
|
4352
4561
|
fetchUser,
|
|
4353
|
-
|
|
4562
|
+
getDevMode,
|
|
4354
4563
|
getFirstMentionId,
|
|
4355
4564
|
getMessageMention,
|
|
4565
|
+
getPackageJson,
|
|
4356
4566
|
getProcessDir,
|
|
4357
4567
|
globalToolsConfig,
|
|
4358
4568
|
importModulesFromDir,
|
|
4359
|
-
initCLI,
|
|
4360
4569
|
isMentionOrSnowflake,
|
|
4361
4570
|
logger,
|
|
4571
|
+
moduleImporters,
|
|
4572
|
+
prefixCommandHandler,
|
|
4362
4573
|
prompt,
|
|
4363
4574
|
sendCommandErrorEmbed,
|
|
4575
|
+
slashCommandHandler,
|
|
4364
4576
|
useClient,
|
|
4365
4577
|
useReadyClient,
|
|
4366
4578
|
validateCommandPermissions
|