From 0193efae714c7c8f5b6a52b27277cb65cae9971e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antonio=20Rom=C3=A1n?= Date: Mon, 29 Nov 2021 11:19:21 +0100 Subject: [PATCH] fix(ActionsManager): revert to manual requires (#7034) --- scripts/.eslintrc.json | 6 ++ scripts/generateRequires.mjs | 41 +++++++++++++ src/client/actions/ActionsManager.js | 54 ++++++++++++++--- src/client/websocket/handlers/index.js | 59 ++++++++++++++++--- src/util/ModuleImporter.js | 80 -------------------------- 5 files changed, 146 insertions(+), 94 deletions(-) create mode 100644 scripts/.eslintrc.json create mode 100644 scripts/generateRequires.mjs delete mode 100644 src/util/ModuleImporter.js diff --git a/scripts/.eslintrc.json b/scripts/.eslintrc.json new file mode 100644 index 000000000000..38d01a2adca5 --- /dev/null +++ b/scripts/.eslintrc.json @@ -0,0 +1,6 @@ +{ + "extends": "../.eslintrc.json", + "parserOptions": { + "sourceType": "module" + } +} diff --git a/scripts/generateRequires.mjs b/scripts/generateRequires.mjs new file mode 100644 index 000000000000..4b8ab236ade7 --- /dev/null +++ b/scripts/generateRequires.mjs @@ -0,0 +1,41 @@ +import { readdir, writeFile } from 'node:fs/promises'; +import { Constants } from '../src/index.js'; + +async function writeWebsocketHandlerImports() { + const lines = ["'use strict';\n", 'const handlers = Object.fromEntries([']; + + for (const name of Object.keys(Constants.WSEvents)) { + lines.push(` ['${name}', require('./${name}')],`); + } + + lines.push(']);\n\nmodule.exports = handlers;\n'); + + const outputFile = new URL('../src/client/websocket/handlers/index.js', import.meta.url); + + await writeFile(outputFile, lines.join('\n')); +} + +async function writeClientActionImports() { + const lines = ["'use strict';\n", 'class ActionsManager {', ' constructor(client) {', ' this.client = client;\n']; + + const actionsDirectory = new URL('../src/client/actions', import.meta.url); + for (const file of (await readdir(actionsDirectory)).sort()) { + if (file === 'Action.js' || file === 'ActionsManager.js') continue; + + lines.push(` this.register(require('./${file.slice(0, -3)}'));`); + } + + lines.push(' }\n'); + lines.push(' register(Action) {'); + lines.push(" this[Action.name.replace(/Action$/, '')] = new Action(this.client);"); + lines.push(' }'); + lines.push('}\n'); + lines.push('module.exports = ActionsManager;\n'); + + const outputFile = new URL('../src/client/actions/ActionsManager.js', import.meta.url); + + await writeFile(outputFile, lines.join('\n')); +} + +writeWebsocketHandlerImports(); +writeClientActionImports(); diff --git a/src/client/actions/ActionsManager.js b/src/client/actions/ActionsManager.js index 581602caba9c..b4694b7059ce 100644 --- a/src/client/actions/ActionsManager.js +++ b/src/client/actions/ActionsManager.js @@ -1,16 +1,56 @@ 'use strict'; -const ModuleImporter = require('../../util/ModuleImporter'); - class ActionsManager { constructor(client) { this.client = client; - const modules = ModuleImporter.import('./client/actions', ['Action.js', 'ActionsManager.js']); - - for (const module of modules) { - this.register(module); - } + this.register(require('./ChannelCreate')); + this.register(require('./ChannelDelete')); + this.register(require('./ChannelUpdate')); + this.register(require('./GuildBanAdd')); + this.register(require('./GuildBanRemove')); + this.register(require('./GuildChannelsPositionUpdate')); + this.register(require('./GuildDelete')); + this.register(require('./GuildEmojiCreate')); + this.register(require('./GuildEmojiDelete')); + this.register(require('./GuildEmojiUpdate')); + this.register(require('./GuildEmojisUpdate')); + this.register(require('./GuildIntegrationsUpdate')); + this.register(require('./GuildMemberRemove')); + this.register(require('./GuildMemberUpdate')); + this.register(require('./GuildRoleCreate')); + this.register(require('./GuildRoleDelete')); + this.register(require('./GuildRoleUpdate')); + this.register(require('./GuildRolesPositionUpdate')); + this.register(require('./GuildStickerCreate')); + this.register(require('./GuildStickerDelete')); + this.register(require('./GuildStickerUpdate')); + this.register(require('./GuildStickersUpdate')); + this.register(require('./GuildUpdate')); + this.register(require('./InteractionCreate')); + this.register(require('./InviteCreate')); + this.register(require('./InviteDelete')); + this.register(require('./MessageCreate')); + this.register(require('./MessageDelete')); + this.register(require('./MessageDeleteBulk')); + this.register(require('./MessageReactionAdd')); + this.register(require('./MessageReactionRemove')); + this.register(require('./MessageReactionRemoveAll')); + this.register(require('./MessageReactionRemoveEmoji')); + this.register(require('./MessageUpdate')); + this.register(require('./PresenceUpdate')); + this.register(require('./StageInstanceCreate')); + this.register(require('./StageInstanceDelete')); + this.register(require('./StageInstanceUpdate')); + this.register(require('./ThreadCreate')); + this.register(require('./ThreadDelete')); + this.register(require('./ThreadListSync')); + this.register(require('./ThreadMemberUpdate')); + this.register(require('./ThreadMembersUpdate')); + this.register(require('./TypingStart')); + this.register(require('./UserUpdate')); + this.register(require('./VoiceStateUpdate')); + this.register(require('./WebhooksUpdate')); } register(Action) { diff --git a/src/client/websocket/handlers/index.js b/src/client/websocket/handlers/index.js index 1e499c6e5b66..393727a8e245 100644 --- a/src/client/websocket/handlers/index.js +++ b/src/client/websocket/handlers/index.js @@ -1,11 +1,56 @@ 'use strict'; -const { WSEvents } = require('../../../util/Constants'); - -const handlers = {}; - -for (const name of Object.keys(WSEvents)) { - handlers[name] = require(`./${name}.js`); -} +const handlers = Object.fromEntries([ + ['READY', require('./READY')], + ['RESUMED', require('./RESUMED')], + ['APPLICATION_COMMAND_CREATE', require('./APPLICATION_COMMAND_CREATE')], + ['APPLICATION_COMMAND_DELETE', require('./APPLICATION_COMMAND_DELETE')], + ['APPLICATION_COMMAND_UPDATE', require('./APPLICATION_COMMAND_UPDATE')], + ['GUILD_CREATE', require('./GUILD_CREATE')], + ['GUILD_DELETE', require('./GUILD_DELETE')], + ['GUILD_UPDATE', require('./GUILD_UPDATE')], + ['INVITE_CREATE', require('./INVITE_CREATE')], + ['INVITE_DELETE', require('./INVITE_DELETE')], + ['GUILD_MEMBER_ADD', require('./GUILD_MEMBER_ADD')], + ['GUILD_MEMBER_REMOVE', require('./GUILD_MEMBER_REMOVE')], + ['GUILD_MEMBER_UPDATE', require('./GUILD_MEMBER_UPDATE')], + ['GUILD_MEMBERS_CHUNK', require('./GUILD_MEMBERS_CHUNK')], + ['GUILD_INTEGRATIONS_UPDATE', require('./GUILD_INTEGRATIONS_UPDATE')], + ['GUILD_ROLE_CREATE', require('./GUILD_ROLE_CREATE')], + ['GUILD_ROLE_DELETE', require('./GUILD_ROLE_DELETE')], + ['GUILD_ROLE_UPDATE', require('./GUILD_ROLE_UPDATE')], + ['GUILD_BAN_ADD', require('./GUILD_BAN_ADD')], + ['GUILD_BAN_REMOVE', require('./GUILD_BAN_REMOVE')], + ['GUILD_EMOJIS_UPDATE', require('./GUILD_EMOJIS_UPDATE')], + ['CHANNEL_CREATE', require('./CHANNEL_CREATE')], + ['CHANNEL_DELETE', require('./CHANNEL_DELETE')], + ['CHANNEL_UPDATE', require('./CHANNEL_UPDATE')], + ['CHANNEL_PINS_UPDATE', require('./CHANNEL_PINS_UPDATE')], + ['MESSAGE_CREATE', require('./MESSAGE_CREATE')], + ['MESSAGE_DELETE', require('./MESSAGE_DELETE')], + ['MESSAGE_UPDATE', require('./MESSAGE_UPDATE')], + ['MESSAGE_DELETE_BULK', require('./MESSAGE_DELETE_BULK')], + ['MESSAGE_REACTION_ADD', require('./MESSAGE_REACTION_ADD')], + ['MESSAGE_REACTION_REMOVE', require('./MESSAGE_REACTION_REMOVE')], + ['MESSAGE_REACTION_REMOVE_ALL', require('./MESSAGE_REACTION_REMOVE_ALL')], + ['MESSAGE_REACTION_REMOVE_EMOJI', require('./MESSAGE_REACTION_REMOVE_EMOJI')], + ['THREAD_CREATE', require('./THREAD_CREATE')], + ['THREAD_UPDATE', require('./THREAD_UPDATE')], + ['THREAD_DELETE', require('./THREAD_DELETE')], + ['THREAD_LIST_SYNC', require('./THREAD_LIST_SYNC')], + ['THREAD_MEMBER_UPDATE', require('./THREAD_MEMBER_UPDATE')], + ['THREAD_MEMBERS_UPDATE', require('./THREAD_MEMBERS_UPDATE')], + ['USER_UPDATE', require('./USER_UPDATE')], + ['PRESENCE_UPDATE', require('./PRESENCE_UPDATE')], + ['TYPING_START', require('./TYPING_START')], + ['VOICE_STATE_UPDATE', require('./VOICE_STATE_UPDATE')], + ['VOICE_SERVER_UPDATE', require('./VOICE_SERVER_UPDATE')], + ['WEBHOOKS_UPDATE', require('./WEBHOOKS_UPDATE')], + ['INTERACTION_CREATE', require('./INTERACTION_CREATE')], + ['STAGE_INSTANCE_CREATE', require('./STAGE_INSTANCE_CREATE')], + ['STAGE_INSTANCE_UPDATE', require('./STAGE_INSTANCE_UPDATE')], + ['STAGE_INSTANCE_DELETE', require('./STAGE_INSTANCE_DELETE')], + ['GUILD_STICKERS_UPDATE', require('./GUILD_STICKERS_UPDATE')], +]); module.exports = handlers; diff --git a/src/util/ModuleImporter.js b/src/util/ModuleImporter.js deleted file mode 100644 index 7c0f9f86b88e..000000000000 --- a/src/util/ModuleImporter.js +++ /dev/null @@ -1,80 +0,0 @@ -'use strict'; - -const fs = require('node:fs'); -const path = require('node:path'); - -/** - * The ModuleImporter helper class is used to import local files, by using the bundler or file system, whichever is - * needed in the current build. - * - * @private - */ -class ModuleImporter extends null { - /** - * This method is used to import a variable number of files in a specific directory and is built to also work with - * webpack and potentially other bundlers. - * - * @param {string} pathToDirectory the path to the searched directory (relative to the `src` directory) - * @param {string[]} [excludedFiles=[]] an array of files which are excluded from the import - * - * @returns {unknown[]} an array of dynamically imported modules - */ - static import(pathToDirectory, excludedFiles = []) { - pathToDirectory = path.normalize(pathToDirectory); - - let moduleMap; - - if (typeof __webpack_require__ === 'function') { - moduleMap = this.importWebpack(pathToDirectory); - } else { - moduleMap = this.importFilesystem(pathToDirectory); - } - - const requiredModules = []; - for (const [fileName, requireFunction] of moduleMap.entries()) { - if (excludedFiles.includes(path.basename(fileName))) continue; - requiredModules.push(requireFunction()); - } - - return requiredModules; - } - - /** - * Helper function to import all modules in a given directory via file system. - * - * @param {string} pathToDirectory the path to the searched directory (relative to the `src` directory) - * @returns {Map} a map of resolved file names to their require function - * - * @private - */ - static importFilesystem(pathToDirectory) { - const basePath = path.resolve(__dirname, '..', pathToDirectory); - const files = fs.readdirSync(basePath); - // Require Function is returned for lazy evaluation - return new Map(files.map(file => [file, () => require(path.join(basePath, file))])); - } - - /** - * Helper function to import all modules in a given directory via webpack.context. - * - * @param {string} pathToDirectory the path to the searched directory (relative to the `src` directory) - * @returns {Map} a map of resolved file names to their require function - * - * @private - */ - static importWebpack(pathToDirectory) { - // The "function" `require.context` is actually evaluated at build/bundling time, and needs to be called with - // literals because of that. By building a context of '..' we actually cover the whole codebase and can - // dynamically import any subdirectory. When not using webpack, the following line is never evaluated. - const context = require.context('..', true, /\.js$/); - - const files = context - .keys() - // We have all files in our context, so now we filter the files in the correct directory - .filter(file => path.normalize(file).startsWith(pathToDirectory)); - - return new Map(files.map(file => [file, () => context(file)])); - } -} - -module.exports = ModuleImporter;