UNPKG

discord-module-loader

Version:

A package that lets you load events and commands easily and fast.

317 lines 17.8 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const debug_1 = __importDefault(require("debug")); const discord_js_1 = require("discord.js"); const node_fs_1 = require("node:fs"); const promises_1 = require("node:fs/promises"); const node_path_1 = require("node:path"); const DiscordCommand_1 = __importDefault(require("./DiscordCommand")); const DiscordEvent_1 = __importDefault(require("./DiscordEvent")); const DiscordGuild_1 = __importDefault(require("./DiscordGuild")); const DiscordModule_1 = __importDefault(require("./DiscordModule")); class DiscordModuleLoader { constructor(client, options) { this.client = client; this.unknownCommandMessage = "Couldn't find executed command. Please try again later, or report the issue."; this.disabledCommandMessage = "This command is currently disabled. Please try again later."; this.disallowedChannelMessage = "You're not allowed to execute this command in this channel!"; this.commandCooldownMessage = "Please wait % seconds before using this command again."; this.commands = new discord_js_1.Collection(); this.modules = new discord_js_1.Collection(); this.guilds = new discord_js_1.Collection(); this.cooldowns = new discord_js_1.Collection(); this.log = (0, debug_1.default)("Discord-Module-Loader"); if (options === null || options === void 0 ? void 0 : options.unknownCommandMessage) this.unknownCommandMessage = options.unknownCommandMessage; if (options === null || options === void 0 ? void 0 : options.disabledCommandMessage) this.disabledCommandMessage = options.disabledCommandMessage; if (options === null || options === void 0 ? void 0 : options.disallowedChannelMessage) this.disallowedChannelMessage = options.disallowedChannelMessage; if (options === null || options === void 0 ? void 0 : options.commandCooldownMessage) this.commandCooldownMessage = options.commandCooldownMessage; client.setMaxListeners(Infinity); client.on("interactionCreate", int => void this.handleInteraction(int)); } loadAll() { return __awaiter(this, void 0, void 0, function* () { yield this.loadCommands(); yield this.loadEvents(); yield this.loadModules(); yield this.loadGuilds(); }); } loadGuilds(dir = "guilds") { return __awaiter(this, void 0, void 0, function* () { dir = (0, node_path_1.resolve)(dir); if (!(0, node_fs_1.existsSync)(dir)) return []; const guilds = yield (0, promises_1.readdir)(dir), log = this.log.extend((0, node_path_1.basename)(dir)); log("Loading %d guilds modules", guilds.length); const returnGuilds = []; for (const folder of guilds) { if (!(yield (0, promises_1.lstat)((0, node_path_1.resolve)(dir, folder))).isDirectory()) throw new Error(`${folder} is not a directory.`); if (!(0, node_fs_1.existsSync)((0, node_path_1.resolve)(dir, folder, "index.js"))) throw new Error(`Couldn't find index.js in ${folder}`); let guild = (yield Promise.resolve().then(() => __importStar(require((0, node_path_1.resolve)(dir, folder, "index.js"))))).default; if (typeof guild === "function") guild = yield guild(); if (!(guild instanceof DiscordGuild_1.default)) throw new Error(`Guild ${folder} is not an Guild.`); if (!this.client.guilds.cache.get(guild.id)) throw new Error(`Guild ${guild.id} is not cached.`); if (this.guilds.has(guild.id)) throw new Error(`Cannot add ${guild.id} more than once.`); this.guilds.set(guild.id, guild); returnGuilds.push([guild.id, guild]); if ((0, node_fs_1.existsSync)((0, node_path_1.resolve)(dir, folder, "events"))) this.addToColl(guild.events, yield this.loadEvents((0, node_path_1.resolve)(dir, folder, "events"), guild.id)); if ((0, node_fs_1.existsSync)((0, node_path_1.resolve)(dir, folder, "commands"))) this.addToColl(guild.commands, yield this.loadCommands((0, node_path_1.resolve)(dir, folder, "commands"), guild.id)); if ((0, node_fs_1.existsSync)((0, node_path_1.resolve)(dir, folder, "modules"))) this.addToColl(guild.modules, yield this.loadModules((0, node_path_1.resolve)(dir, folder, "modules"), guild.id)); if (guild.callback) yield guild.callback(); log("Loaded guild module for guild: %s", guild.id); } return returnGuilds; }); } loadModules(dir = "modules", guildId) { return __awaiter(this, void 0, void 0, function* () { dir = (0, node_path_1.resolve)(dir); if (!(0, node_fs_1.existsSync)(dir)) return []; const modules = yield (0, promises_1.readdir)(dir), log = this.log.extend((0, node_path_1.basename)(dir)); log("Loading %d modules", modules.length); const returnModules = []; for (const folder of modules) { if (!(yield (0, promises_1.lstat)((0, node_path_1.resolve)(dir, folder))).isDirectory()) throw new Error(`${folder} is not a directory.`); if (!(0, node_fs_1.existsSync)((0, node_path_1.resolve)(dir, folder, "index.js"))) throw new Error(`Couldn't find index.js in ${folder}`); let module = (yield Promise.resolve().then(() => __importStar(require((0, node_path_1.resolve)(dir, folder, "index.js"))))).default; if (typeof module === "function") module = yield module(); if (!(module instanceof DiscordModule_1.default)) throw new Error(`Module ${folder} is not an Module`); if (this.modules.has(module.name)) throw new Error(`Cannot add ${module.name} more than once.`); if ((0, node_fs_1.existsSync)((0, node_path_1.resolve)(dir, folder, "events"))) this.addToColl(module.events, yield this.loadEvents((0, node_path_1.resolve)(dir, folder, "events"), guildId)); if ((0, node_fs_1.existsSync)((0, node_path_1.resolve)(dir, folder, "commands"))) this.addToColl(module.commands, yield this.loadCommands((0, node_path_1.resolve)(dir, folder, "commands"), guildId)); if ((0, node_fs_1.existsSync)((0, node_path_1.resolve)(dir, folder, "modules"))) this.addToColl(module.modules, yield this.loadModules((0, node_path_1.resolve)(dir, folder, "modules"))); if (module.callback) yield module.callback(); this.modules.set(module.name, module); returnModules.push([module.name, module]); log("Loaded module %s", module.name); } return returnModules; }); } addToColl(coll, add) { for (const [key, value] of add) coll.set(key, value); } loadEvents(dir = "events", guildId) { return __awaiter(this, void 0, void 0, function* () { dir = (0, node_path_1.resolve)(dir); if (!(0, node_fs_1.existsSync)(dir)) return []; const events = (yield (0, promises_1.readdir)(dir)).filter(file => file.endsWith(".js")), log = this.log.extend((0, node_path_1.basename)(dir)); log("Loading %d events", events.length); const returnEvents = []; for (const file of events) { let event = (yield Promise.resolve().then(() => __importStar(require((0, node_path_1.resolve)(dir, file))))).default; if (typeof event === "function") event = yield event(); if (!(event instanceof DiscordEvent_1.default)) throw new Error(`Event ${file} is not an Event`); if (guildId) { this.guilds.get(guildId).events.set(event.event, event); event.guildId = guildId; } this.client.on(event.event, (...args) => { var _a, _b; if (!event.disabled && event.guildId && ((_b = (_a = args[0]) === null || _a === void 0 ? void 0 : _a.guild) === null || _b === void 0 ? void 0 : _b.id) === event.guildId) event.listener(...args); if (!event.disabled && !event.guildId) event.listener(...args); }); returnEvents.push([event.event, event]); log("Loaded event %s", event.event); } return returnEvents; }); } loadCommands(dir = "commands", guildId, subDirectoryOf) { return __awaiter(this, void 0, void 0, function* () { dir = (0, node_path_1.resolve)(dir); if (!(0, node_fs_1.existsSync)(dir)) return []; const directory = yield (0, promises_1.readdir)(dir, { withFileTypes: true }), commands = directory .filter(file => file.isFile() && file.name.endsWith(".js")) .map(f => f.name), subDirectories = directory .filter(file => file.isDirectory()) .map(f => f.name), log = subDirectoryOf ? this.log.extend(subDirectoryOf).extend((0, node_path_1.basename)(dir)) : this.log.extend((0, node_path_1.basename)(dir)); log("Loading %d commands", commands.length); const returnCommands = []; for (const file of commands) { let discordCommand = (yield Promise.resolve().then(() => __importStar(require((0, node_path_1.resolve)(dir, file))))).default; if (typeof discordCommand === "function") discordCommand = yield discordCommand(); if (!(discordCommand instanceof DiscordCommand_1.default)) throw new Error(`Command ${file} is not a Command`); if (this.commands.has(discordCommand.command.name.toLowerCase())) throw new Error(`Cannot add ${discordCommand.command.name} more than once.`); if (guildId) { this.guilds .get(guildId) .commands.set(discordCommand.command.name.toLowerCase(), discordCommand); discordCommand.guildId = guildId; } this.commands.set(discordCommand.command.name.toLowerCase(), discordCommand); returnCommands.push([ discordCommand.command.name.toLowerCase(), discordCommand ]); log("Loaded command %s", discordCommand.command.name); } if (!subDirectoryOf) { log("Loading %s sub-directories", subDirectories.length); for (const subDirectory of subDirectories) returnCommands.push(...(yield this.loadCommands((0, node_path_1.resolve)(dir, subDirectory), guildId, (0, node_path_1.basename)(dir)))); } return returnCommands; }); } updateSlashCommands() { var _a; return __awaiter(this, void 0, void 0, function* () { if (!this.client.isReady()) throw new Error("Client is not ready."); const localGlobalCommands = this.commands.filter(c => !c.guildId), log = this.log.extend("SlashCommands"); log("Setting %d global commands...", localGlobalCommands.size); yield this.client.application.commands.set(localGlobalCommands.map(c => c.command)); for (const [id, guild] of this.client.guilds.cache) { const dGuild = this.guilds.get(id); if (dGuild === null || dGuild === void 0 ? void 0 : dGuild.commands.size) log("Setting %d commands for guild %s...", dGuild.commands.size, guild.name); yield guild.commands.set((_a = dGuild === null || dGuild === void 0 ? void 0 : dGuild.commands.map(c => c.command)) !== null && _a !== void 0 ? _a : []); } }); } handleInteraction(interaction) { return __awaiter(this, void 0, void 0, function* () { if (interaction.isAutocomplete()) { const command = this.commands.get(interaction.commandName.toLowerCase()); if (!command) return yield interaction.respond([]); try { yield command.execute(interaction); } catch (err) { console.error(err); } } if (interaction.isCommand() || interaction.isContextMenuCommand() || interaction.isChatInputCommand() || interaction.isUserContextMenuCommand()) { const discordCommand = this.commands.get(interaction.commandName.toLowerCase()); if (!discordCommand) return yield interaction.reply({ content: this.unknownCommandMessage, ephemeral: true }); if (discordCommand.disabled) return yield interaction.reply({ content: this.disabledCommandMessage, ephemeral: true }); let allowed = true; if (discordCommand.channelDenylist && discordCommand.channelDenylist.includes(interaction.channelId)) allowed = false; else if (discordCommand.channelAllowlist && !discordCommand.channelAllowlist.includes(interaction.channelId)) allowed = false; if (!allowed) { if (!this.disallowedChannelMessage.length) return; return yield interaction.reply({ content: this.disallowedChannelMessage, ephemeral: true }); } if (discordCommand.cooldown) { if (!this.cooldowns.has(discordCommand.command.name)) this.cooldowns.set(discordCommand.command.name, new discord_js_1.Collection()); const timestamps = this.cooldowns.get(discordCommand.command.name); if (timestamps.has(interaction.user.id)) { const expirationTime = timestamps.get(interaction.user.id) + discordCommand.cooldown * 1000; if (Date.now() < expirationTime) { return yield interaction.reply({ content: this.commandCooldownMessage.replace("%", Math.ceil((expirationTime - Date.now()) / 1000).toString()), ephemeral: true }); } } timestamps.set(interaction.user.id, Date.now()); setTimeout(() => timestamps.delete(interaction.user.id), discordCommand.cooldown * 1000); } try { yield discordCommand.execute(interaction); } catch (err) { console.error(err); } } }); } } exports.default = DiscordModuleLoader; //# sourceMappingURL=ModuleLoader.js.map