vimcord 1.0.35 → 1.0.37
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +395 -47
- package/dist/index.cjs +1286 -1039
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +793 -452
- package/dist/index.d.ts +793 -452
- package/dist/index.js +1249 -1012
- 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.cjs
CHANGED
|
@@ -30,9 +30,6 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/index.ts
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
|
-
BUILTIN_ContextCommandHandler: () => BUILTIN_ContextCommandHandler,
|
|
34
|
-
BUILTIN_PrefixCommandHandler: () => BUILTIN_PrefixCommandHandler,
|
|
35
|
-
BUILTIN_SlashCommandHandler: () => BUILTIN_SlashCommandHandler,
|
|
36
33
|
BaseCommandBuilder: () => BaseCommandBuilder,
|
|
37
34
|
BaseCommandManager: () => BaseCommandManager,
|
|
38
35
|
BetterCollector: () => BetterCollector,
|
|
@@ -45,13 +42,16 @@ __export(index_exports, {
|
|
|
45
42
|
CommandType: () => CommandType,
|
|
46
43
|
ContextCommandBuilder: () => ContextCommandBuilder,
|
|
47
44
|
ContextCommandManager: () => ContextCommandManager,
|
|
45
|
+
DEFAULT_MODULE_SUFFIXES: () => DEFAULT_MODULE_SUFFIXES,
|
|
48
46
|
DynaSend: () => DynaSend,
|
|
47
|
+
ErrorHandler: () => ErrorHandler,
|
|
49
48
|
EventBuilder: () => EventBuilder,
|
|
50
49
|
EventManager: () => EventManager,
|
|
51
50
|
LOGGER_COLORS: () => LOGGER_COLORS,
|
|
52
51
|
LogLevel: () => LogLevel,
|
|
53
52
|
Logger: () => Logger,
|
|
54
53
|
MissingPermissionReason: () => MissingPermissionReason,
|
|
54
|
+
ModuleImporter: () => ModuleImporter,
|
|
55
55
|
MongoDatabase: () => MongoDatabase,
|
|
56
56
|
MongoSchemaBuilder: () => MongoSchemaBuilder,
|
|
57
57
|
PaginationTimeoutType: () => PaginationTimeoutType,
|
|
@@ -71,17 +71,24 @@ __export(index_exports, {
|
|
|
71
71
|
VimcordCLI: () => VimcordCLI,
|
|
72
72
|
__zero: () => __zero,
|
|
73
73
|
cleanMention: () => cleanMention,
|
|
74
|
+
clientLoggerFactory: () => clientLoggerFactory,
|
|
75
|
+
configSetters: () => configSetters,
|
|
76
|
+
contextCommandHandler: () => contextCommandHandler,
|
|
77
|
+
createAppConfig: () => createAppConfig,
|
|
74
78
|
createClient: () => createClient,
|
|
79
|
+
createConfigFactory: () => createConfigFactory,
|
|
80
|
+
createContextCommandConfig: () => createContextCommandConfig,
|
|
75
81
|
createMongoPlugin: () => createMongoPlugin,
|
|
76
82
|
createMongoSchema: () => createMongoSchema,
|
|
83
|
+
createPrefixCommandConfig: () => createPrefixCommandConfig,
|
|
84
|
+
createSlashCommandConfig: () => createSlashCommandConfig,
|
|
85
|
+
createStaffConfig: () => createStaffConfig,
|
|
77
86
|
createToolsConfig: () => createToolsConfig,
|
|
78
|
-
createVimcordAppConfig: () => createVimcordAppConfig,
|
|
79
|
-
createVimcordContextCommandConfig: () => createVimcordContextCommandConfig,
|
|
80
|
-
createVimcordPrefixCommandConfig: () => createVimcordPrefixCommandConfig,
|
|
81
|
-
createVimcordSlashCommandConfig: () => createVimcordSlashCommandConfig,
|
|
82
|
-
createVimcordStaffConfig: () => createVimcordStaffConfig,
|
|
83
87
|
createVimcordStatusConfig: () => createVimcordStatusConfig,
|
|
88
|
+
defineClientOptions: () => defineClientOptions,
|
|
84
89
|
defineGlobalToolsConfig: () => defineGlobalToolsConfig,
|
|
90
|
+
defineVimcordConfig: () => defineVimcordConfig,
|
|
91
|
+
defineVimcordFeatures: () => defineVimcordFeatures,
|
|
85
92
|
dynaSend: () => dynaSend,
|
|
86
93
|
fetchChannel: () => fetchChannel,
|
|
87
94
|
fetchGuild: () => fetchGuild,
|
|
@@ -89,23 +96,29 @@ __export(index_exports, {
|
|
|
89
96
|
fetchMessage: () => fetchMessage,
|
|
90
97
|
fetchRole: () => fetchRole,
|
|
91
98
|
fetchUser: () => fetchUser,
|
|
92
|
-
|
|
99
|
+
getDevMode: () => getDevMode,
|
|
93
100
|
getFirstMentionId: () => getFirstMentionId,
|
|
94
101
|
getMessageMention: () => getMessageMention,
|
|
102
|
+
getPackageJson: () => getPackageJson,
|
|
95
103
|
getProcessDir: () => getProcessDir,
|
|
96
|
-
|
|
104
|
+
globalToolsConfig: () => globalToolsConfig,
|
|
97
105
|
importModulesFromDir: () => importModulesFromDir,
|
|
98
|
-
initCLI: () => initCLI,
|
|
99
106
|
isMentionOrSnowflake: () => isMentionOrSnowflake,
|
|
100
107
|
logger: () => logger,
|
|
108
|
+
moduleImporters: () => moduleImporters,
|
|
109
|
+
prefixCommandHandler: () => prefixCommandHandler,
|
|
101
110
|
prompt: () => prompt,
|
|
102
111
|
sendCommandErrorEmbed: () => sendCommandErrorEmbed,
|
|
112
|
+
slashCommandHandler: () => slashCommandHandler,
|
|
103
113
|
useClient: () => useClient,
|
|
104
114
|
useReadyClient: () => useReadyClient,
|
|
105
115
|
validateCommandPermissions: () => validateCommandPermissions
|
|
106
116
|
});
|
|
107
117
|
module.exports = __toCommonJS(index_exports);
|
|
108
118
|
|
|
119
|
+
// src/modules/validators/permissions.validator.ts
|
|
120
|
+
var import_discord = require("discord.js");
|
|
121
|
+
|
|
109
122
|
// src/types/command.base.ts
|
|
110
123
|
var CommandType = /* @__PURE__ */ ((CommandType2) => {
|
|
111
124
|
CommandType2[CommandType2["Slash"] = 0] = "Slash";
|
|
@@ -133,8 +146,7 @@ var RateLimitScope = /* @__PURE__ */ ((RateLimitScope2) => {
|
|
|
133
146
|
return RateLimitScope2;
|
|
134
147
|
})(RateLimitScope || {});
|
|
135
148
|
|
|
136
|
-
// src/validators/permissions.validator.ts
|
|
137
|
-
var import_discord = require("discord.js");
|
|
149
|
+
// src/modules/validators/permissions.validator.ts
|
|
138
150
|
function __existsAndTrue(value) {
|
|
139
151
|
return value !== void 0 && value;
|
|
140
152
|
}
|
|
@@ -233,8 +245,8 @@ function validateCommandPermissions(permissions, client, user, command) {
|
|
|
233
245
|
}
|
|
234
246
|
|
|
235
247
|
// src/builders/baseCommand.builder.ts
|
|
236
|
-
var import_node_crypto = require("crypto");
|
|
237
248
|
var import_lodash = __toESM(require("lodash"));
|
|
249
|
+
var import_node_crypto = require("crypto");
|
|
238
250
|
var BaseCommandBuilder = class {
|
|
239
251
|
uuid = (0, import_node_crypto.randomUUID)();
|
|
240
252
|
commandType;
|
|
@@ -524,55 +536,199 @@ var ContextCommandBuilder = class extends BaseCommandBuilder {
|
|
|
524
536
|
}
|
|
525
537
|
};
|
|
526
538
|
|
|
527
|
-
// src/
|
|
528
|
-
var
|
|
529
|
-
var
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
539
|
+
// src/builders/event.builder.ts
|
|
540
|
+
var import_node_crypto2 = require("crypto");
|
|
541
|
+
var import_lodash3 = __toESM(require("lodash"));
|
|
542
|
+
|
|
543
|
+
// src/tools/Logger.ts
|
|
544
|
+
var import_chalk = __toESM(require("chalk"));
|
|
545
|
+
var LogLevel = /* @__PURE__ */ ((LogLevel2) => {
|
|
546
|
+
LogLevel2[LogLevel2["DEBUG"] = 0] = "DEBUG";
|
|
547
|
+
LogLevel2[LogLevel2["INFO"] = 1] = "INFO";
|
|
548
|
+
LogLevel2[LogLevel2["SUCCESS"] = 2] = "SUCCESS";
|
|
549
|
+
LogLevel2[LogLevel2["WARN"] = 3] = "WARN";
|
|
550
|
+
LogLevel2[LogLevel2["ERROR"] = 4] = "ERROR";
|
|
551
|
+
return LogLevel2;
|
|
552
|
+
})(LogLevel || {});
|
|
553
|
+
var LOGGER_COLORS = {
|
|
554
|
+
primary: "#5865F2",
|
|
555
|
+
success: "#57F287",
|
|
556
|
+
warn: "#FEE75C",
|
|
557
|
+
danger: "#ED4245",
|
|
558
|
+
muted: "#747F8D",
|
|
559
|
+
text: "#FFFFFF"
|
|
560
|
+
};
|
|
561
|
+
var Logger = class {
|
|
562
|
+
logPrefixEmoji;
|
|
563
|
+
logPrefix;
|
|
564
|
+
minLevel;
|
|
565
|
+
showTimestamp;
|
|
566
|
+
colorScheme;
|
|
567
|
+
constructor(options) {
|
|
568
|
+
const { prefixEmoji = null, prefix = null, minLevel = 0 /* DEBUG */, showTimestamp = true } = options || {};
|
|
569
|
+
this.logPrefixEmoji = prefixEmoji;
|
|
570
|
+
this.logPrefix = prefix;
|
|
571
|
+
this.minLevel = minLevel;
|
|
572
|
+
this.showTimestamp = showTimestamp;
|
|
573
|
+
this.colorScheme = {
|
|
574
|
+
...LOGGER_COLORS,
|
|
575
|
+
...options?.colors
|
|
576
|
+
};
|
|
546
577
|
}
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
578
|
+
formatTimestamp() {
|
|
579
|
+
if (!this.showTimestamp) return "";
|
|
580
|
+
const now = /* @__PURE__ */ new Date();
|
|
581
|
+
const time = now.toLocaleTimeString("en-US", {
|
|
582
|
+
hour12: false,
|
|
583
|
+
hour: "2-digit",
|
|
584
|
+
minute: "2-digit",
|
|
585
|
+
second: "2-digit"
|
|
586
|
+
});
|
|
587
|
+
return import_chalk.default.hex(this.colorScheme.muted)(`[${time}]`);
|
|
588
|
+
}
|
|
589
|
+
formatPrefix() {
|
|
590
|
+
if (!this.logPrefix) return "";
|
|
591
|
+
return import_chalk.default.bold.hex(this.colorScheme.primary)(
|
|
592
|
+
`${this.logPrefixEmoji ? `${this.logPrefixEmoji} ` : ""}${this.logPrefix}`
|
|
593
|
+
);
|
|
594
|
+
}
|
|
595
|
+
shouldLog(level) {
|
|
596
|
+
return level >= this.minLevel;
|
|
597
|
+
}
|
|
598
|
+
get prefixEmoji() {
|
|
599
|
+
return this.logPrefixEmoji;
|
|
600
|
+
}
|
|
601
|
+
get prefix() {
|
|
602
|
+
return this.logPrefix;
|
|
603
|
+
}
|
|
604
|
+
get colors() {
|
|
605
|
+
return this.colorScheme;
|
|
606
|
+
}
|
|
607
|
+
extend(extras) {
|
|
608
|
+
for (const [key, fn] of Object.entries(extras)) {
|
|
609
|
+
if (typeof fn === "function") {
|
|
610
|
+
this[key] = function(...args) {
|
|
611
|
+
return fn.call(this, ...args);
|
|
612
|
+
};
|
|
558
613
|
}
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
);
|
|
562
|
-
const filteredModules = modules.filter((m) => m.module);
|
|
563
|
-
if (!filteredModules.length) {
|
|
564
|
-
console.warn(`No valid modules were found in directory '${dir}'`);
|
|
614
|
+
}
|
|
615
|
+
return this;
|
|
565
616
|
}
|
|
566
|
-
|
|
567
|
-
|
|
617
|
+
setPrefix(prefix) {
|
|
618
|
+
this.logPrefix = prefix;
|
|
619
|
+
return this;
|
|
620
|
+
}
|
|
621
|
+
setPrefixEmoji(prefixEmoji) {
|
|
622
|
+
this.logPrefixEmoji = prefixEmoji;
|
|
623
|
+
return this;
|
|
624
|
+
}
|
|
625
|
+
setMinLevel(minLevel) {
|
|
626
|
+
this.minLevel = minLevel;
|
|
627
|
+
return this;
|
|
628
|
+
}
|
|
629
|
+
setShowTimestamp(show) {
|
|
630
|
+
this.showTimestamp = show;
|
|
631
|
+
return this;
|
|
632
|
+
}
|
|
633
|
+
setColors(colors) {
|
|
634
|
+
this.colorScheme = {
|
|
635
|
+
...LOGGER_COLORS,
|
|
636
|
+
...colors
|
|
637
|
+
};
|
|
638
|
+
return this;
|
|
639
|
+
}
|
|
640
|
+
log(message, ...args) {
|
|
641
|
+
console.log(this.formatTimestamp(), this.formatPrefix(), message, ...args);
|
|
642
|
+
}
|
|
643
|
+
debug(message, ...args) {
|
|
644
|
+
if (!this.shouldLog(0 /* DEBUG */)) return;
|
|
645
|
+
console.log(
|
|
646
|
+
this.formatTimestamp(),
|
|
647
|
+
this.formatPrefix(),
|
|
648
|
+
import_chalk.default.hex(this.colorScheme.muted)("DEBUG"),
|
|
649
|
+
import_chalk.default.dim(message),
|
|
650
|
+
...args
|
|
651
|
+
);
|
|
652
|
+
}
|
|
653
|
+
info(message, ...args) {
|
|
654
|
+
if (!this.shouldLog(1 /* INFO */)) return;
|
|
655
|
+
console.log(this.formatTimestamp(), this.formatPrefix(), import_chalk.default.hex("#87CEEB")("INFO"), message, ...args);
|
|
656
|
+
}
|
|
657
|
+
success(message, ...args) {
|
|
658
|
+
if (!this.shouldLog(2 /* SUCCESS */)) return;
|
|
659
|
+
console.log(
|
|
660
|
+
this.formatTimestamp(),
|
|
661
|
+
this.formatPrefix(),
|
|
662
|
+
import_chalk.default.bold.hex(this.colorScheme.success)("\u2713 SUCCESS"),
|
|
663
|
+
import_chalk.default.hex(this.colorScheme.success)(message),
|
|
664
|
+
...args
|
|
665
|
+
);
|
|
666
|
+
}
|
|
667
|
+
warn(message, ...args) {
|
|
668
|
+
if (!this.shouldLog(3 /* WARN */)) return;
|
|
669
|
+
console.warn(
|
|
670
|
+
this.formatTimestamp(),
|
|
671
|
+
this.formatPrefix(),
|
|
672
|
+
import_chalk.default.bold.hex(this.colorScheme.warn)("\u26A0 WARN"),
|
|
673
|
+
import_chalk.default.hex(this.colorScheme.warn)(message),
|
|
674
|
+
...args
|
|
675
|
+
);
|
|
676
|
+
}
|
|
677
|
+
error(message, error, ...args) {
|
|
678
|
+
if (!this.shouldLog(4 /* ERROR */)) return;
|
|
679
|
+
console.error(
|
|
680
|
+
this.formatTimestamp(),
|
|
681
|
+
this.formatPrefix(),
|
|
682
|
+
import_chalk.default.bold.hex(this.colorScheme.danger)("\u2715 ERROR"),
|
|
683
|
+
import_chalk.default.hex(this.colorScheme.danger)(message),
|
|
684
|
+
...args
|
|
685
|
+
);
|
|
686
|
+
if (error && error.stack) {
|
|
687
|
+
console.error(import_chalk.default.dim(error.stack));
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
loader(message) {
|
|
691
|
+
const frames = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
692
|
+
let i = 0;
|
|
693
|
+
const interval = setInterval(() => {
|
|
694
|
+
process.stdout.write(
|
|
695
|
+
`\r${this.formatTimestamp()} ${this.formatPrefix()} ${import_chalk.default.hex(this.colorScheme.warn)(frames[i])} ${message}`
|
|
696
|
+
);
|
|
697
|
+
i = (i + 1) % frames.length;
|
|
698
|
+
}, 100);
|
|
699
|
+
return (newMessage) => {
|
|
700
|
+
clearInterval(interval);
|
|
701
|
+
process.stdout.write(
|
|
702
|
+
`\r${this.formatTimestamp()} ${this.formatPrefix()} ${import_chalk.default.hex(this.colorScheme.success)("\u2713")} ${newMessage || message}
|
|
703
|
+
`
|
|
704
|
+
);
|
|
705
|
+
};
|
|
706
|
+
}
|
|
707
|
+
table(title, data) {
|
|
708
|
+
console.log(this.formatTimestamp(), this.formatPrefix(), import_chalk.default.bold(title));
|
|
709
|
+
Object.entries(data).forEach(([key, value]) => {
|
|
710
|
+
const formattedKey = import_chalk.default.hex(this.colorScheme.warn)(` ${key}`);
|
|
711
|
+
const formattedValue = import_chalk.default.hex(this.colorScheme.muted)(value);
|
|
712
|
+
console.log(`${formattedKey.padEnd(25)} ${formattedValue}`);
|
|
713
|
+
});
|
|
714
|
+
}
|
|
715
|
+
section(title) {
|
|
716
|
+
const line = "\u2500".repeat(Math.max(30, title.length + 4));
|
|
717
|
+
console.log(import_chalk.default.hex(this.colorScheme.muted)(`
|
|
718
|
+
\u250C\u2500${line}\u2500\u2510`));
|
|
719
|
+
console.log(
|
|
720
|
+
import_chalk.default.hex(this.colorScheme.muted)("\u2502 ") + import_chalk.default.bold.hex(this.colorScheme.text)(title.padEnd(line.length)) + import_chalk.default.hex(this.colorScheme.muted)(" \u2502")
|
|
721
|
+
);
|
|
722
|
+
console.log(import_chalk.default.hex(this.colorScheme.muted)(`\u2514\u2500${line}\u2500\u2518`));
|
|
723
|
+
}
|
|
724
|
+
};
|
|
725
|
+
var logger = new Logger();
|
|
568
726
|
|
|
569
727
|
// src/builders/event.builder.ts
|
|
570
|
-
var import_node_crypto2 = require("crypto");
|
|
571
|
-
var import_lodash3 = __toESM(require("lodash"));
|
|
572
728
|
var EventBuilder = class _EventBuilder {
|
|
573
729
|
uuid = (0, import_node_crypto2.randomUUID)();
|
|
574
730
|
event;
|
|
575
|
-
name =
|
|
731
|
+
name = this.uuid;
|
|
576
732
|
enabled;
|
|
577
733
|
once;
|
|
578
734
|
priority;
|
|
@@ -737,6 +893,7 @@ var EventBuilder = class _EventBuilder {
|
|
|
737
893
|
return;
|
|
738
894
|
}
|
|
739
895
|
if (this.isRateLimited()) {
|
|
896
|
+
logger.warn(`Event '${this.name}' (${this.event}) is rate limited`);
|
|
740
897
|
if (this.rateLimit?.onRateLimit) {
|
|
741
898
|
return await this.rateLimit.onRateLimit(...args);
|
|
742
899
|
}
|
|
@@ -757,7 +914,7 @@ var EventBuilder = class _EventBuilder {
|
|
|
757
914
|
if (this.onError) {
|
|
758
915
|
return await this.onError(err, ...args);
|
|
759
916
|
}
|
|
760
|
-
|
|
917
|
+
logger.error(`Event execution error '${this.name}' (${this.event}):`, err);
|
|
761
918
|
throw err;
|
|
762
919
|
}
|
|
763
920
|
}
|
|
@@ -860,7 +1017,11 @@ var SlashCommandBuilder = class extends BaseCommandBuilder {
|
|
|
860
1017
|
if (subCommand) {
|
|
861
1018
|
const handler = this.routes.get(subCommand.toLowerCase());
|
|
862
1019
|
if (handler) return await handler(client, interaction);
|
|
863
|
-
if (config.onUnknownRouteHandler)
|
|
1020
|
+
if (config.onUnknownRouteHandler) {
|
|
1021
|
+
return await config.onUnknownRouteHandler(client, interaction);
|
|
1022
|
+
} else {
|
|
1023
|
+
return await interaction.reply({ content: `Unknown subcommand: ${subCommand}`, flags: "Ephemeral" });
|
|
1024
|
+
}
|
|
864
1025
|
}
|
|
865
1026
|
return await originalExecute?.(client, interaction);
|
|
866
1027
|
}
|
|
@@ -919,26 +1080,120 @@ var SlashCommandBuilder = class extends BaseCommandBuilder {
|
|
|
919
1080
|
}
|
|
920
1081
|
};
|
|
921
1082
|
|
|
922
|
-
// src/
|
|
923
|
-
var
|
|
924
|
-
|
|
1083
|
+
// src/modules/builtins/context-command.builtins.ts
|
|
1084
|
+
var contextCommandHandler = new EventBuilder({
|
|
1085
|
+
event: "interactionCreate",
|
|
1086
|
+
name: "ContextCommandHandler",
|
|
1087
|
+
async execute(client, interaction) {
|
|
1088
|
+
if (!interaction.isContextMenuCommand()) return;
|
|
1089
|
+
const command = client.commands.context.get(interaction.commandName);
|
|
1090
|
+
if (!command) {
|
|
1091
|
+
const content = `**${interaction.commandName}** is not a registered context command.`;
|
|
1092
|
+
if (interaction.replied || interaction.deferred) {
|
|
1093
|
+
return interaction.followUp({ content, flags: "Ephemeral" });
|
|
1094
|
+
}
|
|
1095
|
+
return interaction.reply({ content, flags: "Ephemeral" });
|
|
1096
|
+
}
|
|
1097
|
+
try {
|
|
1098
|
+
return await command.run(client, client, interaction);
|
|
1099
|
+
} catch (err) {
|
|
1100
|
+
await client.error.handleCommandError(err, interaction.guild, interaction);
|
|
1101
|
+
}
|
|
1102
|
+
}
|
|
1103
|
+
});
|
|
925
1104
|
|
|
926
|
-
// src/
|
|
927
|
-
var
|
|
928
|
-
var
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
1105
|
+
// src/modules/builtins/prefix-command.builtins.ts
|
|
1106
|
+
var import_discord4 = require("discord.js");
|
|
1107
|
+
var prefixCommandHandler = new EventBuilder({
|
|
1108
|
+
event: "messageCreate",
|
|
1109
|
+
name: "PrefixCommandHandler",
|
|
1110
|
+
async execute(client, message) {
|
|
1111
|
+
if (message.author.bot || !message.guild) return;
|
|
1112
|
+
const config = client.config.prefixCommands;
|
|
1113
|
+
let activePrefix = config.defaultPrefix;
|
|
1114
|
+
if (config.guildPrefixResolver) {
|
|
1115
|
+
try {
|
|
1116
|
+
const customPrefix = await config.guildPrefixResolver(client, message.guild.id);
|
|
1117
|
+
if (customPrefix) activePrefix = customPrefix;
|
|
1118
|
+
} catch (err) {
|
|
1119
|
+
client.logger.error(`Error in guildPrefixResolver for guild ${message.guild.id}:`, err);
|
|
1120
|
+
}
|
|
1121
|
+
}
|
|
1122
|
+
let prefixUsed;
|
|
1123
|
+
if (message.content.startsWith(activePrefix)) {
|
|
1124
|
+
prefixUsed = activePrefix;
|
|
1125
|
+
} else if (config.allowMentionAsPrefix) {
|
|
1126
|
+
const mention = (0, import_discord4.userMention)(client.user.id);
|
|
1127
|
+
if (message.content.startsWith(mention)) {
|
|
1128
|
+
prefixUsed = message.content.startsWith(`${mention} `) ? `${mention} ` : mention;
|
|
1129
|
+
}
|
|
1130
|
+
}
|
|
1131
|
+
if (!prefixUsed) return;
|
|
1132
|
+
const contentWithoutPrefix = message.content.slice(prefixUsed.length).trim();
|
|
1133
|
+
const args = contentWithoutPrefix.split(/\s+/);
|
|
1134
|
+
const trigger = args.shift();
|
|
1135
|
+
if (!trigger) return;
|
|
1136
|
+
const command = client.commands.prefix.get(trigger);
|
|
1137
|
+
if (!command) return;
|
|
1138
|
+
message.content = args.join(" ");
|
|
1139
|
+
try {
|
|
1140
|
+
return await command.run(client, client, message);
|
|
1141
|
+
} catch (err) {
|
|
1142
|
+
await client.error.handleCommandError(err, message.guild, message);
|
|
1143
|
+
}
|
|
1144
|
+
}
|
|
1145
|
+
});
|
|
1146
|
+
|
|
1147
|
+
// src/modules/builtins/slash-command.builtins.ts
|
|
1148
|
+
var slashCommandHandler = new EventBuilder({
|
|
1149
|
+
event: "interactionCreate",
|
|
1150
|
+
name: "SlashCommandHandler",
|
|
1151
|
+
async execute(client, interaction) {
|
|
1152
|
+
if (!interaction.isChatInputCommand()) return;
|
|
1153
|
+
const command = client.commands.slash.get(interaction.commandName);
|
|
1154
|
+
if (!command) {
|
|
1155
|
+
const content = `**/\`${interaction.commandName}\`** is not a registered command.`;
|
|
1156
|
+
if (interaction.replied || interaction.deferred) {
|
|
1157
|
+
return interaction.followUp({ content, flags: "Ephemeral" });
|
|
1158
|
+
}
|
|
1159
|
+
return interaction.reply({ content, flags: "Ephemeral" });
|
|
1160
|
+
}
|
|
1161
|
+
try {
|
|
1162
|
+
return await command.run(client, client, interaction);
|
|
1163
|
+
} catch (err) {
|
|
1164
|
+
await client.error.handleCommandError(err, interaction.guild, interaction);
|
|
1165
|
+
}
|
|
1166
|
+
}
|
|
1167
|
+
});
|
|
1168
|
+
|
|
1169
|
+
// src/tools/BetterEmbed.ts
|
|
1170
|
+
var import_discord6 = require("discord.js");
|
|
1171
|
+
|
|
1172
|
+
// src/utils/config.factory.ts
|
|
1173
|
+
var import_lodash5 = __toESM(require("lodash"));
|
|
1174
|
+
function createConfigFactory(defaultConfig6, validate) {
|
|
1175
|
+
return (options = {}, existing) => {
|
|
1176
|
+
const result = import_lodash5.default.merge({}, defaultConfig6, existing, options);
|
|
1177
|
+
validate?.(result);
|
|
1178
|
+
return result;
|
|
1179
|
+
};
|
|
1180
|
+
}
|
|
1181
|
+
|
|
1182
|
+
// src/configs/tools.config.ts
|
|
1183
|
+
var globalToolsConfig = {
|
|
1184
|
+
devMode: false,
|
|
1185
|
+
embedColor: [],
|
|
1186
|
+
embedColorDev: [],
|
|
1187
|
+
timeouts: {
|
|
1188
|
+
collectorTimeout: 6e4,
|
|
1189
|
+
collectorIdle: 6e4,
|
|
1190
|
+
pagination: 6e4,
|
|
1191
|
+
prompt: 3e4,
|
|
1192
|
+
modalSubmit: 6e4
|
|
1193
|
+
},
|
|
1194
|
+
collector: {
|
|
1195
|
+
notAParticipantMessage: "You are not allowed to use this.",
|
|
1196
|
+
userLockMessage: "Please wait until your current action is finished.",
|
|
942
1197
|
notAParticipantWarningCooldown: 5e3
|
|
943
1198
|
},
|
|
944
1199
|
paginator: {
|
|
@@ -960,95 +1215,13 @@ var globalVimcordToolsConfig = {
|
|
|
960
1215
|
rejectLabel: "Cancel"
|
|
961
1216
|
}
|
|
962
1217
|
};
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
function createToolsConfig(options) {
|
|
967
|
-
return import_lodash5.default.merge(globalVimcordToolsConfig, options);
|
|
968
|
-
}
|
|
969
|
-
|
|
970
|
-
// src/configs/app.config.ts
|
|
971
|
-
var import_lodash6 = __toESM(require("lodash"));
|
|
972
|
-
var defaultConfig = {
|
|
973
|
-
devMode: process.argv.includes("--dev"),
|
|
974
|
-
name: "Discord Bot",
|
|
975
|
-
appVersion: "1.0.0",
|
|
976
|
-
verbose: false,
|
|
977
|
-
disableBanner: false,
|
|
978
|
-
moduleSuffixes: {
|
|
979
|
-
slashCommand: "slash",
|
|
980
|
-
contextCommand: "ctx",
|
|
981
|
-
prefixCommand: "prefix",
|
|
982
|
-
event: "event"
|
|
983
|
-
}
|
|
984
|
-
};
|
|
985
|
-
function createVimcordAppConfig(options = {}) {
|
|
986
|
-
return import_lodash6.default.merge(defaultConfig, options);
|
|
987
|
-
}
|
|
988
|
-
|
|
989
|
-
// src/configs/staff.config.ts
|
|
990
|
-
var import_lodash7 = __toESM(require("lodash"));
|
|
991
|
-
var defaultConfig2 = {
|
|
992
|
-
ownerId: null,
|
|
993
|
-
superUsers: [],
|
|
994
|
-
superUserRoles: [],
|
|
995
|
-
bypassers: [],
|
|
996
|
-
bypassesGuildAdmin: {
|
|
997
|
-
allBotStaff: false,
|
|
998
|
-
botOwner: false,
|
|
999
|
-
superUsers: false,
|
|
1000
|
-
bypassers: false
|
|
1001
|
-
},
|
|
1002
|
-
guild: {
|
|
1003
|
-
id: null,
|
|
1004
|
-
inviteUrl: null,
|
|
1005
|
-
channels: {}
|
|
1006
|
-
}
|
|
1007
|
-
};
|
|
1008
|
-
function createVimcordStaffConfig(options = {}) {
|
|
1009
|
-
return import_lodash7.default.merge(defaultConfig2, options);
|
|
1010
|
-
}
|
|
1011
|
-
|
|
1012
|
-
// src/configs/slashCommand.config.ts
|
|
1013
|
-
var import_lodash8 = __toESM(require("lodash"));
|
|
1014
|
-
var defaultConfig3 = {
|
|
1015
|
-
logExecution: true
|
|
1016
|
-
};
|
|
1017
|
-
function createVimcordSlashCommandConfig(options = {}) {
|
|
1018
|
-
return import_lodash8.default.merge(defaultConfig3, options);
|
|
1019
|
-
}
|
|
1020
|
-
|
|
1021
|
-
// src/configs/prefixCommand.config.ts
|
|
1022
|
-
var import_lodash9 = __toESM(require("lodash"));
|
|
1023
|
-
var defaultConfig4 = {
|
|
1024
|
-
enabled: true,
|
|
1025
|
-
defaultPrefix: "!",
|
|
1026
|
-
allowMentionAsPrefix: true,
|
|
1027
|
-
allowCaseInsensitiveCommandNames: true,
|
|
1028
|
-
logExecution: true
|
|
1029
|
-
};
|
|
1030
|
-
function createVimcordPrefixCommandConfig(options = {}) {
|
|
1031
|
-
return import_lodash9.default.merge(defaultConfig4, options);
|
|
1032
|
-
}
|
|
1033
|
-
|
|
1034
|
-
// src/configs/contextCommand.config.ts
|
|
1035
|
-
var import_lodash10 = __toESM(require("lodash"));
|
|
1036
|
-
var defaultConfig5 = {
|
|
1037
|
-
enabled: true,
|
|
1038
|
-
logExecution: true
|
|
1218
|
+
var createToolsConfig = createConfigFactory(globalToolsConfig);
|
|
1219
|
+
var defineGlobalToolsConfig = (options) => {
|
|
1220
|
+
Object.assign(globalToolsConfig, createToolsConfig(options, globalToolsConfig));
|
|
1039
1221
|
};
|
|
1040
|
-
function createVimcordContextCommandConfig(options = {}) {
|
|
1041
|
-
return import_lodash10.default.merge(defaultConfig5, options);
|
|
1042
|
-
}
|
|
1043
|
-
|
|
1044
|
-
// src/utils/sendCommandErrorEmbed.ts
|
|
1045
|
-
var import_discord6 = require("discord.js");
|
|
1046
|
-
|
|
1047
|
-
// src/tools/BetterEmbed.ts
|
|
1048
|
-
var import_discord5 = require("discord.js");
|
|
1049
1222
|
|
|
1050
1223
|
// src/tools/dynaSend.ts
|
|
1051
|
-
var
|
|
1224
|
+
var import_discord5 = require("discord.js");
|
|
1052
1225
|
|
|
1053
1226
|
// src/tools/types.ts
|
|
1054
1227
|
var SendMethod = /* @__PURE__ */ ((SendMethod2) => {
|
|
@@ -1068,7 +1241,7 @@ var DynaSend = class {
|
|
|
1068
1241
|
return Array.isArray(value) ? value : [value];
|
|
1069
1242
|
}
|
|
1070
1243
|
static isInteractionCallback(obj) {
|
|
1071
|
-
return obj instanceof
|
|
1244
|
+
return obj instanceof import_discord5.InteractionCallbackResponse;
|
|
1072
1245
|
}
|
|
1073
1246
|
static filterFlags(flags, excludeFlags) {
|
|
1074
1247
|
if (!flags) return void 0;
|
|
@@ -1076,26 +1249,26 @@ var DynaSend = class {
|
|
|
1076
1249
|
return flagArray.filter((flag) => !excludeFlags.includes(flag));
|
|
1077
1250
|
}
|
|
1078
1251
|
static detectSendMethod(handler) {
|
|
1079
|
-
if (handler instanceof
|
|
1252
|
+
if (handler instanceof import_discord5.BaseInteraction) {
|
|
1080
1253
|
return handler.replied || handler.deferred ? 1 /* EditReply */ : 0 /* Reply */;
|
|
1081
1254
|
}
|
|
1082
|
-
if (handler instanceof
|
|
1083
|
-
if (handler instanceof
|
|
1084
|
-
if (handler instanceof
|
|
1255
|
+
if (handler instanceof import_discord5.BaseChannel) return 3 /* Channel */;
|
|
1256
|
+
if (handler instanceof import_discord5.Message) return 4 /* MessageReply */;
|
|
1257
|
+
if (handler instanceof import_discord5.GuildMember || handler instanceof import_discord5.User) return 6 /* User */;
|
|
1085
1258
|
throw new Error("[DynaSend] Unable to determine send method for handler type");
|
|
1086
1259
|
}
|
|
1087
1260
|
static validateSendMethod(handler, method) {
|
|
1088
1261
|
const interactionMethods = [0 /* Reply */, 1 /* EditReply */, 2 /* FollowUp */];
|
|
1089
|
-
if (interactionMethods.includes(method) && !(handler instanceof
|
|
1262
|
+
if (interactionMethods.includes(method) && !(handler instanceof import_discord5.BaseInteraction)) {
|
|
1090
1263
|
throw new TypeError(`[DynaSend] SendMethod '${SendMethod[method]}' requires BaseInteraction handler`);
|
|
1091
1264
|
}
|
|
1092
|
-
if (method === 3 /* Channel */ && !(handler instanceof
|
|
1265
|
+
if (method === 3 /* Channel */ && !(handler instanceof import_discord5.BaseChannel)) {
|
|
1093
1266
|
throw new TypeError(`[DynaSend] SendMethod '${SendMethod[method]}' requires BaseChannel handler`);
|
|
1094
1267
|
}
|
|
1095
|
-
if ([4 /* MessageReply */, 5 /* MessageEdit */].includes(method) && !(handler instanceof
|
|
1268
|
+
if ([4 /* MessageReply */, 5 /* MessageEdit */].includes(method) && !(handler instanceof import_discord5.Message)) {
|
|
1096
1269
|
throw new TypeError(`[DynaSend] SendMethod '${SendMethod[method]}' requires Message handler`);
|
|
1097
1270
|
}
|
|
1098
|
-
if (method === 6 /* User */ && !(handler instanceof
|
|
1271
|
+
if (method === 6 /* User */ && !(handler instanceof import_discord5.GuildMember || handler instanceof import_discord5.User)) {
|
|
1099
1272
|
throw new TypeError(`[DynaSend] SendMethod '${SendMethod[method]}' requires User or GuildMember handler`);
|
|
1100
1273
|
}
|
|
1101
1274
|
}
|
|
@@ -1226,7 +1399,7 @@ async function dynaSend(handler, options) {
|
|
|
1226
1399
|
|
|
1227
1400
|
// src/tools/BetterEmbed.ts
|
|
1228
1401
|
var BetterEmbed = class _BetterEmbed {
|
|
1229
|
-
embed = new
|
|
1402
|
+
embed = new import_discord6.EmbedBuilder();
|
|
1230
1403
|
data;
|
|
1231
1404
|
config;
|
|
1232
1405
|
/** A powerful wrapper for `EmbedBuilder` that introduces useful features
|
|
@@ -1255,7 +1428,7 @@ var BetterEmbed = class _BetterEmbed {
|
|
|
1255
1428
|
* - __`$month`__: _M or MM_
|
|
1256
1429
|
* - __`$day`__: _D or DD_ */
|
|
1257
1430
|
constructor(data = {}) {
|
|
1258
|
-
this.config = data.config
|
|
1431
|
+
this.config = data.config ? createToolsConfig(data.config) : globalToolsConfig;
|
|
1259
1432
|
this.data = {
|
|
1260
1433
|
context: data.context || null,
|
|
1261
1434
|
author: data.author || null,
|
|
@@ -1303,8 +1476,8 @@ var BetterEmbed = class _BetterEmbed {
|
|
|
1303
1476
|
applyContextFormatting(str) {
|
|
1304
1477
|
if (!this.data.acf) return;
|
|
1305
1478
|
const user = this.getContextUser();
|
|
1306
|
-
const guildMember = user instanceof
|
|
1307
|
-
const actualUser = guildMember?.user || (user instanceof
|
|
1479
|
+
const guildMember = user instanceof import_discord6.GuildMember ? user : null;
|
|
1480
|
+
const actualUser = guildMember?.user || (user instanceof import_discord6.User ? user : null);
|
|
1308
1481
|
const client = this.getContextClient();
|
|
1309
1482
|
const formatString = (str2) => {
|
|
1310
1483
|
if (!str2 || !str2.includes("$")) return str2;
|
|
@@ -1494,24 +1667,25 @@ var BetterEmbed = class _BetterEmbed {
|
|
|
1494
1667
|
}
|
|
1495
1668
|
};
|
|
1496
1669
|
|
|
1497
|
-
// src/utils/
|
|
1670
|
+
// src/utils/command-error.utils.ts
|
|
1671
|
+
var import_discord7 = require("discord.js");
|
|
1498
1672
|
async function sendCommandErrorEmbed(client, error, guild, messageOrInteraction) {
|
|
1499
1673
|
if (!client.features.enableCommandErrorMessage) return null;
|
|
1500
1674
|
const config = typeof client.features.enableCommandErrorMessage !== "boolean" ? client.features.enableCommandErrorMessage : void 0;
|
|
1501
1675
|
const buttons = {
|
|
1502
|
-
supportServer: new
|
|
1676
|
+
supportServer: new import_discord7.ButtonBuilder({
|
|
1503
1677
|
url: config?.inviteUrl || client.config.staff.guild.inviteUrl || "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
|
|
1504
1678
|
// may or may not be a rickroll
|
|
1505
1679
|
label: config?.inviteButtonLabel || "Support Support",
|
|
1506
|
-
style:
|
|
1680
|
+
style: import_discord7.ButtonStyle.Link
|
|
1507
1681
|
}),
|
|
1508
|
-
details: new
|
|
1682
|
+
details: new import_discord7.ButtonBuilder({
|
|
1509
1683
|
customId: "btn_details",
|
|
1510
1684
|
label: config?.detailButtonLabel || "Details",
|
|
1511
|
-
style:
|
|
1685
|
+
style: import_discord7.ButtonStyle.Secondary
|
|
1512
1686
|
})
|
|
1513
1687
|
};
|
|
1514
|
-
const actionRow = new
|
|
1688
|
+
const actionRow = new import_discord7.ActionRowBuilder({
|
|
1515
1689
|
components: config?.inviteUrl && guild?.id !== (config.inviteUrl || client.config.staff.guild.id) ? [buttons.supportServer, buttons.details] : [buttons.details]
|
|
1516
1690
|
});
|
|
1517
1691
|
const embed_error = config?.embed?.(new BetterEmbed(), error, guild) || new BetterEmbed({
|
|
@@ -1519,19 +1693,20 @@ async function sendCommandErrorEmbed(client, error, guild, messageOrInteraction)
|
|
|
1519
1693
|
title: "Something went wrong",
|
|
1520
1694
|
description: "If you keep encountering this error, please report it."
|
|
1521
1695
|
});
|
|
1522
|
-
const msg = await
|
|
1696
|
+
const msg = await dynaSend(messageOrInteraction, {
|
|
1697
|
+
embeds: [embed_error],
|
|
1523
1698
|
components: [actionRow],
|
|
1524
1699
|
flags: config?.ephemeral ? "Ephemeral" : void 0,
|
|
1525
1700
|
deleteAfter: config?.deleteAfter
|
|
1526
1701
|
});
|
|
1527
1702
|
if (!msg) return null;
|
|
1528
1703
|
const collector = msg.createMessageComponentCollector({
|
|
1529
|
-
componentType:
|
|
1704
|
+
componentType: import_discord7.ComponentType.Button,
|
|
1530
1705
|
idle: config?.detailButtonIdleTimeout ?? 3e4,
|
|
1531
1706
|
filter: (i) => i.customId === "btn_details"
|
|
1532
1707
|
});
|
|
1533
1708
|
collector.on("collect", (i) => {
|
|
1534
|
-
const attachment = new
|
|
1709
|
+
const attachment = new import_discord7.AttachmentBuilder(Buffer.from(`${error.message}
|
|
1535
1710
|
|
|
1536
1711
|
${error.stack}`), {
|
|
1537
1712
|
name: "error.txt"
|
|
@@ -1540,537 +1715,335 @@ ${error.stack}`), {
|
|
|
1540
1715
|
});
|
|
1541
1716
|
collector.on("end", () => {
|
|
1542
1717
|
buttons.details.setDisabled(true);
|
|
1543
|
-
|
|
1544
|
-
|
|
1718
|
+
dynaSend(messageOrInteraction, {
|
|
1719
|
+
embeds: [embed_error],
|
|
1720
|
+
sendMethod: messageOrInteraction instanceof import_discord7.Message ? 5 /* MessageEdit */ : void 0,
|
|
1545
1721
|
components: [actionRow]
|
|
1546
1722
|
});
|
|
1547
1723
|
});
|
|
1548
1724
|
return msg;
|
|
1549
1725
|
}
|
|
1550
1726
|
|
|
1551
|
-
// src/
|
|
1552
|
-
var
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
if (!interaction.isChatInputCommand()) return;
|
|
1557
|
-
const command = client.commands.slash.get(interaction.commandName);
|
|
1558
|
-
if (!command) {
|
|
1559
|
-
const content = `**/\`${interaction.commandName}\`** is not a registered command.`;
|
|
1560
|
-
if (interaction.replied || interaction.deferred) {
|
|
1561
|
-
return interaction.followUp({ content, flags: "Ephemeral" });
|
|
1562
|
-
}
|
|
1563
|
-
return interaction.reply({ content, flags: "Ephemeral" });
|
|
1564
|
-
}
|
|
1565
|
-
try {
|
|
1566
|
-
return await command.run(client, client, interaction);
|
|
1567
|
-
} catch (err) {
|
|
1568
|
-
await sendCommandErrorEmbed(client, err, interaction.guild, interaction);
|
|
1569
|
-
throw err;
|
|
1570
|
-
}
|
|
1727
|
+
// src/client/error-handler.ts
|
|
1728
|
+
var ErrorHandler = class {
|
|
1729
|
+
client;
|
|
1730
|
+
constructor(client) {
|
|
1731
|
+
this.client = client;
|
|
1571
1732
|
}
|
|
1572
|
-
|
|
1733
|
+
/** Handles command errors - sends error embed to user, then rethrows. */
|
|
1734
|
+
async handleCommandError(error, guild, messageOrInteraction) {
|
|
1735
|
+
await sendCommandErrorEmbed(this.client, error, guild, messageOrInteraction);
|
|
1736
|
+
throw error;
|
|
1737
|
+
}
|
|
1738
|
+
/** Handles internal Vimcord errors - logs with [Vimcord] prefix. */
|
|
1739
|
+
handleVimcordError(error, context) {
|
|
1740
|
+
this.client.logger.error(`[Vimcord] [${context}]`, error);
|
|
1741
|
+
}
|
|
1742
|
+
/** Sets up global process error handlers. */
|
|
1743
|
+
setupGlobalHandlers() {
|
|
1744
|
+
process.on("uncaughtException", (err) => this.handleVimcordError(err, "Uncaught Exception"));
|
|
1745
|
+
process.on("unhandledRejection", (err) => this.handleVimcordError(err, "Unhandled Rejection"));
|
|
1746
|
+
process.on("exit", (code) => this.client.logger.debug(`Process exited with code ${code}`));
|
|
1747
|
+
this.client.on("error", (err) => this.handleVimcordError(err, "Client Error"));
|
|
1748
|
+
this.client.on("shardError", (err) => this.handleVimcordError(err, "Client Shard Error"));
|
|
1749
|
+
}
|
|
1750
|
+
};
|
|
1573
1751
|
|
|
1574
|
-
// src/
|
|
1575
|
-
var
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
if (config.
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1752
|
+
// src/client/vimcord.logger.ts
|
|
1753
|
+
var import_chalk2 = __toESM(require("chalk"));
|
|
1754
|
+
|
|
1755
|
+
// package.json
|
|
1756
|
+
var version = "1.0.37";
|
|
1757
|
+
|
|
1758
|
+
// src/client/vimcord.logger.ts
|
|
1759
|
+
var clientLoggerFactory = (client) => new Logger({ prefixEmoji: "\u26A1", prefix: `vimcord (i${client.clientId})` }).extend({
|
|
1760
|
+
clientBanner(client2) {
|
|
1761
|
+
if (client2.config.app.disableBanner) return;
|
|
1762
|
+
const border = "\u2550".repeat(50);
|
|
1763
|
+
console.log(import_chalk2.default.hex(this.colors.primary)(`
|
|
1764
|
+
\u2554${border}\u2557`));
|
|
1765
|
+
console.log(
|
|
1766
|
+
import_chalk2.default.hex(this.colors.primary)("\u2551") + import_chalk2.default.bold.hex(this.colors.text)(
|
|
1767
|
+
` \u{1F680} ${client2.config.app.name} v${client2.$version}`.padEnd(50 - (client2.$devMode ? 12 : 0))
|
|
1768
|
+
) + import_chalk2.default.hex(this.colors.primary)(`${client2.$devMode ? import_chalk2.default.hex(this.colors.warn)("devMode \u26A0\uFE0F ") : ""}\u2551`)
|
|
1769
|
+
);
|
|
1770
|
+
console.log(import_chalk2.default.hex(this.colors.primary)(`\u2551${"".padEnd(50)}\u2551`));
|
|
1771
|
+
console.log(
|
|
1772
|
+
import_chalk2.default.hex(this.colors.primary)("\u2551") + import_chalk2.default.hex(this.colors.muted)(
|
|
1773
|
+
` # Powered by Vimcord v${version}`.padEnd(50 - 3 - `${client2.clientId}`.length)
|
|
1774
|
+
) + import_chalk2.default.hex(this.colors.primary)(`${import_chalk2.default.hex(this.colors.muted)(`i${client2.clientId}`)} \u2551`)
|
|
1775
|
+
);
|
|
1776
|
+
console.log(import_chalk2.default.hex(this.colors.primary)(`\u255A${border}\u255D
|
|
1777
|
+
`));
|
|
1778
|
+
},
|
|
1779
|
+
clientReady(clientTag, guildCount) {
|
|
1780
|
+
console.log(
|
|
1781
|
+
this.formatTimestamp(),
|
|
1782
|
+
this.formatPrefix(),
|
|
1783
|
+
import_chalk2.default.hex(this.colors.success)("\u{1F916} READY"),
|
|
1784
|
+
import_chalk2.default.white(`Connected as ${import_chalk2.default.bold.hex(this.colors.primary)(clientTag)}`),
|
|
1785
|
+
import_chalk2.default.hex(this.colors.muted)(`\u2022 ${guildCount} guilds`)
|
|
1786
|
+
);
|
|
1787
|
+
},
|
|
1788
|
+
moduleLoaded(moduleName, count, ignoredCount) {
|
|
1789
|
+
const countText = count ? import_chalk2.default.hex(this.colors.muted)(`(${count} items)`) : "";
|
|
1790
|
+
console.log(
|
|
1791
|
+
this.formatTimestamp(),
|
|
1792
|
+
this.formatPrefix(),
|
|
1793
|
+
import_chalk2.default.hex("#9B59B6")("\u{1F4E6} MODULE"),
|
|
1794
|
+
import_chalk2.default.hex(this.colors.warn)(`${moduleName} loaded`),
|
|
1795
|
+
ignoredCount ? import_chalk2.default.hex(this.colors.muted)(`(${ignoredCount} ignored)`) : "",
|
|
1796
|
+
countText
|
|
1797
|
+
);
|
|
1798
|
+
},
|
|
1799
|
+
commandExecuted(commandName, username, guildName) {
|
|
1800
|
+
const location = guildName ? `in ${import_chalk2.default.hex(this.colors.muted)(guildName)}` : "in DMs";
|
|
1801
|
+
console.log(
|
|
1802
|
+
this.formatTimestamp(),
|
|
1803
|
+
this.formatPrefix(),
|
|
1804
|
+
import_chalk2.default.hex("#87CEEB")("\u{1F4DD} COMMAND"),
|
|
1805
|
+
import_chalk2.default.hex(this.colors.warn)(`/${commandName}`),
|
|
1806
|
+
import_chalk2.default.white(`used by ${import_chalk2.default.bold(username)}`),
|
|
1807
|
+
import_chalk2.default.hex(this.colors.muted)(location)
|
|
1808
|
+
);
|
|
1809
|
+
},
|
|
1810
|
+
database(action, details) {
|
|
1811
|
+
console.log(
|
|
1812
|
+
this.formatTimestamp(),
|
|
1813
|
+
this.formatPrefix(),
|
|
1814
|
+
import_chalk2.default.hex("#FF6B9D")("\u{1F5C4}\uFE0F DATABASE"),
|
|
1815
|
+
import_chalk2.default.white(action),
|
|
1816
|
+
details ? import_chalk2.default.hex(this.colors.muted)(details) : ""
|
|
1817
|
+
);
|
|
1614
1818
|
}
|
|
1615
1819
|
});
|
|
1616
1820
|
|
|
1617
|
-
// src/
|
|
1618
|
-
var
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1821
|
+
// src/utils/process.utils.ts
|
|
1822
|
+
var import_node_fs = require("fs");
|
|
1823
|
+
var import_node_path = require("path");
|
|
1824
|
+
function getPackageJson() {
|
|
1825
|
+
return JSON.parse((0, import_node_fs.readFileSync)((0, import_node_path.join)(process.cwd(), "package.json"), "utf-8"));
|
|
1826
|
+
}
|
|
1827
|
+
function getDevMode() {
|
|
1828
|
+
return process.argv.includes("--dev");
|
|
1829
|
+
}
|
|
1830
|
+
|
|
1831
|
+
// src/configs/app.config.ts
|
|
1832
|
+
var defaultConfig = {
|
|
1833
|
+
name: "Discord Bot",
|
|
1834
|
+
version: getPackageJson()?.version ?? "1.0.0",
|
|
1835
|
+
devMode: getDevMode(),
|
|
1836
|
+
verbose: false,
|
|
1837
|
+
enableCLI: false,
|
|
1838
|
+
disableBanner: false
|
|
1839
|
+
};
|
|
1840
|
+
var createAppConfig = createConfigFactory(defaultConfig, (config) => {
|
|
1841
|
+
if (!config.name) throw new Error("App name is required");
|
|
1842
|
+
defineGlobalToolsConfig({ devMode: config.devMode });
|
|
1638
1843
|
});
|
|
1639
1844
|
|
|
1640
|
-
// src/
|
|
1641
|
-
var
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
LogLevel2[LogLevel2["INFO"] = 1] = "INFO";
|
|
1645
|
-
LogLevel2[LogLevel2["SUCCESS"] = 2] = "SUCCESS";
|
|
1646
|
-
LogLevel2[LogLevel2["WARN"] = 3] = "WARN";
|
|
1647
|
-
LogLevel2[LogLevel2["ERROR"] = 4] = "ERROR";
|
|
1648
|
-
return LogLevel2;
|
|
1649
|
-
})(LogLevel || {});
|
|
1650
|
-
var LOGGER_COLORS = {
|
|
1651
|
-
primary: "#5865F2",
|
|
1652
|
-
success: "#57F287",
|
|
1653
|
-
warn: "#FEE75C",
|
|
1654
|
-
danger: "#ED4245",
|
|
1655
|
-
muted: "#747F8D",
|
|
1656
|
-
text: "#FFFFFF"
|
|
1845
|
+
// src/configs/contextCommand.config.ts
|
|
1846
|
+
var defaultConfig2 = {
|
|
1847
|
+
enabled: true,
|
|
1848
|
+
logExecution: true
|
|
1657
1849
|
};
|
|
1658
|
-
var
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
this.logPrefix = prefix;
|
|
1668
|
-
this.minLevel = minLevel;
|
|
1669
|
-
this.showTimestamp = showTimestamp;
|
|
1670
|
-
this.colorScheme = {
|
|
1671
|
-
...LOGGER_COLORS,
|
|
1672
|
-
...options?.colors
|
|
1673
|
-
};
|
|
1674
|
-
}
|
|
1675
|
-
formatTimestamp() {
|
|
1676
|
-
if (!this.showTimestamp) return "";
|
|
1677
|
-
const now = /* @__PURE__ */ new Date();
|
|
1678
|
-
const time = now.toLocaleTimeString("en-US", {
|
|
1679
|
-
hour12: false,
|
|
1680
|
-
hour: "2-digit",
|
|
1681
|
-
minute: "2-digit",
|
|
1682
|
-
second: "2-digit"
|
|
1683
|
-
});
|
|
1684
|
-
return import_chalk.default.hex(this.colorScheme.muted)(`[${time}]`);
|
|
1685
|
-
}
|
|
1686
|
-
formatPrefix() {
|
|
1687
|
-
if (!this.logPrefix) return "";
|
|
1688
|
-
return import_chalk.default.bold.hex(this.colorScheme.primary)(
|
|
1689
|
-
`${this.logPrefixEmoji ? `${this.logPrefixEmoji} ` : ""}${this.logPrefix}`
|
|
1690
|
-
);
|
|
1691
|
-
}
|
|
1692
|
-
shouldLog(level) {
|
|
1693
|
-
return level >= this.minLevel;
|
|
1694
|
-
}
|
|
1695
|
-
get prefixEmoji() {
|
|
1696
|
-
return this.logPrefixEmoji;
|
|
1697
|
-
}
|
|
1698
|
-
get prefix() {
|
|
1699
|
-
return this.logPrefix;
|
|
1700
|
-
}
|
|
1701
|
-
get colors() {
|
|
1702
|
-
return this.colorScheme;
|
|
1703
|
-
}
|
|
1704
|
-
extend(extras) {
|
|
1705
|
-
for (const [key, fn] of Object.entries(extras)) {
|
|
1706
|
-
if (typeof fn === "function") {
|
|
1707
|
-
this[key] = function(...args) {
|
|
1708
|
-
return fn.call(this, ...args);
|
|
1709
|
-
};
|
|
1710
|
-
}
|
|
1711
|
-
}
|
|
1712
|
-
return this;
|
|
1713
|
-
}
|
|
1714
|
-
setPrefix(prefix) {
|
|
1715
|
-
this.logPrefix = prefix;
|
|
1716
|
-
return this;
|
|
1717
|
-
}
|
|
1718
|
-
setPrefixEmoji(prefixEmoji) {
|
|
1719
|
-
this.logPrefixEmoji = prefixEmoji;
|
|
1720
|
-
return this;
|
|
1721
|
-
}
|
|
1722
|
-
setMinLevel(minLevel) {
|
|
1723
|
-
this.minLevel = minLevel;
|
|
1724
|
-
return this;
|
|
1725
|
-
}
|
|
1726
|
-
setShowTimestamp(show) {
|
|
1727
|
-
this.showTimestamp = show;
|
|
1728
|
-
return this;
|
|
1729
|
-
}
|
|
1730
|
-
setColors(colors) {
|
|
1731
|
-
this.colorScheme = {
|
|
1732
|
-
...LOGGER_COLORS,
|
|
1733
|
-
...colors
|
|
1734
|
-
};
|
|
1735
|
-
return this;
|
|
1736
|
-
}
|
|
1737
|
-
log(message, ...args) {
|
|
1738
|
-
console.log(this.formatTimestamp(), this.formatPrefix(), message, ...args);
|
|
1739
|
-
}
|
|
1740
|
-
debug(message, ...args) {
|
|
1741
|
-
if (!this.shouldLog(0 /* DEBUG */)) return;
|
|
1742
|
-
console.log(
|
|
1743
|
-
this.formatTimestamp(),
|
|
1744
|
-
this.formatPrefix(),
|
|
1745
|
-
import_chalk.default.hex(this.colorScheme.muted)("DEBUG"),
|
|
1746
|
-
import_chalk.default.dim(message),
|
|
1747
|
-
...args
|
|
1748
|
-
);
|
|
1749
|
-
}
|
|
1750
|
-
info(message, ...args) {
|
|
1751
|
-
if (!this.shouldLog(1 /* INFO */)) return;
|
|
1752
|
-
console.log(this.formatTimestamp(), this.formatPrefix(), import_chalk.default.hex("#87CEEB")("INFO"), message, ...args);
|
|
1753
|
-
}
|
|
1754
|
-
success(message, ...args) {
|
|
1755
|
-
if (!this.shouldLog(2 /* SUCCESS */)) return;
|
|
1756
|
-
console.log(
|
|
1757
|
-
this.formatTimestamp(),
|
|
1758
|
-
this.formatPrefix(),
|
|
1759
|
-
import_chalk.default.bold.hex(this.colorScheme.success)("\u2713 SUCCESS"),
|
|
1760
|
-
import_chalk.default.hex(this.colorScheme.success)(message),
|
|
1761
|
-
...args
|
|
1762
|
-
);
|
|
1763
|
-
}
|
|
1764
|
-
warn(message, ...args) {
|
|
1765
|
-
if (!this.shouldLog(3 /* WARN */)) return;
|
|
1766
|
-
console.warn(
|
|
1767
|
-
this.formatTimestamp(),
|
|
1768
|
-
this.formatPrefix(),
|
|
1769
|
-
import_chalk.default.bold.hex(this.colorScheme.warn)("\u26A0 WARN"),
|
|
1770
|
-
import_chalk.default.hex(this.colorScheme.warn)(message),
|
|
1771
|
-
...args
|
|
1772
|
-
);
|
|
1773
|
-
}
|
|
1774
|
-
error(message, error, ...args) {
|
|
1775
|
-
if (!this.shouldLog(4 /* ERROR */)) return;
|
|
1776
|
-
console.error(
|
|
1777
|
-
this.formatTimestamp(),
|
|
1778
|
-
this.formatPrefix(),
|
|
1779
|
-
import_chalk.default.bold.hex(this.colorScheme.danger)("\u2715 ERROR"),
|
|
1780
|
-
import_chalk.default.hex(this.colorScheme.danger)(message),
|
|
1781
|
-
...args
|
|
1782
|
-
);
|
|
1783
|
-
if (error && error.stack) {
|
|
1784
|
-
console.error(import_chalk.default.dim(error.stack));
|
|
1785
|
-
}
|
|
1786
|
-
}
|
|
1787
|
-
loader(message) {
|
|
1788
|
-
const frames = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
1789
|
-
let i = 0;
|
|
1790
|
-
const interval = setInterval(() => {
|
|
1791
|
-
process.stdout.write(
|
|
1792
|
-
`\r${this.formatTimestamp()} ${this.formatPrefix()} ${import_chalk.default.hex(this.colorScheme.warn)(frames[i])} ${message}`
|
|
1793
|
-
);
|
|
1794
|
-
i = (i + 1) % frames.length;
|
|
1795
|
-
}, 100);
|
|
1796
|
-
return (newMessage) => {
|
|
1797
|
-
clearInterval(interval);
|
|
1798
|
-
process.stdout.write(
|
|
1799
|
-
`\r${this.formatTimestamp()} ${this.formatPrefix()} ${import_chalk.default.hex(this.colorScheme.success)("\u2713")} ${newMessage || message}
|
|
1800
|
-
`
|
|
1801
|
-
);
|
|
1802
|
-
};
|
|
1803
|
-
}
|
|
1804
|
-
table(title, data) {
|
|
1805
|
-
console.log(this.formatTimestamp(), this.formatPrefix(), import_chalk.default.bold(title));
|
|
1806
|
-
Object.entries(data).forEach(([key, value]) => {
|
|
1807
|
-
const formattedKey = import_chalk.default.hex(this.colorScheme.warn)(` ${key}`);
|
|
1808
|
-
const formattedValue = import_chalk.default.hex(this.colorScheme.muted)(value);
|
|
1809
|
-
console.log(`${formattedKey.padEnd(25)} ${formattedValue}`);
|
|
1810
|
-
});
|
|
1811
|
-
}
|
|
1812
|
-
section(title) {
|
|
1813
|
-
const line = "\u2500".repeat(Math.max(30, title.length + 4));
|
|
1814
|
-
console.log(import_chalk.default.hex(this.colorScheme.muted)(`
|
|
1815
|
-
\u250C\u2500${line}\u2500\u2510`));
|
|
1816
|
-
console.log(
|
|
1817
|
-
import_chalk.default.hex(this.colorScheme.muted)("\u2502 ") + import_chalk.default.bold.hex(this.colorScheme.text)(title.padEnd(line.length)) + import_chalk.default.hex(this.colorScheme.muted)(" \u2502")
|
|
1818
|
-
);
|
|
1819
|
-
console.log(import_chalk.default.hex(this.colorScheme.muted)(`\u2514\u2500${line}\u2500\u2518`));
|
|
1820
|
-
}
|
|
1850
|
+
var createContextCommandConfig = createConfigFactory(defaultConfig2);
|
|
1851
|
+
|
|
1852
|
+
// src/configs/prefixCommand.config.ts
|
|
1853
|
+
var defaultConfig3 = {
|
|
1854
|
+
enabled: true,
|
|
1855
|
+
defaultPrefix: "!",
|
|
1856
|
+
allowMentionAsPrefix: true,
|
|
1857
|
+
allowCaseInsensitiveCommandNames: true,
|
|
1858
|
+
logExecution: true
|
|
1821
1859
|
};
|
|
1822
|
-
var
|
|
1860
|
+
var createPrefixCommandConfig = createConfigFactory(defaultConfig3);
|
|
1823
1861
|
|
|
1824
|
-
// src/
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
}
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
if (!message.guild) return null;
|
|
1847
|
-
const member = await fetchMember(message.guild, message.mentions.users.at(index)?.id ?? arg);
|
|
1848
|
-
return idOnly ? member?.id || null : member;
|
|
1849
|
-
case "channel":
|
|
1850
|
-
const channelMention = message.mentions.channels.at(index) || null;
|
|
1851
|
-
if (!channelMention && arg) {
|
|
1852
|
-
return idOnly ? arg : message.guild ? await fetchChannel(message.guild, arg) : message.client.channels.cache.get(__zero(arg)) ?? message.client.channels.fetch(__zero(arg));
|
|
1853
|
-
} else {
|
|
1854
|
-
return idOnly ? channelMention?.id || null : channelMention;
|
|
1855
|
-
}
|
|
1856
|
-
case "role":
|
|
1857
|
-
const roleMention = message.mentions.roles.at(index) || null;
|
|
1858
|
-
if (!roleMention && arg) {
|
|
1859
|
-
return idOnly ? arg : message.guild ? await fetchRole(message.guild, arg) : null;
|
|
1860
|
-
} else {
|
|
1861
|
-
return idOnly ? roleMention?.id || null : roleMention;
|
|
1862
|
-
}
|
|
1863
|
-
default:
|
|
1864
|
-
return null;
|
|
1862
|
+
// src/configs/slashCommand.config.ts
|
|
1863
|
+
var defaultConfig4 = {
|
|
1864
|
+
logExecution: true
|
|
1865
|
+
};
|
|
1866
|
+
var createSlashCommandConfig = createConfigFactory(defaultConfig4);
|
|
1867
|
+
|
|
1868
|
+
// src/configs/staff.config.ts
|
|
1869
|
+
var defaultConfig5 = {
|
|
1870
|
+
ownerId: null,
|
|
1871
|
+
superUsers: [],
|
|
1872
|
+
superUserRoles: [],
|
|
1873
|
+
bypassers: [],
|
|
1874
|
+
bypassesGuildAdmin: {
|
|
1875
|
+
allBotStaff: false,
|
|
1876
|
+
botOwner: false,
|
|
1877
|
+
superUsers: false,
|
|
1878
|
+
bypassers: false
|
|
1879
|
+
},
|
|
1880
|
+
guild: {
|
|
1881
|
+
id: null,
|
|
1882
|
+
inviteUrl: null,
|
|
1883
|
+
channels: {}
|
|
1865
1884
|
}
|
|
1866
|
-
}
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1885
|
+
};
|
|
1886
|
+
var createStaffConfig = createConfigFactory(defaultConfig5);
|
|
1887
|
+
|
|
1888
|
+
// src/client/vimcord.utils.ts
|
|
1889
|
+
var DEFAULT_MODULE_SUFFIXES = {
|
|
1890
|
+
slashCommands: ".slash",
|
|
1891
|
+
contextCommands: ".ctx",
|
|
1892
|
+
prefixCommands: ".prefix",
|
|
1893
|
+
events: ".event"
|
|
1894
|
+
};
|
|
1895
|
+
var configSetters = {
|
|
1896
|
+
app: createAppConfig,
|
|
1897
|
+
staff: createStaffConfig,
|
|
1898
|
+
slashCommands: createSlashCommandConfig,
|
|
1899
|
+
prefixCommands: createPrefixCommandConfig,
|
|
1900
|
+
contextCommands: createContextCommandConfig
|
|
1901
|
+
};
|
|
1902
|
+
var moduleImporters = {
|
|
1903
|
+
slashCommands: (client, options, set) => {
|
|
1904
|
+
const opt = options;
|
|
1905
|
+
const dir = Array.isArray(options) ? options : opt?.dir ?? [];
|
|
1906
|
+
const suffix = Array.isArray(options) ? DEFAULT_MODULE_SUFFIXES.slashCommands : opt?.suffix ?? DEFAULT_MODULE_SUFFIXES.slashCommands;
|
|
1907
|
+
return client.commands.slash.importFrom(dir, set, suffix);
|
|
1908
|
+
},
|
|
1909
|
+
contextCommands: (client, options, set) => {
|
|
1910
|
+
const opt = options;
|
|
1911
|
+
const dir = Array.isArray(options) ? options : opt?.dir ?? [];
|
|
1912
|
+
const suffix = Array.isArray(options) ? DEFAULT_MODULE_SUFFIXES.contextCommands : opt?.suffix ?? DEFAULT_MODULE_SUFFIXES.contextCommands;
|
|
1913
|
+
return client.commands.context.importFrom(dir, set, suffix);
|
|
1914
|
+
},
|
|
1915
|
+
prefixCommands: (client, options, set) => {
|
|
1916
|
+
const opt = options;
|
|
1917
|
+
const dir = Array.isArray(options) ? options : opt?.dir ?? [];
|
|
1918
|
+
const suffix = Array.isArray(options) ? DEFAULT_MODULE_SUFFIXES.prefixCommands : opt?.suffix ?? DEFAULT_MODULE_SUFFIXES.prefixCommands;
|
|
1919
|
+
return client.commands.prefix.importFrom(dir, set, suffix);
|
|
1920
|
+
},
|
|
1921
|
+
events: (client, options, set) => {
|
|
1922
|
+
const opt = options;
|
|
1923
|
+
const dir = Array.isArray(options) ? options : opt?.dir ?? [];
|
|
1924
|
+
const suffix = Array.isArray(options) ? DEFAULT_MODULE_SUFFIXES.events : opt?.suffix ?? DEFAULT_MODULE_SUFFIXES.events;
|
|
1925
|
+
return client.events.importFrom(dir, set, suffix);
|
|
1881
1926
|
}
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
async function fetchUser(client, userId) {
|
|
1886
|
-
if (!userId) return null;
|
|
1887
|
-
return client.users.cache.get(__zero(userId)) || await client.users.fetch(__zero(userId)).catch(() => null);
|
|
1888
|
-
}
|
|
1889
|
-
async function fetchGuild(client, guildId) {
|
|
1890
|
-
if (!guildId) return null;
|
|
1891
|
-
return client.guilds.cache.get(__zero(guildId)) || await client.guilds.fetch(__zero(guildId)).catch(() => null);
|
|
1892
|
-
}
|
|
1893
|
-
async function fetchMember(guild, memberId) {
|
|
1894
|
-
if (!memberId) return null;
|
|
1895
|
-
return guild.members.cache.get(__zero(memberId)) || await guild.members.fetch(__zero(memberId)).catch(() => null);
|
|
1896
|
-
}
|
|
1897
|
-
async function fetchChannel(guild, channelId, type) {
|
|
1898
|
-
if (!channelId) return null;
|
|
1899
|
-
const channel = guild.channels.cache.get(__zero(channelId)) || await guild.channels.fetch(__zero(channelId)).catch(() => null);
|
|
1900
|
-
if (type && channel?.type !== type) return null;
|
|
1901
|
-
return channel;
|
|
1927
|
+
};
|
|
1928
|
+
function defineClientOptions(options) {
|
|
1929
|
+
return options;
|
|
1902
1930
|
}
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
return guild.roles.cache.get(__zero(roleId)) || await guild.roles.fetch(__zero(roleId)).catch(() => null) || null;
|
|
1931
|
+
function defineVimcordFeatures(features) {
|
|
1932
|
+
return features;
|
|
1906
1933
|
}
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1934
|
+
function defineVimcordConfig(config) {
|
|
1935
|
+
return {
|
|
1936
|
+
app: createAppConfig(config.app),
|
|
1937
|
+
staff: createStaffConfig(config.staff),
|
|
1938
|
+
slashCommands: createSlashCommandConfig(config.slashCommands),
|
|
1939
|
+
prefixCommands: createPrefixCommandConfig(config.prefixCommands),
|
|
1940
|
+
contextCommands: createContextCommandConfig(config.contextCommands)
|
|
1941
|
+
};
|
|
1910
1942
|
}
|
|
1943
|
+
var useClient = Vimcord.getInstance;
|
|
1944
|
+
var useReadyClient = Vimcord.getReadyInstance;
|
|
1945
|
+
var createClient = Vimcord.create;
|
|
1911
1946
|
|
|
1912
|
-
// src/
|
|
1947
|
+
// src/modules/command.manager.ts
|
|
1913
1948
|
var import_discord8 = require("discord.js");
|
|
1914
|
-
var import_lodash11 = __toESM(require("lodash"));
|
|
1915
|
-
var StatusType = /* @__PURE__ */ ((StatusType2) => {
|
|
1916
|
-
StatusType2["DND"] = "dnd";
|
|
1917
|
-
StatusType2["Idle"] = "idle";
|
|
1918
|
-
StatusType2["Online"] = "online";
|
|
1919
|
-
StatusType2["Invisible"] = "invisible";
|
|
1920
|
-
return StatusType2;
|
|
1921
|
-
})(StatusType || {});
|
|
1922
|
-
var defaultPresence = {
|
|
1923
|
-
production: {
|
|
1924
|
-
interval: 6e4,
|
|
1925
|
-
randomize: false,
|
|
1926
|
-
activity: [
|
|
1927
|
-
{ status: "online" /* Online */, type: import_discord8.ActivityType.Custom, name: "Need help? Use /help or !help" },
|
|
1928
|
-
{ status: "online" /* Online */, type: import_discord8.ActivityType.Custom, name: "Join our community!" },
|
|
1929
|
-
{ status: "online" /* Online */, type: import_discord8.ActivityType.Watching, name: "\u2728 $GUILD_COUNT servers" }
|
|
1930
|
-
]
|
|
1931
|
-
},
|
|
1932
|
-
development: {
|
|
1933
|
-
activity: { status: "dnd" /* DND */, type: import_discord8.ActivityType.Custom, name: "In development!" }
|
|
1934
|
-
}
|
|
1935
|
-
};
|
|
1936
|
-
function createVimcordStatusConfig(options = {}) {
|
|
1937
|
-
return import_lodash11.default.merge(defaultPresence, options);
|
|
1938
|
-
}
|
|
1939
1949
|
|
|
1940
|
-
// src/
|
|
1941
|
-
var
|
|
1942
|
-
var
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
this.logger.debug(`Status changed to '${activity.name}'`);
|
|
1956
|
-
}
|
|
1957
|
-
});
|
|
1958
|
-
this.emitter.on("cleared", () => {
|
|
1959
|
-
if (this.client.config.app.verbose) {
|
|
1960
|
-
this.logger.debug("Status cleared");
|
|
1961
|
-
}
|
|
1962
|
-
});
|
|
1963
|
-
}
|
|
1964
|
-
clearData() {
|
|
1965
|
-
this.task?.stop();
|
|
1966
|
-
this.task = null;
|
|
1967
|
-
this.lastActivity = null;
|
|
1968
|
-
this.lastActivityIndex = 0;
|
|
1969
|
-
return this;
|
|
1970
|
-
}
|
|
1971
|
-
async getReadyClient() {
|
|
1972
|
-
const client = await this.client.waitForReady();
|
|
1973
|
-
if (!client.user) throw new Error("Cannot manage the client's activity when its user is not hydrated");
|
|
1974
|
-
return client;
|
|
1975
|
-
}
|
|
1976
|
-
async formatActivityName(name) {
|
|
1977
|
-
name = name.replace("$USER_COUNT", import_qznt2.$.format.number(this.client.users.cache.size)).replace("$GUILD_COUNT", import_qznt2.$.format.number(this.client.guilds.cache.size)).replace(
|
|
1978
|
-
"$INVITE",
|
|
1979
|
-
this.client.config.staff.guild.inviteUrl ? this.client.config.staff.guild.inviteUrl : "<STAFF_INVITE_URL_NOT_SET>"
|
|
1980
|
-
);
|
|
1981
|
-
if (name.includes("$STAFF_GUILD_MEMBER_COUNT")) {
|
|
1982
|
-
await fetchGuild(this.client, this.client.config.staff.guild.id).then((guild) => {
|
|
1983
|
-
if (!guild) return name = name.replace("$STAFF_GUILD_MEMBER_COUNT", "<STAFF_GUILD_NOT_FOUND>");
|
|
1984
|
-
name = name.replace("$STAFF_GUILD_MEMBER_COUNT", import_qznt2.$.format.number(guild.members.cache.size));
|
|
1985
|
-
}).catch((err) => this.logger.error("Failed to fetch the staff guild", err));
|
|
1986
|
-
}
|
|
1987
|
-
return name;
|
|
1988
|
-
}
|
|
1989
|
-
async setActivity(activity) {
|
|
1990
|
-
const client = await this.getReadyClient();
|
|
1991
|
-
activity.name = await this.formatActivityName(activity.name);
|
|
1992
|
-
client.user.setStatus(activity.status);
|
|
1993
|
-
client.user.setActivity({ name: activity.name, type: activity.type, url: activity.streamUrl });
|
|
1994
|
-
this.emitter.emit("changed", activity);
|
|
1995
|
-
}
|
|
1996
|
-
async statusRotationTask(clientStatus) {
|
|
1997
|
-
let activity;
|
|
1998
|
-
if (clientStatus.randomize && Array.isArray(clientStatus.activity)) {
|
|
1999
|
-
activity = import_qznt2.$.rnd.choice(clientStatus.activity, { not: this.lastActivity });
|
|
2000
|
-
this.lastActivity = activity;
|
|
2001
|
-
} else {
|
|
2002
|
-
const activityIndex = (this.lastActivityIndex + 1) % clientStatus.activity.length;
|
|
2003
|
-
this.lastActivityIndex = activityIndex;
|
|
2004
|
-
activity = clientStatus.activity[activityIndex];
|
|
2005
|
-
}
|
|
2006
|
-
await this.setActivity(activity);
|
|
2007
|
-
this.emitter.emit("rotation", activity);
|
|
2008
|
-
}
|
|
2009
|
-
async scheduleStatusRotation(clientStatus) {
|
|
2010
|
-
if (!clientStatus.interval) throw new Error("Cannot create client activity interval without interval time");
|
|
2011
|
-
this.task?.stop();
|
|
2012
|
-
this.task = null;
|
|
2013
|
-
this.task = new import_qznt2.$.Loop(() => this.statusRotationTask(clientStatus), import_qznt2.$.math.ms(clientStatus.interval), true);
|
|
2014
|
-
this.start();
|
|
1950
|
+
// src/utils/import.utils.ts
|
|
1951
|
+
var import_node_path2 = __toESM(require("path"));
|
|
1952
|
+
var import_qznt = require("qznt");
|
|
1953
|
+
function getProcessDir() {
|
|
1954
|
+
const mainPath = process.argv[1];
|
|
1955
|
+
if (!mainPath) return "";
|
|
1956
|
+
return import_node_path2.default.dirname(mainPath);
|
|
1957
|
+
}
|
|
1958
|
+
async function importModulesFromDir(dir, suffix) {
|
|
1959
|
+
const cwd = getProcessDir();
|
|
1960
|
+
const MODULE_RELATIVE_PATH = import_node_path2.default.join(cwd, dir);
|
|
1961
|
+
const MODULE_LOG_PATH = dir;
|
|
1962
|
+
const files = import_qznt.$.fs.readDir(MODULE_RELATIVE_PATH).filter((fn) => fn.endsWith(`${suffix ? `.${suffix}` : ""}.js`) || fn.endsWith(`${suffix ? `.${suffix}` : ""}.ts`));
|
|
1963
|
+
if (!files.length) {
|
|
1964
|
+
return [];
|
|
2015
1965
|
}
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
1966
|
+
const modules = await Promise.all(
|
|
1967
|
+
files.map(async (fn) => {
|
|
1968
|
+
let _path = import_node_path2.default.join(MODULE_RELATIVE_PATH, fn);
|
|
1969
|
+
let _logPath = `./${import_node_path2.default.join(MODULE_LOG_PATH, fn)}`;
|
|
1970
|
+
let _module;
|
|
1971
|
+
try {
|
|
1972
|
+
delete require.cache[require.resolve(_path)];
|
|
1973
|
+
_module = require(_path);
|
|
1974
|
+
} catch (err) {
|
|
1975
|
+
console.warn(`Failed to import module at '${_logPath}'`, err);
|
|
1976
|
+
_module = null;
|
|
1977
|
+
}
|
|
1978
|
+
return { module: _module, path: _logPath };
|
|
1979
|
+
})
|
|
1980
|
+
);
|
|
1981
|
+
const filteredModules = modules.filter((m) => m.module);
|
|
1982
|
+
if (!filteredModules.length) {
|
|
1983
|
+
console.warn(`No valid modules were found in directory '${dir}'`);
|
|
2022
1984
|
}
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
1985
|
+
return filteredModules;
|
|
1986
|
+
}
|
|
1987
|
+
|
|
1988
|
+
// src/modules/base-module.importer.ts
|
|
1989
|
+
var ModuleImporter = class {
|
|
1990
|
+
client;
|
|
1991
|
+
constructor(client) {
|
|
1992
|
+
this.client = client;
|
|
2029
1993
|
}
|
|
2030
|
-
async set
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
if (!clientStatus.interval) {
|
|
2039
|
-
await this.setActivity(Array.isArray(clientStatus.activity) ? clientStatus.activity[0] : clientStatus.activity);
|
|
2040
|
-
} else {
|
|
2041
|
-
await this.scheduleStatusRotation(clientStatus);
|
|
1994
|
+
async importFrom(dir, set = false, suffix) {
|
|
1995
|
+
if (set) this.items.clear();
|
|
1996
|
+
const dirs = Array.isArray(dir) ? dir : [dir];
|
|
1997
|
+
const modules = [];
|
|
1998
|
+
const effectiveSuffix = Array.isArray(suffix) ? suffix[0] : suffix ?? this.itemSuffix;
|
|
1999
|
+
for (const _dir of dirs) {
|
|
2000
|
+
const results = await importModulesFromDir(_dir, effectiveSuffix ?? void 0);
|
|
2001
|
+
modules.push(...results.map(({ module: module2 }) => module2.default));
|
|
2042
2002
|
}
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
if (this.task) {
|
|
2047
|
-
this.task.stop();
|
|
2048
|
-
this.task = null;
|
|
2049
|
-
this.emitter.emit("destroyed");
|
|
2050
|
-
await this.clear();
|
|
2003
|
+
for (const module2 of modules) {
|
|
2004
|
+
const name = this.getName(module2);
|
|
2005
|
+
this.items.set(name, module2);
|
|
2051
2006
|
}
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
async clear() {
|
|
2055
|
-
const client = await this.getReadyClient();
|
|
2056
|
-
this.clearData();
|
|
2057
|
-
client.user.setActivity({ name: "" });
|
|
2058
|
-
this.emitter.emit("cleared");
|
|
2059
|
-
return this;
|
|
2007
|
+
this.client.logger.moduleLoaded(this.itemName, modules.length);
|
|
2008
|
+
return this.items;
|
|
2060
2009
|
}
|
|
2061
2010
|
};
|
|
2062
2011
|
|
|
2063
2012
|
// src/modules/command.manager.ts
|
|
2064
|
-
var
|
|
2065
|
-
var BaseCommandManager = class {
|
|
2013
|
+
var BaseCommandManager = class extends ModuleImporter {
|
|
2066
2014
|
type;
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2015
|
+
items = /* @__PURE__ */ new Map();
|
|
2016
|
+
itemSuffix;
|
|
2017
|
+
constructor(client, type, itemSuffix) {
|
|
2018
|
+
super(client);
|
|
2071
2019
|
this.type = type;
|
|
2072
|
-
|
|
2073
|
-
|
|
2020
|
+
switch (type) {
|
|
2021
|
+
case 0 /* Slash */:
|
|
2022
|
+
this.itemSuffix = itemSuffix ?? DEFAULT_MODULE_SUFFIXES.slashCommands;
|
|
2023
|
+
break;
|
|
2024
|
+
case 2 /* Context */:
|
|
2025
|
+
this.itemSuffix = itemSuffix ?? DEFAULT_MODULE_SUFFIXES.contextCommands;
|
|
2026
|
+
break;
|
|
2027
|
+
case 1 /* Prefix */:
|
|
2028
|
+
this.itemSuffix = itemSuffix ?? DEFAULT_MODULE_SUFFIXES.prefixCommands;
|
|
2029
|
+
break;
|
|
2030
|
+
}
|
|
2031
|
+
}
|
|
2032
|
+
get commands() {
|
|
2033
|
+
return this.items;
|
|
2034
|
+
}
|
|
2035
|
+
get itemName() {
|
|
2036
|
+
switch (this.type) {
|
|
2037
|
+
case 0 /* Slash */:
|
|
2038
|
+
return "Slash Commands";
|
|
2039
|
+
case 2 /* Context */:
|
|
2040
|
+
return "Context Commands";
|
|
2041
|
+
case 1 /* Prefix */:
|
|
2042
|
+
return "Prefix Commands";
|
|
2043
|
+
}
|
|
2044
|
+
}
|
|
2045
|
+
getName(module2) {
|
|
2046
|
+
return "builder" in module2 ? module2.builder.name : module2.options.name;
|
|
2074
2047
|
}
|
|
2075
2048
|
/**
|
|
2076
2049
|
* Gets a command by name.
|
|
@@ -2079,7 +2052,7 @@ var BaseCommandManager = class {
|
|
|
2079
2052
|
if (this.type === 1 /* Prefix */) {
|
|
2080
2053
|
const config = this.client.config.prefixCommands;
|
|
2081
2054
|
const search = config.allowCaseInsensitiveCommandNames ? name.toLowerCase() : name;
|
|
2082
|
-
return Array.from(this.
|
|
2055
|
+
return Array.from(this.items.values()).find((cmd) => {
|
|
2083
2056
|
const commandName = "builder" in cmd ? cmd.builder.name : cmd.options.name;
|
|
2084
2057
|
const trigger = config.allowCaseInsensitiveCommandNames ? commandName.toLowerCase() : commandName;
|
|
2085
2058
|
if (trigger === search) return true;
|
|
@@ -2090,7 +2063,7 @@ var BaseCommandManager = class {
|
|
|
2090
2063
|
}
|
|
2091
2064
|
});
|
|
2092
2065
|
} else {
|
|
2093
|
-
return this.
|
|
2066
|
+
return this.items.get(name);
|
|
2094
2067
|
}
|
|
2095
2068
|
}
|
|
2096
2069
|
/**
|
|
@@ -2099,7 +2072,7 @@ var BaseCommandManager = class {
|
|
|
2099
2072
|
getAll(options = {}) {
|
|
2100
2073
|
const matchedCommands = /* @__PURE__ */ new Map();
|
|
2101
2074
|
const isDev = this.client.config.app.devMode;
|
|
2102
|
-
for (const cmd of this.
|
|
2075
|
+
for (const cmd of this.items.values()) {
|
|
2103
2076
|
const commandName = "builder" in cmd ? cmd.builder.name : cmd.options.name;
|
|
2104
2077
|
if (options.names || options.fuzzyNames) {
|
|
2105
2078
|
const nameMatched = options.names?.includes(commandName) || options.fuzzyNames?.some((fuzzy) => commandName.includes(fuzzy));
|
|
@@ -2126,7 +2099,7 @@ var BaseCommandManager = class {
|
|
|
2126
2099
|
*/
|
|
2127
2100
|
sortByCategory() {
|
|
2128
2101
|
const categories = /* @__PURE__ */ new Map();
|
|
2129
|
-
for (const cmd of this.
|
|
2102
|
+
for (const cmd of this.items.values()) {
|
|
2130
2103
|
const metadata = cmd.options.metadata;
|
|
2131
2104
|
if (!metadata?.category) continue;
|
|
2132
2105
|
let entry = categories.get(metadata.category);
|
|
@@ -2149,52 +2122,20 @@ var BaseCommandManager = class {
|
|
|
2149
2122
|
return cat;
|
|
2150
2123
|
});
|
|
2151
2124
|
}
|
|
2152
|
-
/**
|
|
2153
|
-
* Imports command modules from a directory.
|
|
2154
|
-
* @param dir Path of one or more folders.
|
|
2155
|
-
* @param set Replaces imported command modules with the ones found.
|
|
2156
|
-
*/
|
|
2157
|
-
async importFrom(dir, set = false) {
|
|
2158
|
-
if (set) this.commands.clear();
|
|
2159
|
-
const dirs = Array.isArray(dir) ? dir : [dir];
|
|
2160
|
-
const modules = [];
|
|
2161
|
-
for (const _dir of dirs) {
|
|
2162
|
-
const results = await importModulesFromDir(_dir, this.moduleSuffix);
|
|
2163
|
-
modules.push(...results.map(({ module: module2 }) => module2.default));
|
|
2164
|
-
}
|
|
2165
|
-
for (const module2 of modules) {
|
|
2166
|
-
const commandName = "builder" in module2 ? module2.builder.name : module2.options.name;
|
|
2167
|
-
this.commands.set(commandName, module2);
|
|
2168
|
-
}
|
|
2169
|
-
let moduleType;
|
|
2170
|
-
switch (this.type) {
|
|
2171
|
-
case 0 /* Slash */:
|
|
2172
|
-
moduleType = "Slash Commands";
|
|
2173
|
-
break;
|
|
2174
|
-
case 2 /* Context */:
|
|
2175
|
-
moduleType = "Context Commands";
|
|
2176
|
-
break;
|
|
2177
|
-
case 1 /* Prefix */:
|
|
2178
|
-
moduleType = "Prefix Commands";
|
|
2179
|
-
break;
|
|
2180
|
-
}
|
|
2181
|
-
this.client.logger.moduleLoaded(moduleType, modules.length);
|
|
2182
|
-
return this.commands;
|
|
2183
|
-
}
|
|
2184
2125
|
};
|
|
2185
2126
|
var SlashCommandManager = class extends BaseCommandManager {
|
|
2186
2127
|
constructor(client) {
|
|
2187
|
-
super(client, 0 /* Slash
|
|
2128
|
+
super(client, 0 /* Slash */);
|
|
2188
2129
|
}
|
|
2189
2130
|
};
|
|
2190
2131
|
var ContextCommandManager = class extends BaseCommandManager {
|
|
2191
2132
|
constructor(client) {
|
|
2192
|
-
super(client, 2 /* Context
|
|
2133
|
+
super(client, 2 /* Context */);
|
|
2193
2134
|
}
|
|
2194
2135
|
};
|
|
2195
2136
|
var PrefixCommandManager = class extends BaseCommandManager {
|
|
2196
2137
|
constructor(client) {
|
|
2197
|
-
super(client, 1 /* Prefix
|
|
2138
|
+
super(client, 1 /* Prefix */);
|
|
2198
2139
|
}
|
|
2199
2140
|
};
|
|
2200
2141
|
var CommandManager = class {
|
|
@@ -2212,7 +2153,7 @@ var CommandManager = class {
|
|
|
2212
2153
|
return [...this.slash.getAll(options), ...this.context.getAll(options)];
|
|
2213
2154
|
}
|
|
2214
2155
|
async registerGlobal(options = {}) {
|
|
2215
|
-
const client = await this.client.
|
|
2156
|
+
const client = await Vimcord.getReadyInstance(this.client.clientId);
|
|
2216
2157
|
if (!client.rest) {
|
|
2217
2158
|
console.error(`[CommandManager] \u2716 Failed to register app commands globally: REST is not initialized`);
|
|
2218
2159
|
return;
|
|
@@ -2222,29 +2163,34 @@ var CommandManager = class {
|
|
|
2222
2163
|
console.log("[CommandManager] No commands to register globally");
|
|
2223
2164
|
return;
|
|
2224
2165
|
}
|
|
2225
|
-
console.log(
|
|
2166
|
+
console.log(
|
|
2167
|
+
`[CommandManager] Registering (${commands.length}) ${commands.length === 1 ? "command" : "commands"} globally...`
|
|
2168
|
+
);
|
|
2226
2169
|
try {
|
|
2227
|
-
await client.rest.put(
|
|
2228
|
-
console.log(`[CommandManager] \u2714 Registered app commands globally`);
|
|
2170
|
+
await client.rest.put(import_discord8.Routes.applicationCommands(client.user.id), { body: commands });
|
|
2171
|
+
console.log(`[CommandManager] \u2714 Registered app ${commands.length === 1 ? "command" : "commands"} globally`);
|
|
2229
2172
|
} catch (err) {
|
|
2230
|
-
console.error(
|
|
2173
|
+
console.error(
|
|
2174
|
+
`[CommandManager] \u2716 Failed to register app ${commands.length === 1 ? "command" : "commands"} globally`,
|
|
2175
|
+
err
|
|
2176
|
+
);
|
|
2231
2177
|
}
|
|
2232
2178
|
}
|
|
2233
2179
|
async unregisterGlobal() {
|
|
2234
|
-
const client = await this.client.
|
|
2180
|
+
const client = await Vimcord.getReadyInstance(this.client.clientId);
|
|
2235
2181
|
if (!client.rest) {
|
|
2236
2182
|
console.error(`[CommandManager] \u2716 Failed to remove app commands globally: REST is not initialized`);
|
|
2237
2183
|
return;
|
|
2238
2184
|
}
|
|
2239
2185
|
try {
|
|
2240
|
-
await client.rest.put(
|
|
2186
|
+
await client.rest.put(import_discord8.Routes.applicationCommands(client.user.id), { body: [] });
|
|
2241
2187
|
console.log(`[CommandManager] \u2714 Removed app commands globally`);
|
|
2242
2188
|
} catch (err) {
|
|
2243
2189
|
console.error(`[CommandManager] \u2716 Failed to remove app commands globally`, err);
|
|
2244
2190
|
}
|
|
2245
2191
|
}
|
|
2246
2192
|
async registerGuild(options = {}) {
|
|
2247
|
-
const client = await this.client.
|
|
2193
|
+
const client = await Vimcord.getReadyInstance(this.client.clientId);
|
|
2248
2194
|
if (!client.rest) {
|
|
2249
2195
|
console.error(`[CommandManager] \u2716 Failed to register app commands by guild: REST is not initialized`);
|
|
2250
2196
|
return;
|
|
@@ -2255,21 +2201,28 @@ var CommandManager = class {
|
|
|
2255
2201
|
return;
|
|
2256
2202
|
}
|
|
2257
2203
|
const guildIds = options.guilds || client.guilds.cache.map((g) => g.id);
|
|
2258
|
-
console.log(
|
|
2204
|
+
console.log(
|
|
2205
|
+
`[CommandManager] Registering (${commands.length}) ${commands.length === 1 ? "command" : "commands"} for ${guildIds.length} guilds...`
|
|
2206
|
+
);
|
|
2259
2207
|
await Promise.all(
|
|
2260
2208
|
guildIds.map(
|
|
2261
|
-
(guildId) => client.rest.put(
|
|
2209
|
+
(guildId) => client.rest.put(import_discord8.Routes.applicationGuildCommands(client.user.id, guildId), { body: commands }).then(() => {
|
|
2262
2210
|
const gName = client.guilds.cache.get(guildId)?.name || "n/a";
|
|
2263
|
-
console.log(
|
|
2211
|
+
console.log(
|
|
2212
|
+
`[CommandManager] \u2714 Set app ${commands.length === 1 ? "command" : "commands"} in guild: ${guildId} (${gName})`
|
|
2213
|
+
);
|
|
2264
2214
|
}).catch((err) => {
|
|
2265
2215
|
const gName = client.guilds.cache.get(guildId)?.name || "n/a";
|
|
2266
|
-
console.log(
|
|
2216
|
+
console.log(
|
|
2217
|
+
`[CommandManager] \u2716 Failed to set app ${commands.length === 1 ? "command" : "commands"} in guild: ${guildId} (${gName})`,
|
|
2218
|
+
err
|
|
2219
|
+
);
|
|
2267
2220
|
})
|
|
2268
2221
|
)
|
|
2269
2222
|
);
|
|
2270
2223
|
}
|
|
2271
2224
|
async unregisterGuild(options = {}) {
|
|
2272
|
-
const client = await this.client.
|
|
2225
|
+
const client = await Vimcord.getReadyInstance(this.client.clientId);
|
|
2273
2226
|
if (!client.rest) {
|
|
2274
2227
|
console.error(`[CommandManager] \u2716 Failed to register app commands by guild: REST is not initialized`);
|
|
2275
2228
|
return;
|
|
@@ -2278,31 +2231,35 @@ var CommandManager = class {
|
|
|
2278
2231
|
console.log(`[CommandManager] Unregistering commands from ${guildIds.length} guilds...`);
|
|
2279
2232
|
await Promise.all(
|
|
2280
2233
|
guildIds.map(
|
|
2281
|
-
(guildId) => client.rest.put(
|
|
2234
|
+
(guildId) => client.rest.put(import_discord8.Routes.applicationGuildCommands(client.user.id, guildId), { body: [] }).then(() => console.log(`[CommandManager] \u2714 Removed app commands in guild: ${guildId}`)).catch((err) => console.log(`[CommandManager] \u2716 Failed to remove app commands in guild: ${guildId}`, err))
|
|
2282
2235
|
)
|
|
2283
2236
|
);
|
|
2284
2237
|
}
|
|
2285
2238
|
};
|
|
2286
2239
|
|
|
2287
2240
|
// src/modules/event.manager.ts
|
|
2288
|
-
var
|
|
2289
|
-
var EventManager = class {
|
|
2290
|
-
|
|
2291
|
-
|
|
2241
|
+
var import_discord9 = require("discord.js");
|
|
2242
|
+
var EventManager = class extends ModuleImporter {
|
|
2243
|
+
items = /* @__PURE__ */ new Map();
|
|
2244
|
+
itemSuffix = "event";
|
|
2245
|
+
itemName = "Event Handlers";
|
|
2292
2246
|
logger;
|
|
2293
2247
|
constructor(client) {
|
|
2294
|
-
|
|
2248
|
+
super(client);
|
|
2295
2249
|
this.logger = new Logger({ prefixEmoji: "\u{1F4CB}", prefix: `EventManager (i${this.client.clientId})` });
|
|
2296
|
-
for (const event of Object.values(
|
|
2250
|
+
for (const event of Object.values(import_discord9.Events)) {
|
|
2297
2251
|
client.on(
|
|
2298
2252
|
event.toString(),
|
|
2299
2253
|
async (...args) => this.executeEvents.apply(this, [event, ...args])
|
|
2300
2254
|
);
|
|
2301
2255
|
}
|
|
2302
2256
|
}
|
|
2257
|
+
getName(module2) {
|
|
2258
|
+
return module2.name;
|
|
2259
|
+
}
|
|
2303
2260
|
register(...events) {
|
|
2304
2261
|
for (const event of events) {
|
|
2305
|
-
this.
|
|
2262
|
+
this.items.set(event.name, event);
|
|
2306
2263
|
if (this.client.config.app.verbose) {
|
|
2307
2264
|
this.logger.debug(`'${event.name}' registered for EventType '${event.event}'`);
|
|
2308
2265
|
}
|
|
@@ -2310,95 +2267,348 @@ var EventManager = class {
|
|
|
2310
2267
|
}
|
|
2311
2268
|
unregister(...names) {
|
|
2312
2269
|
for (const name of names) {
|
|
2313
|
-
const event = this.
|
|
2270
|
+
const event = this.items.get(name);
|
|
2314
2271
|
if (!event) continue;
|
|
2315
|
-
this.
|
|
2272
|
+
this.items.delete(name);
|
|
2316
2273
|
if (this.client.config.app.verbose) {
|
|
2317
2274
|
this.logger.debug(`'${event.name}' unregistered for EventType '${event.event}'`);
|
|
2318
2275
|
}
|
|
2319
2276
|
}
|
|
2320
2277
|
}
|
|
2321
|
-
clear() {
|
|
2322
|
-
this.
|
|
2323
|
-
this.
|
|
2278
|
+
clear() {
|
|
2279
|
+
this.items.forEach((e) => this.unregister(e.name));
|
|
2280
|
+
this.items.clear();
|
|
2281
|
+
}
|
|
2282
|
+
get(name) {
|
|
2283
|
+
return this.items.get(name);
|
|
2284
|
+
}
|
|
2285
|
+
getByTag(tag) {
|
|
2286
|
+
return Array.from(this.items.values()).filter((event) => event.metadata?.tags?.includes(tag));
|
|
2287
|
+
}
|
|
2288
|
+
getByCategory(category) {
|
|
2289
|
+
return Array.from(this.items.values()).filter((event) => event.metadata?.category?.includes(category));
|
|
2290
|
+
}
|
|
2291
|
+
getByEvent(eventType) {
|
|
2292
|
+
return Array.from(this.items.values()).filter((event) => event.event === eventType);
|
|
2293
|
+
}
|
|
2294
|
+
async executeEvents(eventType, ...args) {
|
|
2295
|
+
const events = this.getByEvent(eventType);
|
|
2296
|
+
if (!events.length) return;
|
|
2297
|
+
const sortedEvents = events.sort((a, b) => b.priority - a.priority);
|
|
2298
|
+
await Promise.all(
|
|
2299
|
+
sortedEvents.map(async (event) => {
|
|
2300
|
+
try {
|
|
2301
|
+
await event.execute?.(this.client, ...args);
|
|
2302
|
+
if (event.once) {
|
|
2303
|
+
this.unregister(event.name);
|
|
2304
|
+
}
|
|
2305
|
+
} catch (err) {
|
|
2306
|
+
this.logger.error(`'${event.name}' failed to execute`, err);
|
|
2307
|
+
}
|
|
2308
|
+
})
|
|
2309
|
+
);
|
|
2310
|
+
}
|
|
2311
|
+
};
|
|
2312
|
+
|
|
2313
|
+
// src/tools/utils.ts
|
|
2314
|
+
var MENTION_OR_SNOWFLAKE_REGEX = /<@[#&]?[\d]{6,}>|[\d]{6,}/;
|
|
2315
|
+
var fetchUserPromises = /* @__PURE__ */ new Map();
|
|
2316
|
+
var fetchGuildPromises = /* @__PURE__ */ new Map();
|
|
2317
|
+
var fetchMemberPromises = /* @__PURE__ */ new Map();
|
|
2318
|
+
var fetchChannelPromises = /* @__PURE__ */ new Map();
|
|
2319
|
+
var fetchMessagePromises = /* @__PURE__ */ new Map();
|
|
2320
|
+
var fetchRolePromises = /* @__PURE__ */ new Map();
|
|
2321
|
+
function createCachedFetch(cache, fetchFn, cacheKey) {
|
|
2322
|
+
const cached = cache.get(cacheKey);
|
|
2323
|
+
if (cached) return cached;
|
|
2324
|
+
const promise = fetchFn().finally(() => cache.delete(cacheKey));
|
|
2325
|
+
cache.set(cacheKey, promise);
|
|
2326
|
+
return promise;
|
|
2327
|
+
}
|
|
2328
|
+
function __zero(str) {
|
|
2329
|
+
return str?.length ? str : "0";
|
|
2330
|
+
}
|
|
2331
|
+
function isMentionOrSnowflake(str) {
|
|
2332
|
+
return str ? MENTION_OR_SNOWFLAKE_REGEX.test(str) : false;
|
|
2333
|
+
}
|
|
2334
|
+
function cleanMention(str) {
|
|
2335
|
+
return str ? str.replaceAll(/[<@#&>]/g, "").trim() : void 0;
|
|
2336
|
+
}
|
|
2337
|
+
async function getMessageMention(message, content, type, index = 0, idOnly) {
|
|
2338
|
+
const args = content?.split(" ");
|
|
2339
|
+
const arg = isMentionOrSnowflake(args?.[index]) ? cleanMention(args?.[index]) : void 0;
|
|
2340
|
+
switch (type) {
|
|
2341
|
+
case "user": {
|
|
2342
|
+
const userMention2 = message.mentions.users.at(index) || null;
|
|
2343
|
+
if (!userMention2 && arg) {
|
|
2344
|
+
return idOnly ? arg : await fetchUser(message.client, arg);
|
|
2345
|
+
}
|
|
2346
|
+
return idOnly ? userMention2?.id || null : userMention2;
|
|
2347
|
+
}
|
|
2348
|
+
case "member": {
|
|
2349
|
+
if (!message.guild) return null;
|
|
2350
|
+
const member = await fetchMember(message.guild, message.mentions.users.at(index)?.id ?? arg);
|
|
2351
|
+
return idOnly ? member?.id || null : member;
|
|
2352
|
+
}
|
|
2353
|
+
case "channel": {
|
|
2354
|
+
const channelMention = message.mentions.channels.at(index) || null;
|
|
2355
|
+
if (!channelMention && arg) {
|
|
2356
|
+
if (idOnly) return arg;
|
|
2357
|
+
const channel = message.guild ? await fetchChannel(message.guild, arg) : message.client.channels.cache.get(__zero(arg)) ?? message.client.channels.fetch(__zero(arg));
|
|
2358
|
+
return channel;
|
|
2359
|
+
}
|
|
2360
|
+
return idOnly ? channelMention?.id || null : channelMention;
|
|
2361
|
+
}
|
|
2362
|
+
case "role": {
|
|
2363
|
+
const roleMention = message.mentions.roles.at(index) || null;
|
|
2364
|
+
if (!roleMention && arg) {
|
|
2365
|
+
if (idOnly) return arg;
|
|
2366
|
+
return message.guild ? await fetchRole(message.guild, arg) : null;
|
|
2367
|
+
}
|
|
2368
|
+
return idOnly ? roleMention?.id || null : roleMention;
|
|
2369
|
+
}
|
|
2370
|
+
default:
|
|
2371
|
+
return null;
|
|
2372
|
+
}
|
|
2373
|
+
}
|
|
2374
|
+
function getFirstMentionId(options) {
|
|
2375
|
+
let mentionId = "";
|
|
2376
|
+
if (options.message) {
|
|
2377
|
+
switch (options.type) {
|
|
2378
|
+
case "user":
|
|
2379
|
+
mentionId = options.message.mentions.users.first()?.id || "";
|
|
2380
|
+
break;
|
|
2381
|
+
case "member":
|
|
2382
|
+
mentionId = options.message.mentions.members?.first()?.id || "";
|
|
2383
|
+
break;
|
|
2384
|
+
case "channel":
|
|
2385
|
+
mentionId = options.message.mentions.channels.first()?.id || "";
|
|
2386
|
+
break;
|
|
2387
|
+
case "role":
|
|
2388
|
+
mentionId = options.message.mentions.roles.first()?.id || "";
|
|
2389
|
+
break;
|
|
2390
|
+
}
|
|
2391
|
+
}
|
|
2392
|
+
const firstArg = options.content?.split(" ")[0] || "";
|
|
2393
|
+
return mentionId || isMentionOrSnowflake(firstArg) ? cleanMention(firstArg) : "";
|
|
2394
|
+
}
|
|
2395
|
+
async function fetchUser(client, userId) {
|
|
2396
|
+
if (!userId) return null;
|
|
2397
|
+
const key = `${client.user.id}-${userId}`;
|
|
2398
|
+
const cached = client.users.cache.get(__zero(userId));
|
|
2399
|
+
if (cached) return cached;
|
|
2400
|
+
return createCachedFetch(fetchUserPromises, () => client.users.fetch(__zero(userId)).catch(() => null), key);
|
|
2401
|
+
}
|
|
2402
|
+
async function fetchGuild(client, guildId) {
|
|
2403
|
+
if (!guildId) return null;
|
|
2404
|
+
const key = `${client.user.id}-${guildId}`;
|
|
2405
|
+
const cached = client.guilds.cache.get(__zero(guildId));
|
|
2406
|
+
if (cached) return cached;
|
|
2407
|
+
return createCachedFetch(fetchGuildPromises, () => client.guilds.fetch(__zero(guildId)).catch(() => null), key);
|
|
2408
|
+
}
|
|
2409
|
+
async function fetchMember(guild, memberId) {
|
|
2410
|
+
if (!memberId) return null;
|
|
2411
|
+
const key = `${guild.id}-${memberId}`;
|
|
2412
|
+
const cached = guild.members.cache.get(__zero(memberId));
|
|
2413
|
+
if (cached) return cached;
|
|
2414
|
+
return createCachedFetch(fetchMemberPromises, () => guild.members.fetch(__zero(memberId)).catch(() => null), key);
|
|
2415
|
+
}
|
|
2416
|
+
async function fetchChannel(guild, channelId, type) {
|
|
2417
|
+
if (!channelId) return null;
|
|
2418
|
+
const key = `${guild.id}-${channelId}`;
|
|
2419
|
+
const cached = guild.channels.cache.get(__zero(channelId)) ?? null;
|
|
2420
|
+
if (cached) {
|
|
2421
|
+
if (type && cached.type !== type) return null;
|
|
2422
|
+
return cached;
|
|
2423
|
+
}
|
|
2424
|
+
const channel = await createCachedFetch(
|
|
2425
|
+
fetchChannelPromises,
|
|
2426
|
+
() => guild.channels.fetch(__zero(channelId)).catch(() => null),
|
|
2427
|
+
key
|
|
2428
|
+
);
|
|
2429
|
+
if (type && channel?.type !== type) return null;
|
|
2430
|
+
return channel;
|
|
2431
|
+
}
|
|
2432
|
+
async function fetchMessage(channel, messageId) {
|
|
2433
|
+
if (!messageId) return null;
|
|
2434
|
+
const key = `${channel.guild.id}-${messageId}`;
|
|
2435
|
+
const cached = channel.messages.cache.get(__zero(messageId));
|
|
2436
|
+
if (cached) return cached;
|
|
2437
|
+
return createCachedFetch(fetchMessagePromises, () => channel.messages.fetch(__zero(messageId)).catch(() => null), key);
|
|
2438
|
+
}
|
|
2439
|
+
async function fetchRole(guild, roleId) {
|
|
2440
|
+
if (!roleId) return null;
|
|
2441
|
+
const key = `${guild.id}-${roleId}`;
|
|
2442
|
+
const cached = guild.roles.cache.get(__zero(roleId));
|
|
2443
|
+
if (cached) return cached;
|
|
2444
|
+
return createCachedFetch(fetchRolePromises, () => guild.roles.fetch(__zero(roleId)).catch(() => null), key);
|
|
2445
|
+
}
|
|
2446
|
+
|
|
2447
|
+
// src/types/status.ts
|
|
2448
|
+
var import_discord10 = require("discord.js");
|
|
2449
|
+
var import_lodash6 = __toESM(require("lodash"));
|
|
2450
|
+
var StatusType = /* @__PURE__ */ ((StatusType2) => {
|
|
2451
|
+
StatusType2["DND"] = "dnd";
|
|
2452
|
+
StatusType2["Idle"] = "idle";
|
|
2453
|
+
StatusType2["Online"] = "online";
|
|
2454
|
+
StatusType2["Invisible"] = "invisible";
|
|
2455
|
+
return StatusType2;
|
|
2456
|
+
})(StatusType || {});
|
|
2457
|
+
var defaultPresence = {
|
|
2458
|
+
production: {
|
|
2459
|
+
interval: 6e4,
|
|
2460
|
+
randomize: false,
|
|
2461
|
+
activity: [
|
|
2462
|
+
{ status: "online" /* Online */, type: import_discord10.ActivityType.Custom, name: "Need help? Use /help or !help" },
|
|
2463
|
+
{ status: "online" /* Online */, type: import_discord10.ActivityType.Custom, name: "Join our community!" },
|
|
2464
|
+
{ status: "online" /* Online */, type: import_discord10.ActivityType.Watching, name: "\u2728 $GUILD_COUNT servers" }
|
|
2465
|
+
]
|
|
2466
|
+
},
|
|
2467
|
+
development: {
|
|
2468
|
+
activity: { status: "dnd" /* DND */, type: import_discord10.ActivityType.Custom, name: "In development!" }
|
|
2469
|
+
}
|
|
2470
|
+
};
|
|
2471
|
+
function createVimcordStatusConfig(options = {}) {
|
|
2472
|
+
return import_lodash6.default.merge(defaultPresence, options);
|
|
2473
|
+
}
|
|
2474
|
+
|
|
2475
|
+
// src/modules/status.manager.ts
|
|
2476
|
+
var import_node_events = __toESM(require("events"));
|
|
2477
|
+
var import_qznt2 = require("qznt");
|
|
2478
|
+
var StatusManager = class {
|
|
2479
|
+
client;
|
|
2480
|
+
logger;
|
|
2481
|
+
emitter = new import_node_events.default();
|
|
2482
|
+
lastActivity = null;
|
|
2483
|
+
lastActivityIndex = 0;
|
|
2484
|
+
task = null;
|
|
2485
|
+
constructor(client) {
|
|
2486
|
+
this.client = client;
|
|
2487
|
+
this.logger = new Logger({ prefixEmoji: "\u{1F4AC}", prefix: `StatusManager (i${this.client.clientId})` });
|
|
2488
|
+
this.emitter.on("changed", (activity) => {
|
|
2489
|
+
if (this.client.config.app.verbose) {
|
|
2490
|
+
this.logger.debug(`Status changed to '${activity.name}'`);
|
|
2491
|
+
}
|
|
2492
|
+
});
|
|
2493
|
+
this.emitter.on("cleared", () => {
|
|
2494
|
+
if (this.client.config.app.verbose) {
|
|
2495
|
+
this.logger.debug("Status cleared");
|
|
2496
|
+
}
|
|
2497
|
+
});
|
|
2498
|
+
}
|
|
2499
|
+
clearData() {
|
|
2500
|
+
this.task?.stop();
|
|
2501
|
+
this.task = null;
|
|
2502
|
+
this.lastActivity = null;
|
|
2503
|
+
this.lastActivityIndex = 0;
|
|
2504
|
+
return this;
|
|
2505
|
+
}
|
|
2506
|
+
async getReadyClient() {
|
|
2507
|
+
const client = await Vimcord.getReadyInstance(this.client.clientId);
|
|
2508
|
+
if (!client.user) throw new Error("Cannot manage the client's activity when its user is not hydrated");
|
|
2509
|
+
return client;
|
|
2510
|
+
}
|
|
2511
|
+
async formatActivityName(name) {
|
|
2512
|
+
name = name.replace("$USER_COUNT", import_qznt2.$.format.number(this.client.users.cache.size)).replace("$GUILD_COUNT", import_qznt2.$.format.number(this.client.guilds.cache.size)).replace(
|
|
2513
|
+
"$INVITE",
|
|
2514
|
+
this.client.config.staff.guild.inviteUrl ? this.client.config.staff.guild.inviteUrl : "<STAFF_INVITE_URL_NOT_SET>"
|
|
2515
|
+
);
|
|
2516
|
+
if (name.includes("$STAFF_GUILD_MEMBER_COUNT")) {
|
|
2517
|
+
await fetchGuild(this.client, this.client.config.staff.guild.id).then((guild) => {
|
|
2518
|
+
if (!guild) return name = name.replace("$STAFF_GUILD_MEMBER_COUNT", "<STAFF_GUILD_NOT_FOUND>");
|
|
2519
|
+
name = name.replace("$STAFF_GUILD_MEMBER_COUNT", import_qznt2.$.format.number(guild.members.cache.size));
|
|
2520
|
+
}).catch((err) => this.logger.error("Failed to fetch the staff guild", err));
|
|
2521
|
+
}
|
|
2522
|
+
return name;
|
|
2523
|
+
}
|
|
2524
|
+
async setActivity(activity) {
|
|
2525
|
+
const client = await this.getReadyClient();
|
|
2526
|
+
activity.name = await this.formatActivityName(activity.name);
|
|
2527
|
+
client.user.setStatus(activity.status);
|
|
2528
|
+
client.user.setActivity({ name: activity.name, type: activity.type, url: activity.streamUrl });
|
|
2529
|
+
this.emitter.emit("changed", activity);
|
|
2324
2530
|
}
|
|
2325
|
-
|
|
2326
|
-
|
|
2531
|
+
async statusRotationTask(clientStatus) {
|
|
2532
|
+
let activity;
|
|
2533
|
+
if (clientStatus.randomize && Array.isArray(clientStatus.activity)) {
|
|
2534
|
+
activity = import_qznt2.$.rnd.choice(clientStatus.activity, { not: this.lastActivity });
|
|
2535
|
+
this.lastActivity = activity;
|
|
2536
|
+
} else {
|
|
2537
|
+
const activityIndex = (this.lastActivityIndex + 1) % clientStatus.activity.length;
|
|
2538
|
+
this.lastActivityIndex = activityIndex;
|
|
2539
|
+
activity = clientStatus.activity[activityIndex];
|
|
2540
|
+
}
|
|
2541
|
+
await this.setActivity(activity);
|
|
2542
|
+
this.emitter.emit("rotation", activity);
|
|
2327
2543
|
}
|
|
2328
|
-
|
|
2329
|
-
|
|
2544
|
+
async scheduleStatusRotation(clientStatus) {
|
|
2545
|
+
if (!clientStatus.interval) throw new Error("Cannot create client activity interval without interval time");
|
|
2546
|
+
this.task?.stop();
|
|
2547
|
+
this.task = null;
|
|
2548
|
+
this.task = new import_qznt2.$.Loop(() => this.statusRotationTask(clientStatus), import_qznt2.$.math.ms(clientStatus.interval), true);
|
|
2549
|
+
this.start();
|
|
2330
2550
|
}
|
|
2331
|
-
|
|
2332
|
-
|
|
2551
|
+
start() {
|
|
2552
|
+
if (this.task) {
|
|
2553
|
+
this.task.start();
|
|
2554
|
+
this.emitter.emit("started", this.task);
|
|
2555
|
+
}
|
|
2556
|
+
return this;
|
|
2333
2557
|
}
|
|
2334
|
-
|
|
2335
|
-
|
|
2558
|
+
pause() {
|
|
2559
|
+
if (this.task) {
|
|
2560
|
+
this.task.stop();
|
|
2561
|
+
this.emitter.emit("paused", this.task);
|
|
2562
|
+
}
|
|
2563
|
+
return this;
|
|
2336
2564
|
}
|
|
2337
|
-
async
|
|
2338
|
-
const
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
})
|
|
2352
|
-
);
|
|
2565
|
+
async set(status) {
|
|
2566
|
+
const statusConfig = createVimcordStatusConfig(status);
|
|
2567
|
+
let clientStatus;
|
|
2568
|
+
if (this.client.config.app.devMode) {
|
|
2569
|
+
clientStatus = statusConfig.development;
|
|
2570
|
+
} else {
|
|
2571
|
+
clientStatus = statusConfig.production;
|
|
2572
|
+
}
|
|
2573
|
+
if (!clientStatus.interval) {
|
|
2574
|
+
await this.setActivity(Array.isArray(clientStatus.activity) ? clientStatus.activity[0] : clientStatus.activity);
|
|
2575
|
+
} else {
|
|
2576
|
+
await this.scheduleStatusRotation(clientStatus);
|
|
2577
|
+
}
|
|
2578
|
+
return this;
|
|
2353
2579
|
}
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
if (replaceAll) {
|
|
2361
|
-
this.clear();
|
|
2362
|
-
}
|
|
2363
|
-
let importedEvents = 0;
|
|
2364
|
-
let ignoredEvents = 0;
|
|
2365
|
-
for (const event of eventModules.flat()) {
|
|
2366
|
-
if (!event.module.default.enabled) {
|
|
2367
|
-
ignoredEvents++;
|
|
2368
|
-
} else {
|
|
2369
|
-
importedEvents++;
|
|
2370
|
-
}
|
|
2371
|
-
this.register(event.module.default);
|
|
2580
|
+
async destroy() {
|
|
2581
|
+
if (this.task) {
|
|
2582
|
+
this.task.stop();
|
|
2583
|
+
this.task = null;
|
|
2584
|
+
this.emitter.emit("destroyed");
|
|
2585
|
+
await this.clear();
|
|
2372
2586
|
}
|
|
2373
|
-
this
|
|
2374
|
-
|
|
2587
|
+
return this;
|
|
2588
|
+
}
|
|
2589
|
+
async clear() {
|
|
2590
|
+
const client = await this.getReadyClient();
|
|
2591
|
+
this.clearData();
|
|
2592
|
+
client.user.setActivity({ name: "" });
|
|
2593
|
+
this.emitter.emit("cleared");
|
|
2594
|
+
return this;
|
|
2375
2595
|
}
|
|
2376
2596
|
};
|
|
2377
2597
|
|
|
2378
|
-
//
|
|
2379
|
-
var version = "1.0.35";
|
|
2380
|
-
|
|
2381
|
-
// src/client.ts
|
|
2382
|
-
var import_node_crypto3 = require("crypto");
|
|
2383
|
-
var import_qznt4 = require("qznt");
|
|
2384
|
-
|
|
2385
|
-
// src/utils/VimcordCLI.ts
|
|
2598
|
+
// src/utils/vimcord.cli.ts
|
|
2386
2599
|
var import_node_readline = require("readline");
|
|
2387
2600
|
var import_qznt3 = require("qznt");
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
}
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
}
|
|
2399
|
-
|
|
2400
|
-
// src/utils/VimcordCLI.ts
|
|
2401
|
-
var VimcordCLI = class {
|
|
2601
|
+
var VimcordCLI = class _VimcordCLI {
|
|
2602
|
+
static mode = "off";
|
|
2603
|
+
static setMode(mode) {
|
|
2604
|
+
if (_VimcordCLI.mode === mode) return;
|
|
2605
|
+
_VimcordCLI.mode = mode;
|
|
2606
|
+
if (mode === "on") {
|
|
2607
|
+
CLI.logger.log(`~ Type ${CLI.options.prefix}help to view available commands`);
|
|
2608
|
+
} else {
|
|
2609
|
+
CLI.logger.log(`~ [MODE] Now set to "${mode}"`);
|
|
2610
|
+
}
|
|
2611
|
+
}
|
|
2402
2612
|
rl;
|
|
2403
2613
|
options;
|
|
2404
2614
|
commands = /* @__PURE__ */ new Map();
|
|
@@ -2411,6 +2621,7 @@ var VimcordCLI = class {
|
|
|
2411
2621
|
terminal: false
|
|
2412
2622
|
});
|
|
2413
2623
|
this.rl.on("line", (line) => {
|
|
2624
|
+
if (_VimcordCLI.mode !== "on") return;
|
|
2414
2625
|
const { isCommand, commandName, content, args } = this.parseLine(line);
|
|
2415
2626
|
if (!isCommand) return;
|
|
2416
2627
|
const command = this.commands.get(commandName);
|
|
@@ -2467,7 +2678,6 @@ var VimcordCLI = class {
|
|
|
2467
2678
|
return true;
|
|
2468
2679
|
}
|
|
2469
2680
|
};
|
|
2470
|
-
var initCalled = false;
|
|
2471
2681
|
var CLI = new VimcordCLI({ prefix: "/" });
|
|
2472
2682
|
CLI.addCommand("help", "View information about a command, or the available CLI options", (args) => {
|
|
2473
2683
|
const prefix = CLI.options.prefix;
|
|
@@ -2574,16 +2784,81 @@ CLI.addCommand("cmds", "List the loaded commands", async (args, content) => {
|
|
|
2574
2784
|
return CLI.logger.error(`'${mode}' is not a valid option. Valid options: [slash|prefix|ctx]`);
|
|
2575
2785
|
}
|
|
2576
2786
|
});
|
|
2577
|
-
function initCLI() {
|
|
2578
|
-
if (initCalled) return;
|
|
2579
|
-
CLI.logger.log(`~ Type ${CLI.options.prefix}help to view available commands`);
|
|
2580
|
-
initCalled = true;
|
|
2581
|
-
}
|
|
2582
2787
|
|
|
2583
|
-
// src/client.ts
|
|
2584
|
-
var
|
|
2788
|
+
// src/client/Vimcord.ts
|
|
2789
|
+
var import_discord11 = require("discord.js");
|
|
2790
|
+
var import_dotenv = require("dotenv");
|
|
2791
|
+
var import_node_crypto3 = require("crypto");
|
|
2792
|
+
var import_node_events2 = __toESM(require("events"));
|
|
2793
|
+
var import_qznt4 = require("qznt");
|
|
2585
2794
|
var Vimcord = class _Vimcord extends import_discord11.Client {
|
|
2586
2795
|
static instances = /* @__PURE__ */ new Map();
|
|
2796
|
+
static emitter = new import_node_events2.default();
|
|
2797
|
+
clientStartingPromise = null;
|
|
2798
|
+
static create(optionsOrConfig, features, config) {
|
|
2799
|
+
if ("options" in optionsOrConfig) {
|
|
2800
|
+
const { options, features: features2, config: config2 } = optionsOrConfig;
|
|
2801
|
+
return new _Vimcord(options, features2, config2);
|
|
2802
|
+
} else {
|
|
2803
|
+
return new _Vimcord(optionsOrConfig, features, config);
|
|
2804
|
+
}
|
|
2805
|
+
}
|
|
2806
|
+
/**
|
|
2807
|
+
* Returns an instance of Vimcord.
|
|
2808
|
+
* @param clientId [default: 0]
|
|
2809
|
+
*/
|
|
2810
|
+
static getInstance(clientId) {
|
|
2811
|
+
if (clientId === void 0) {
|
|
2812
|
+
return _Vimcord.instances.values().next().value;
|
|
2813
|
+
}
|
|
2814
|
+
return _Vimcord.instances.get(clientId);
|
|
2815
|
+
}
|
|
2816
|
+
/**
|
|
2817
|
+
* Waits for a Vimcord instance to be ready.
|
|
2818
|
+
* @param clientId [default: 0]
|
|
2819
|
+
* @param timeoutMs [default: 60000]
|
|
2820
|
+
*/
|
|
2821
|
+
static async getReadyInstance(clientId, timeoutMs = 6e4) {
|
|
2822
|
+
const client = _Vimcord.getInstance(clientId);
|
|
2823
|
+
if (client?.isReady()) {
|
|
2824
|
+
_Vimcord.emitter.emit("ready", client);
|
|
2825
|
+
return client;
|
|
2826
|
+
}
|
|
2827
|
+
if (client) {
|
|
2828
|
+
return new Promise((resolve, reject) => {
|
|
2829
|
+
const timeout = setTimeout(() => {
|
|
2830
|
+
_Vimcord.emitter.off("ready", listener);
|
|
2831
|
+
reject(new Error(`Client (i${clientId ?? 0}) timed out waiting for ready`));
|
|
2832
|
+
}, timeoutMs);
|
|
2833
|
+
const listener = (c) => {
|
|
2834
|
+
if (c.clientId === (clientId ?? 0)) {
|
|
2835
|
+
clearTimeout(timeout);
|
|
2836
|
+
_Vimcord.emitter.off("ready", listener);
|
|
2837
|
+
resolve(c);
|
|
2838
|
+
}
|
|
2839
|
+
};
|
|
2840
|
+
client.once("clientReady", () => {
|
|
2841
|
+
clearTimeout(timeout);
|
|
2842
|
+
_Vimcord.emitter.emit("ready", client);
|
|
2843
|
+
resolve(client);
|
|
2844
|
+
});
|
|
2845
|
+
});
|
|
2846
|
+
}
|
|
2847
|
+
return new Promise((resolve, reject) => {
|
|
2848
|
+
const timeout = setTimeout(() => {
|
|
2849
|
+
_Vimcord.emitter.off("ready", listener);
|
|
2850
|
+
reject(new Error(`Vimcord instance (i${clientId ?? 0}) failed to initialize within ${timeoutMs / 1e3}s.`));
|
|
2851
|
+
}, timeoutMs);
|
|
2852
|
+
const listener = (c) => {
|
|
2853
|
+
if (c.clientId === (clientId ?? 0)) {
|
|
2854
|
+
clearTimeout(timeout);
|
|
2855
|
+
_Vimcord.emitter.off("ready", listener);
|
|
2856
|
+
resolve(c);
|
|
2857
|
+
}
|
|
2858
|
+
};
|
|
2859
|
+
_Vimcord.emitter.on("ready", listener);
|
|
2860
|
+
});
|
|
2861
|
+
}
|
|
2587
2862
|
uuid = (0, import_node_crypto3.randomUUID)();
|
|
2588
2863
|
clientId = _Vimcord.instances.size;
|
|
2589
2864
|
clientOptions;
|
|
@@ -2593,229 +2868,181 @@ var Vimcord = class _Vimcord extends import_discord11.Client {
|
|
|
2593
2868
|
events;
|
|
2594
2869
|
commands;
|
|
2595
2870
|
db;
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
clientBanner(client) {
|
|
2599
|
-
if (client.config.app.disableBanner) return;
|
|
2600
|
-
const border = "\u2550".repeat(50);
|
|
2601
|
-
console.log(import_chalk2.default.hex(this.colors.primary)(`
|
|
2602
|
-
\u2554${border}\u2557`));
|
|
2603
|
-
console.log(
|
|
2604
|
-
import_chalk2.default.hex(this.colors.primary)("\u2551") + import_chalk2.default.bold.hex(this.colors.text)(
|
|
2605
|
-
` \u{1F680} ${client.config.app.name} v${client.config.app.appVersion}`.padEnd(
|
|
2606
|
-
50 - (client.config.app.devMode ? 12 : 0)
|
|
2607
|
-
)
|
|
2608
|
-
) + import_chalk2.default.hex(this.colors.primary)(
|
|
2609
|
-
`${client.config.app.devMode ? import_chalk2.default.hex(this.colors.warn)("devMode \u26A0\uFE0F ") : ""}\u2551`
|
|
2610
|
-
)
|
|
2611
|
-
);
|
|
2612
|
-
console.log(import_chalk2.default.hex(this.colors.primary)(`\u2551${"".padEnd(50)}\u2551`));
|
|
2613
|
-
console.log(
|
|
2614
|
-
import_chalk2.default.hex(this.colors.primary)("\u2551") + import_chalk2.default.hex(this.colors.muted)(
|
|
2615
|
-
` # Powered by Vimcord v${version}`.padEnd(50 - 3 - `${client.clientId}`.length)
|
|
2616
|
-
) + import_chalk2.default.hex(this.colors.primary)(`${import_chalk2.default.hex(this.colors.muted)(`i${client.clientId}`)} \u2551`)
|
|
2617
|
-
);
|
|
2618
|
-
console.log(import_chalk2.default.hex(this.colors.primary)(`\u255A${border}\u255D
|
|
2619
|
-
`));
|
|
2620
|
-
},
|
|
2621
|
-
clientReady(clientTag, guildCount) {
|
|
2622
|
-
console.log(
|
|
2623
|
-
this.formatTimestamp(),
|
|
2624
|
-
this.formatPrefix(),
|
|
2625
|
-
import_chalk2.default.hex(this.colors.success)("\u{1F916} READY"),
|
|
2626
|
-
import_chalk2.default.white(`Connected as ${import_chalk2.default.bold.hex(this.colors.primary)(clientTag)}`),
|
|
2627
|
-
import_chalk2.default.hex(this.colors.muted)(`\u2022 ${guildCount} guilds`)
|
|
2628
|
-
);
|
|
2629
|
-
},
|
|
2630
|
-
moduleLoaded(moduleName, count, ignoredCount) {
|
|
2631
|
-
const countText = count ? import_chalk2.default.hex(this.colors.muted)(`(${count} items)`) : "";
|
|
2632
|
-
console.log(
|
|
2633
|
-
this.formatTimestamp(),
|
|
2634
|
-
this.formatPrefix(),
|
|
2635
|
-
import_chalk2.default.hex("#9B59B6")("\u{1F4E6} MODULE"),
|
|
2636
|
-
import_chalk2.default.hex(this.colors.warn)(`${moduleName} loaded`),
|
|
2637
|
-
ignoredCount ? import_chalk2.default.hex(this.colors.muted)(`(${ignoredCount} ignored)`) : "",
|
|
2638
|
-
countText
|
|
2639
|
-
);
|
|
2640
|
-
},
|
|
2641
|
-
commandExecuted(commandName, username, guildName) {
|
|
2642
|
-
const location = guildName ? `in ${import_chalk2.default.hex(this.colors.muted)(guildName)}` : "in DMs";
|
|
2643
|
-
console.log(
|
|
2644
|
-
this.formatTimestamp(),
|
|
2645
|
-
this.formatPrefix(),
|
|
2646
|
-
import_chalk2.default.hex("#87CEEB")("\u{1F4DD} COMMAND"),
|
|
2647
|
-
import_chalk2.default.hex(this.colors.warn)(`/${commandName}`),
|
|
2648
|
-
import_chalk2.default.white(`used by ${import_chalk2.default.bold(username)}`),
|
|
2649
|
-
import_chalk2.default.hex(this.colors.muted)(location)
|
|
2650
|
-
);
|
|
2651
|
-
},
|
|
2652
|
-
database(action, details) {
|
|
2653
|
-
console.log(
|
|
2654
|
-
this.formatTimestamp(),
|
|
2655
|
-
this.formatPrefix(),
|
|
2656
|
-
import_chalk2.default.hex("#FF6B9D")("\u{1F5C4}\uFE0F DATABASE"),
|
|
2657
|
-
import_chalk2.default.white(action),
|
|
2658
|
-
details ? import_chalk2.default.hex(this.colors.muted)(details) : ""
|
|
2659
|
-
);
|
|
2660
|
-
}
|
|
2661
|
-
});
|
|
2662
|
-
clientStartingPromise = null;
|
|
2871
|
+
logger = clientLoggerFactory(this);
|
|
2872
|
+
error;
|
|
2663
2873
|
constructor(options, features = {}, config = {}) {
|
|
2664
2874
|
super(options);
|
|
2665
2875
|
this.clientOptions = options;
|
|
2666
2876
|
this.features = features;
|
|
2667
|
-
this.config =
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
|
|
2672
|
-
contextCommands: createVimcordContextCommandConfig(config.contextCommands)
|
|
2673
|
-
};
|
|
2877
|
+
this.config = defineVimcordConfig(config);
|
|
2878
|
+
this.error = new ErrorHandler(this);
|
|
2879
|
+
if (this.features.useGlobalErrorHandlers) {
|
|
2880
|
+
this.error.setupGlobalHandlers();
|
|
2881
|
+
}
|
|
2674
2882
|
this.status = new StatusManager(this);
|
|
2675
2883
|
this.events = new EventManager(this);
|
|
2676
2884
|
this.commands = new CommandManager(this);
|
|
2677
|
-
if (this.features.useEnv) {
|
|
2678
|
-
if (typeof this.features.useEnv === "object") {
|
|
2679
|
-
import_dotenv.default.config({ quiet: true, ...this.features.useEnv });
|
|
2680
|
-
} else {
|
|
2681
|
-
import_dotenv.default.config({ quiet: true });
|
|
2682
|
-
}
|
|
2683
|
-
}
|
|
2684
|
-
if (this.features.useGlobalErrorHandlers) {
|
|
2685
|
-
process.on("uncaughtException", (err) => this.logger.error("Uncaught Exception", err));
|
|
2686
|
-
process.on("unhandledRejection", (err) => this.logger.error("Unhandled Rejection", err));
|
|
2687
|
-
process.on("exit", (code) => this.logger.debug(`Process exited with code ${code}`));
|
|
2688
|
-
this.on("error", (err) => this.logger.error("Client Error", err));
|
|
2689
|
-
this.on("shardError", (err) => this.logger.error("Client Shard Error", err));
|
|
2690
|
-
}
|
|
2691
2885
|
this.logger.clientBanner(this);
|
|
2692
|
-
this.once("clientReady", (client) =>
|
|
2693
|
-
this.logger.clientReady(client.user.tag, client.guilds.cache.size);
|
|
2694
|
-
});
|
|
2886
|
+
this.once("clientReady", (client) => this.logger.clientReady(client.user.tag, client.guilds.cache.size));
|
|
2695
2887
|
_Vimcord.instances.set(this.clientId, this);
|
|
2696
|
-
|
|
2888
|
+
if (this.config.app.enableCLI) {
|
|
2889
|
+
VimcordCLI.setMode("on");
|
|
2890
|
+
}
|
|
2697
2891
|
}
|
|
2698
|
-
/**
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
features: this.features,
|
|
2703
|
-
config: this.config
|
|
2704
|
-
};
|
|
2892
|
+
/** Current app name */
|
|
2893
|
+
// prettier-ignore
|
|
2894
|
+
get $name() {
|
|
2895
|
+
return this.config.app.name;
|
|
2705
2896
|
}
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
return new _Vimcord(options, features, config);
|
|
2897
|
+
// prettier-ignore
|
|
2898
|
+
set $name(name) {
|
|
2899
|
+
this.config.app.name = name;
|
|
2710
2900
|
}
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
}
|
|
2716
|
-
return this;
|
|
2901
|
+
/** Current app version */
|
|
2902
|
+
// prettier-ignore
|
|
2903
|
+
get $version() {
|
|
2904
|
+
return this.config.app.version;
|
|
2717
2905
|
}
|
|
2718
|
-
|
|
2719
|
-
|
|
2720
|
-
|
|
2906
|
+
// prettier-ignore
|
|
2907
|
+
set $version(version2) {
|
|
2908
|
+
this.config.app.version = version2;
|
|
2721
2909
|
}
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
|
|
2910
|
+
/** Current dev mode state */
|
|
2911
|
+
// prettier-ignore
|
|
2912
|
+
get $devMode() {
|
|
2913
|
+
return this.config.app.devMode;
|
|
2725
2914
|
}
|
|
2726
|
-
|
|
2727
|
-
|
|
2728
|
-
|
|
2915
|
+
// prettier-ignore
|
|
2916
|
+
set $devMode(mode) {
|
|
2917
|
+
this.config.app.devMode = mode;
|
|
2729
2918
|
}
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
|
|
2919
|
+
/** Current verbose mode state */
|
|
2920
|
+
// prettier-ignore
|
|
2921
|
+
get $verboseMode() {
|
|
2922
|
+
return this.config.app.verbose;
|
|
2733
2923
|
}
|
|
2734
|
-
|
|
2735
|
-
|
|
2736
|
-
|
|
2924
|
+
// prettier-ignore
|
|
2925
|
+
set $verboseMode(mode) {
|
|
2926
|
+
this.config.app.verbose = mode;
|
|
2737
2927
|
}
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
return this;
|
|
2928
|
+
/** Returns the options, features, and config of this client. */
|
|
2929
|
+
toJSON() {
|
|
2930
|
+
return { options: this.clientOptions, features: this.features, config: this.config };
|
|
2741
2931
|
}
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
|
|
2932
|
+
/** Makes a clone of this client. */
|
|
2933
|
+
clone() {
|
|
2934
|
+
const { options, features, config } = this.toJSON();
|
|
2935
|
+
return new _Vimcord(options, features, config);
|
|
2745
2936
|
}
|
|
2746
|
-
|
|
2747
|
-
|
|
2937
|
+
/**
|
|
2938
|
+
* Modifies a client config.
|
|
2939
|
+
* @param type The type of config to modify.
|
|
2940
|
+
* @param options The options to set for the config.
|
|
2941
|
+
*/
|
|
2942
|
+
configure(type, options = {}) {
|
|
2943
|
+
this.config[type] = configSetters[type](options, this.config[type]);
|
|
2748
2944
|
return this;
|
|
2749
2945
|
}
|
|
2750
|
-
|
|
2751
|
-
this.db = db;
|
|
2752
|
-
this.logger.database("Using", db.moduleName);
|
|
2753
|
-
return this.db.connect();
|
|
2754
|
-
}
|
|
2755
|
-
async waitForReady() {
|
|
2756
|
-
if (this.isReady()) return this;
|
|
2757
|
-
return new Promise((resolve, reject) => {
|
|
2758
|
-
const timeout = setTimeout(
|
|
2759
|
-
() => reject(new Error(`Client (i${this.clientId}) timed out waiting for ready`)),
|
|
2760
|
-
6e4
|
|
2761
|
-
);
|
|
2762
|
-
this.once("clientReady", () => {
|
|
2763
|
-
clearTimeout(timeout);
|
|
2764
|
-
resolve(this);
|
|
2765
|
-
});
|
|
2766
|
-
});
|
|
2767
|
-
}
|
|
2946
|
+
/** Builds the client by importing modules and registering builtin handlers. */
|
|
2768
2947
|
async build() {
|
|
2769
|
-
this.
|
|
2770
|
-
this.
|
|
2771
|
-
this.
|
|
2772
|
-
this.
|
|
2773
|
-
this.
|
|
2948
|
+
this.configure("app", this.config.app);
|
|
2949
|
+
this.configure("staff", this.config.staff);
|
|
2950
|
+
this.configure("slashCommands", this.config.slashCommands);
|
|
2951
|
+
this.configure("prefixCommands", this.config.prefixCommands);
|
|
2952
|
+
this.configure("contextCommands", this.config.contextCommands);
|
|
2774
2953
|
if (this.features.importModules) {
|
|
2775
2954
|
const importModules = this.features.importModules;
|
|
2776
2955
|
await Promise.all([
|
|
2777
|
-
importModules.events && this.
|
|
2778
|
-
importModules.slashCommands && this.
|
|
2779
|
-
importModules.prefixCommands && this.
|
|
2780
|
-
importModules.contextCommands && this.
|
|
2956
|
+
importModules.events && this.importModules("events", importModules.events),
|
|
2957
|
+
importModules.slashCommands && this.importModules("slashCommands", importModules.slashCommands),
|
|
2958
|
+
importModules.prefixCommands && this.importModules("prefixCommands", importModules.prefixCommands),
|
|
2959
|
+
importModules.contextCommands && this.importModules("contextCommands", importModules.contextCommands)
|
|
2781
2960
|
]);
|
|
2782
2961
|
}
|
|
2783
2962
|
if (this.features.useDefaultSlashCommandHandler) {
|
|
2784
|
-
this.events.register(
|
|
2963
|
+
this.events.register(slashCommandHandler);
|
|
2785
2964
|
}
|
|
2786
2965
|
if (this.features.useDefaultContextCommandHandler) {
|
|
2787
|
-
this.events.register(
|
|
2966
|
+
this.events.register(contextCommandHandler);
|
|
2788
2967
|
}
|
|
2789
2968
|
if (this.features.useDefaultPrefixCommandHandler) {
|
|
2790
|
-
this.events.register(
|
|
2969
|
+
this.events.register(prefixCommandHandler);
|
|
2791
2970
|
}
|
|
2792
2971
|
return this;
|
|
2793
2972
|
}
|
|
2794
|
-
|
|
2973
|
+
/**
|
|
2974
|
+
* Imports modules into the client.
|
|
2975
|
+
* @param type The type of modules to import.
|
|
2976
|
+
* @param options The options to import the module with.
|
|
2977
|
+
* @param set Replaces already imported modules with the ones found.
|
|
2978
|
+
*/
|
|
2979
|
+
async importModules(type, options, set) {
|
|
2980
|
+
await moduleImporters[type](this, options, set);
|
|
2981
|
+
return this;
|
|
2982
|
+
}
|
|
2983
|
+
/**
|
|
2984
|
+
* Allows Vimcord to handle environment variables using [dotenv](https://www.npmjs.com/package/dotenv).
|
|
2985
|
+
* @param options Options for dotenv
|
|
2986
|
+
* @see https://www.npmjs.com/package/dotenv
|
|
2987
|
+
*/
|
|
2988
|
+
useEnv(options) {
|
|
2989
|
+
this.logger.database("Using", "dotenv");
|
|
2990
|
+
(0, import_dotenv.configDotenv)({ quiet: true, ...options });
|
|
2991
|
+
return this;
|
|
2992
|
+
}
|
|
2993
|
+
/**
|
|
2994
|
+
* Connects to a database.
|
|
2995
|
+
* @param db The database manager to use.
|
|
2996
|
+
*/
|
|
2997
|
+
async useDatabase(db) {
|
|
2998
|
+
this.db = db;
|
|
2999
|
+
this.logger.database("Using", db.moduleName);
|
|
3000
|
+
return this.db.connect();
|
|
3001
|
+
}
|
|
3002
|
+
/**
|
|
3003
|
+
* Fetches a user from the client, checking the cache first.
|
|
3004
|
+
* @param userId The ID of the user to fetch.
|
|
3005
|
+
*/
|
|
3006
|
+
async fetchUser(userId) {
|
|
3007
|
+
const client = await _Vimcord.getReadyInstance(this.clientId);
|
|
3008
|
+
return fetchUser(client, userId);
|
|
3009
|
+
}
|
|
3010
|
+
/**
|
|
3011
|
+
* Fetches a guild from the client, checking the cache first.
|
|
3012
|
+
* @param guildId The ID of the guild to fetch.
|
|
3013
|
+
*/
|
|
3014
|
+
async fetchGuild(guildId) {
|
|
3015
|
+
const client = await _Vimcord.getReadyInstance(this.clientId);
|
|
3016
|
+
return fetchGuild(client, guildId);
|
|
3017
|
+
}
|
|
3018
|
+
async start(tokenOrPreHook, callback) {
|
|
2795
3019
|
if (this.clientStartingPromise) return this.clientStartingPromise;
|
|
2796
|
-
const
|
|
3020
|
+
const execute = async () => {
|
|
2797
3021
|
let token = typeof tokenOrPreHook === "string" ? tokenOrPreHook : void 0;
|
|
2798
|
-
token ??= this
|
|
3022
|
+
token ??= this.$devMode ? process.env.TOKEN_DEV : process.env.TOKEN;
|
|
2799
3023
|
if (!token) {
|
|
2800
3024
|
throw new Error(
|
|
2801
|
-
`TOKEN Missing: ${this
|
|
3025
|
+
`TOKEN Missing: ${this.$devMode ? "devMode is enabled, but TOKEN_DEV is not set" : "TOKEN not set"}`
|
|
2802
3026
|
);
|
|
2803
3027
|
}
|
|
2804
3028
|
await this.build();
|
|
2805
3029
|
try {
|
|
3030
|
+
const stopLoader = this.logger.loader("Connecting to Discord...");
|
|
3031
|
+
const loginResult = await import_qznt4.$.async.retry(() => super.login(token), {
|
|
3032
|
+
retries: this.features.maxLoginAttempts ?? 3,
|
|
3033
|
+
delay: 1e3
|
|
3034
|
+
});
|
|
3035
|
+
stopLoader("Connected to Discord ");
|
|
3036
|
+
this.$verboseMode && this.logger.debug("Waiting for ready...");
|
|
2806
3037
|
if (typeof tokenOrPreHook === "function") {
|
|
2807
3038
|
await tokenOrPreHook(this);
|
|
2808
3039
|
} else {
|
|
2809
|
-
await
|
|
3040
|
+
await callback?.(this);
|
|
2810
3041
|
}
|
|
2811
|
-
const stopLoader = this.logger.loader("Connecting to Discord...");
|
|
2812
|
-
const loginResult = await import_qznt4.$.async.retry(() => super.login(token), this.features.loginAttempts ?? 3, 1e3);
|
|
2813
|
-
stopLoader("Connected to Discord ");
|
|
2814
|
-
this.config.app.verbose && this.logger.debug("\u23F3 Waiting for ready...");
|
|
2815
3042
|
return loginResult;
|
|
2816
3043
|
} catch (err) {
|
|
2817
3044
|
this.logger.error(
|
|
2818
|
-
`Failed to log into Discord after ${this.features.
|
|
3045
|
+
`Failed to log into Discord after ${this.features.maxLoginAttempts} attempt(s)`,
|
|
2819
3046
|
err
|
|
2820
3047
|
);
|
|
2821
3048
|
return null;
|
|
@@ -2823,29 +3050,25 @@ var Vimcord = class _Vimcord extends import_discord11.Client {
|
|
|
2823
3050
|
this.clientStartingPromise = null;
|
|
2824
3051
|
}
|
|
2825
3052
|
};
|
|
2826
|
-
this.clientStartingPromise =
|
|
3053
|
+
this.clientStartingPromise = execute();
|
|
2827
3054
|
return this.clientStartingPromise;
|
|
2828
3055
|
}
|
|
3056
|
+
/** Destroys the client and disconnects from Discord. */
|
|
2829
3057
|
async kill() {
|
|
2830
3058
|
await super.destroy();
|
|
2831
3059
|
_Vimcord.instances.delete(this.clientId);
|
|
2832
|
-
this.logger.debug("
|
|
2833
|
-
}
|
|
2834
|
-
/** Shortcut for {@link fetchUser tools.fetchUser} */
|
|
2835
|
-
async fetchUser(id) {
|
|
2836
|
-
const client = await this.waitForReady();
|
|
2837
|
-
return fetchUser(client, id);
|
|
2838
|
-
}
|
|
2839
|
-
/** Shortcut for {@link fetchGuild tools.fetchGuild} */
|
|
2840
|
-
async fetchGuild(id) {
|
|
2841
|
-
const client = await this.waitForReady();
|
|
2842
|
-
return fetchGuild(client, id);
|
|
3060
|
+
this.logger.debug("Logged out of Discord");
|
|
2843
3061
|
}
|
|
2844
3062
|
};
|
|
2845
3063
|
|
|
2846
|
-
// src/
|
|
3064
|
+
// src/db/mongo/mongo-schema.builder.ts
|
|
3065
|
+
var import_mongoose2 = require("mongoose");
|
|
3066
|
+
var import_node_crypto4 = require("crypto");
|
|
3067
|
+
var import_qznt6 = require("qznt");
|
|
3068
|
+
|
|
3069
|
+
// src/db/mongo/mongo.database.ts
|
|
2847
3070
|
var import_mongoose = __toESM(require("mongoose"));
|
|
2848
|
-
var
|
|
3071
|
+
var import_node_events3 = __toESM(require("events"));
|
|
2849
3072
|
var import_qznt5 = require("qznt");
|
|
2850
3073
|
try {
|
|
2851
3074
|
import("mongoose");
|
|
@@ -2854,7 +3077,7 @@ try {
|
|
|
2854
3077
|
}
|
|
2855
3078
|
var MongoDatabase = class _MongoDatabase {
|
|
2856
3079
|
static instances = /* @__PURE__ */ new Map();
|
|
2857
|
-
static emitter = new
|
|
3080
|
+
static emitter = new import_node_events3.default();
|
|
2858
3081
|
moduleName = "MongoDatabase";
|
|
2859
3082
|
clientId;
|
|
2860
3083
|
client;
|
|
@@ -2939,10 +3162,9 @@ var MongoDatabase = class _MongoDatabase {
|
|
|
2939
3162
|
this.isConnecting = true;
|
|
2940
3163
|
try {
|
|
2941
3164
|
const stopLoader = this.client.logger.loader("Connecting to MongoDB...");
|
|
2942
|
-
await import_qznt5.$.async.retry(
|
|
2943
|
-
|
|
2944
|
-
|
|
2945
|
-
);
|
|
3165
|
+
await import_qznt5.$.async.retry(() => this.mongoose.connect(connectionUri, { autoIndex: true, ...connectionOptions }), {
|
|
3166
|
+
retries: maxRetries
|
|
3167
|
+
});
|
|
2946
3168
|
_MongoDatabase.emitter.emit("ready", this);
|
|
2947
3169
|
stopLoader("Connected to MongoDB ");
|
|
2948
3170
|
} catch (err) {
|
|
@@ -2973,10 +3195,7 @@ var MongoDatabase = class _MongoDatabase {
|
|
|
2973
3195
|
}
|
|
2974
3196
|
};
|
|
2975
3197
|
|
|
2976
|
-
// src/
|
|
2977
|
-
var import_mongoose2 = require("mongoose");
|
|
2978
|
-
var import_node_crypto4 = require("crypto");
|
|
2979
|
-
var import_qznt6 = require("qznt");
|
|
3198
|
+
// src/db/mongo/mongo-schema.builder.ts
|
|
2980
3199
|
try {
|
|
2981
3200
|
import("mongoose");
|
|
2982
3201
|
} catch {
|
|
@@ -3062,10 +3281,13 @@ var MongoSchemaBuilder = class _MongoSchemaBuilder {
|
|
|
3062
3281
|
* @param maxRetries [default: 3]
|
|
3063
3282
|
*/
|
|
3064
3283
|
async execute(fn, maxRetries = 3) {
|
|
3065
|
-
return await import_qznt6.$.async.retry(
|
|
3066
|
-
|
|
3067
|
-
|
|
3068
|
-
|
|
3284
|
+
return await import_qznt6.$.async.retry(
|
|
3285
|
+
async () => {
|
|
3286
|
+
const model = await this.getModel();
|
|
3287
|
+
return await fn(model);
|
|
3288
|
+
},
|
|
3289
|
+
{ retries: maxRetries }
|
|
3290
|
+
);
|
|
3069
3291
|
}
|
|
3070
3292
|
async startSession(options) {
|
|
3071
3293
|
return await this.execute(async () => {
|
|
@@ -3139,6 +3361,12 @@ var MongoSchemaBuilder = class _MongoSchemaBuilder {
|
|
|
3139
3361
|
return result?.length ? result : [];
|
|
3140
3362
|
});
|
|
3141
3363
|
}
|
|
3364
|
+
async bulkWrite(ops, options) {
|
|
3365
|
+
return await this.execute(async (model) => model.bulkWrite(ops, options));
|
|
3366
|
+
}
|
|
3367
|
+
async bulkSave(docs, options) {
|
|
3368
|
+
return await this.execute(async (model) => model.bulkSave(docs, options));
|
|
3369
|
+
}
|
|
3142
3370
|
};
|
|
3143
3371
|
|
|
3144
3372
|
// src/tools/BetterCollector.ts
|
|
@@ -3310,8 +3538,8 @@ var BetterCollector = class _BetterCollector {
|
|
|
3310
3538
|
handleListenerError(err) {
|
|
3311
3539
|
console.error("[BetterCollector] Listener Error:", err);
|
|
3312
3540
|
}
|
|
3313
|
-
constructor(message, options) {
|
|
3314
|
-
this.config = options
|
|
3541
|
+
constructor(message, options = {}) {
|
|
3542
|
+
this.config = options.config ? createToolsConfig(options.config) : globalToolsConfig;
|
|
3315
3543
|
this.message = message || void 0;
|
|
3316
3544
|
this.options = options;
|
|
3317
3545
|
this.build();
|
|
@@ -3357,7 +3585,7 @@ var BetterContainer = class {
|
|
|
3357
3585
|
data;
|
|
3358
3586
|
config;
|
|
3359
3587
|
constructor(data = {}) {
|
|
3360
|
-
this.config = data.config
|
|
3588
|
+
this.config = data.config ? createToolsConfig(data.config) : globalToolsConfig;
|
|
3361
3589
|
this.data = {
|
|
3362
3590
|
color: data.color ?? (this.config.devMode ? this.config.embedColorDev : this.config.embedColor),
|
|
3363
3591
|
...data
|
|
@@ -3365,7 +3593,7 @@ var BetterContainer = class {
|
|
|
3365
3593
|
this.build();
|
|
3366
3594
|
}
|
|
3367
3595
|
configure() {
|
|
3368
|
-
if (this.data.color) {
|
|
3596
|
+
if (this.data.color !== void 0) {
|
|
3369
3597
|
try {
|
|
3370
3598
|
const color = Array.isArray(this.data.color) ? this.data.color[Math.floor(Math.random() * this.data.color.length)] ?? null : this.data.color;
|
|
3371
3599
|
if (color) {
|
|
@@ -3381,6 +3609,14 @@ var BetterContainer = class {
|
|
|
3381
3609
|
build() {
|
|
3382
3610
|
this.configure();
|
|
3383
3611
|
}
|
|
3612
|
+
setColor(color) {
|
|
3613
|
+
this.data.color = color;
|
|
3614
|
+
return this;
|
|
3615
|
+
}
|
|
3616
|
+
clearColor() {
|
|
3617
|
+
this.data.color = null;
|
|
3618
|
+
return this;
|
|
3619
|
+
}
|
|
3384
3620
|
addSeparator(options) {
|
|
3385
3621
|
this.container.addSeparatorComponents((sb) => {
|
|
3386
3622
|
if (options?.divider !== void 0) sb.setDivider(options.divider);
|
|
@@ -3458,7 +3694,7 @@ var BetterModal = class {
|
|
|
3458
3694
|
this.id = options.id || this.createModalId();
|
|
3459
3695
|
this.options = options;
|
|
3460
3696
|
this.modal = new import_discord13.ModalBuilder().setCustomId(this.id);
|
|
3461
|
-
this.config = options.config ||
|
|
3697
|
+
this.config = options.config || globalToolsConfig;
|
|
3462
3698
|
if (options.title) {
|
|
3463
3699
|
this.setTitle(options.title);
|
|
3464
3700
|
}
|
|
@@ -3638,7 +3874,8 @@ var BetterModal = class {
|
|
|
3638
3874
|
values,
|
|
3639
3875
|
interaction: modalSubmit,
|
|
3640
3876
|
reply: (options2) => dynaSend(modalSubmit, options2),
|
|
3641
|
-
deferUpdate: async (options2) => await modalSubmit.deferUpdate(options2)
|
|
3877
|
+
deferUpdate: async (options2) => await modalSubmit.deferUpdate(options2),
|
|
3878
|
+
followUp: async (options2) => await modalSubmit.followUp(options2)
|
|
3642
3879
|
};
|
|
3643
3880
|
} catch (error) {
|
|
3644
3881
|
return null;
|
|
@@ -3656,7 +3893,7 @@ var BetterModal = class {
|
|
|
3656
3893
|
|
|
3657
3894
|
// src/tools/Paginator.ts
|
|
3658
3895
|
var import_discord14 = require("discord.js");
|
|
3659
|
-
var
|
|
3896
|
+
var import_node_events4 = __toESM(require("events"));
|
|
3660
3897
|
var PaginationType = /* @__PURE__ */ ((PaginationType2) => {
|
|
3661
3898
|
PaginationType2[PaginationType2["Short"] = 0] = "Short";
|
|
3662
3899
|
PaginationType2[PaginationType2["ShortJump"] = 1] = "ShortJump";
|
|
@@ -3701,9 +3938,9 @@ var Paginator = class {
|
|
|
3701
3938
|
config;
|
|
3702
3939
|
data;
|
|
3703
3940
|
events;
|
|
3704
|
-
eventEmitter = new
|
|
3941
|
+
eventEmitter = new import_node_events4.default();
|
|
3705
3942
|
constructor(options = {}) {
|
|
3706
|
-
this.config = options.config
|
|
3943
|
+
this.config = options.config ? createToolsConfig(options.config) : globalToolsConfig;
|
|
3707
3944
|
this.options = {
|
|
3708
3945
|
type: options.type ?? 0 /* Short */,
|
|
3709
3946
|
participants: options.participants ?? [],
|
|
@@ -4131,7 +4368,7 @@ var Prompt = class {
|
|
|
4131
4368
|
config;
|
|
4132
4369
|
message = null;
|
|
4133
4370
|
constructor(options = {}) {
|
|
4134
|
-
this.config = options.config
|
|
4371
|
+
this.config = options.config ? createToolsConfig(options.config) : globalToolsConfig;
|
|
4135
4372
|
this.participants = options.participants ?? [];
|
|
4136
4373
|
this.timeout = options.timeout ?? this.config.timeouts.prompt;
|
|
4137
4374
|
this.content = options.content;
|
|
@@ -4313,9 +4550,6 @@ async function prompt(handler, options, sendOptions) {
|
|
|
4313
4550
|
}
|
|
4314
4551
|
// Annotate the CommonJS export names for ESM import in node:
|
|
4315
4552
|
0 && (module.exports = {
|
|
4316
|
-
BUILTIN_ContextCommandHandler,
|
|
4317
|
-
BUILTIN_PrefixCommandHandler,
|
|
4318
|
-
BUILTIN_SlashCommandHandler,
|
|
4319
4553
|
BaseCommandBuilder,
|
|
4320
4554
|
BaseCommandManager,
|
|
4321
4555
|
BetterCollector,
|
|
@@ -4328,13 +4562,16 @@ async function prompt(handler, options, sendOptions) {
|
|
|
4328
4562
|
CommandType,
|
|
4329
4563
|
ContextCommandBuilder,
|
|
4330
4564
|
ContextCommandManager,
|
|
4565
|
+
DEFAULT_MODULE_SUFFIXES,
|
|
4331
4566
|
DynaSend,
|
|
4567
|
+
ErrorHandler,
|
|
4332
4568
|
EventBuilder,
|
|
4333
4569
|
EventManager,
|
|
4334
4570
|
LOGGER_COLORS,
|
|
4335
4571
|
LogLevel,
|
|
4336
4572
|
Logger,
|
|
4337
4573
|
MissingPermissionReason,
|
|
4574
|
+
ModuleImporter,
|
|
4338
4575
|
MongoDatabase,
|
|
4339
4576
|
MongoSchemaBuilder,
|
|
4340
4577
|
PaginationTimeoutType,
|
|
@@ -4354,17 +4591,24 @@ async function prompt(handler, options, sendOptions) {
|
|
|
4354
4591
|
VimcordCLI,
|
|
4355
4592
|
__zero,
|
|
4356
4593
|
cleanMention,
|
|
4594
|
+
clientLoggerFactory,
|
|
4595
|
+
configSetters,
|
|
4596
|
+
contextCommandHandler,
|
|
4597
|
+
createAppConfig,
|
|
4357
4598
|
createClient,
|
|
4599
|
+
createConfigFactory,
|
|
4600
|
+
createContextCommandConfig,
|
|
4358
4601
|
createMongoPlugin,
|
|
4359
4602
|
createMongoSchema,
|
|
4603
|
+
createPrefixCommandConfig,
|
|
4604
|
+
createSlashCommandConfig,
|
|
4605
|
+
createStaffConfig,
|
|
4360
4606
|
createToolsConfig,
|
|
4361
|
-
createVimcordAppConfig,
|
|
4362
|
-
createVimcordContextCommandConfig,
|
|
4363
|
-
createVimcordPrefixCommandConfig,
|
|
4364
|
-
createVimcordSlashCommandConfig,
|
|
4365
|
-
createVimcordStaffConfig,
|
|
4366
4607
|
createVimcordStatusConfig,
|
|
4608
|
+
defineClientOptions,
|
|
4367
4609
|
defineGlobalToolsConfig,
|
|
4610
|
+
defineVimcordConfig,
|
|
4611
|
+
defineVimcordFeatures,
|
|
4368
4612
|
dynaSend,
|
|
4369
4613
|
fetchChannel,
|
|
4370
4614
|
fetchGuild,
|
|
@@ -4372,17 +4616,20 @@ async function prompt(handler, options, sendOptions) {
|
|
|
4372
4616
|
fetchMessage,
|
|
4373
4617
|
fetchRole,
|
|
4374
4618
|
fetchUser,
|
|
4375
|
-
|
|
4619
|
+
getDevMode,
|
|
4376
4620
|
getFirstMentionId,
|
|
4377
4621
|
getMessageMention,
|
|
4622
|
+
getPackageJson,
|
|
4378
4623
|
getProcessDir,
|
|
4379
|
-
|
|
4624
|
+
globalToolsConfig,
|
|
4380
4625
|
importModulesFromDir,
|
|
4381
|
-
initCLI,
|
|
4382
4626
|
isMentionOrSnowflake,
|
|
4383
4627
|
logger,
|
|
4628
|
+
moduleImporters,
|
|
4629
|
+
prefixCommandHandler,
|
|
4384
4630
|
prompt,
|
|
4385
4631
|
sendCommandErrorEmbed,
|
|
4632
|
+
slashCommandHandler,
|
|
4386
4633
|
useClient,
|
|
4387
4634
|
useReadyClient,
|
|
4388
4635
|
validateCommandPermissions
|