-
Notifications
You must be signed in to change notification settings - Fork 0
feat: Switch from dynamic import to a more explicit approach #3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
8e6a395
eff689d
9e558f4
6660944
4cd0d16
ce1c40f
9847659
a09150d
29ad085
07356b6
18d612e
8f6ddba
8a9fc4c
1baab21
c180739
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,114 +1,27 @@ | ||
| import type { PathLike } from 'node:fs'; | ||
| import { readdir, stat } from 'node:fs/promises'; | ||
| import type { Client } from 'discord.js'; | ||
| import { docsCommands } from '../commands/docs/index.js'; | ||
| import { guidesCommand } from '../commands/guides/index.js'; | ||
| import { type Command, predicate as commandPredicate } from '../commands/index.js'; | ||
| import { pingCommand } from '../commands/ping.js'; | ||
| import { tipsCommands } from '../commands/tips/index.js'; | ||
| import { hasVarEvent } from '../events/has-var.js'; | ||
|
||
| import { type DiscordEvent, predicate as eventPredicate } from '../events/index.js'; | ||
| import { interactionCreateEvent } from '../events/interaction-create.js'; | ||
| import { justAskEvent } from '../events/just-ask.js'; | ||
| import { readyEvent } from '../events/ready.js'; | ||
|
|
||
| /** | ||
| * A predicate to check if the structure is valid | ||
| */ | ||
| export type StructurePredicate<T> = (structure: unknown) => structure is T; | ||
|
|
||
| /** | ||
| * Loads all structures in the provided directory | ||
| * | ||
| * @param dir - The directory to load the structures from | ||
| * @param predicate - The predicate to check if the structure is valid | ||
| * @param recursive- Whether to load structures recursively | ||
| * @returns | ||
| */ | ||
| export const loadStructures = async <T>( | ||
| dir: PathLike, | ||
| predicate: StructurePredicate<T>, | ||
| recursive = true | ||
| ): Promise<T[]> => { | ||
| const statDir = await stat(dir); | ||
|
|
||
| if (!statDir.isDirectory()) { | ||
| throw new Error(`The path ${dir} is not a directory`); | ||
| } | ||
|
|
||
| // Get all files in the directory | ||
| const files = await readdir(dir); | ||
|
|
||
| // Create an empty array to store the structures | ||
| const structures: T[] = []; | ||
|
|
||
| // Loop through all files in the directory | ||
| for (const file of files) { | ||
| const fileUrl = new URL(`${dir}/${file}`, import.meta.url); | ||
|
|
||
| // Get the stats of the file | ||
| const fileStat = await stat(fileUrl); | ||
|
|
||
| // If the file is a directory and recursive is true, load the structures in the directory | ||
| if (fileStat.isDirectory() && recursive) { | ||
| structures.push(...(await loadStructures(fileUrl, predicate, recursive))); | ||
| continue; | ||
| } | ||
|
|
||
| // If the file is index.js or the file does not end with .js, skip it | ||
| if ( | ||
| // file === 'index.js' || | ||
| // file === 'index.ts' || | ||
| !file.endsWith('.js') && | ||
| !file.endsWith('.ts') | ||
| ) { | ||
| continue; | ||
| } | ||
|
|
||
| // Import the structure from the file | ||
| const { default: structure } = await import(fileUrl.href); | ||
|
|
||
| // If the structure is an array, loop through all structures in the array and check if they are valid | ||
| // If the structure is not an array, check if it is valid | ||
| if (Array.isArray(structure)) { | ||
| for (const str of structure) { | ||
| if (predicate(str)) { | ||
| structures.push(str); | ||
| } | ||
| } | ||
| } else if (predicate(structure)) { | ||
| structures.push(structure); | ||
| } | ||
| } | ||
| return structures; | ||
| }; | ||
|
|
||
| /** | ||
| * Gets all the commands in the provided directory | ||
| * | ||
| * @param dir - The directory to load the commands from | ||
| * @param recursive - Whether to load commands recursively | ||
| * @returns A map of command names to commands | ||
| */ | ||
| export const getCommands = async ( | ||
| dir: PathLike, | ||
| recursive = true | ||
| ): Promise<Map<string, Command>> => { | ||
| const commands = await loadStructures<Command>(dir, commandPredicate, recursive); | ||
|
|
||
| return new Map(commands.map((command) => [command.data.name, command])); | ||
| }; | ||
|
|
||
| /** | ||
| * Gets all the events in the provided directory | ||
| * | ||
| * @param dir - The directory to load the events from | ||
| * @param recursive - Whether to load events recursively | ||
| * @returns An array of events | ||
| */ | ||
| export const getEvents = async (dir: PathLike, recursive = true): Promise<DiscordEvent[]> => { | ||
| return loadStructures(dir, eventPredicate, recursive); | ||
| }; | ||
|
|
||
| /** | ||
| * Loads commands to the Discord API | ||
| * Register commands to the Discord API | ||
| * | ||
| * @param client - The Discord client | ||
| * @param commands - A map of command names to commands | ||
| */ | ||
| export const loadCommands = async ( | ||
| export const registerCommands = async ( | ||
| client: Client, | ||
| commands: Map<string, Command> | ||
| ): Promise<void> => { | ||
|
|
@@ -128,12 +41,12 @@ export const loadCommands = async ( | |
| }; | ||
|
|
||
| /** | ||
| * Loads events to the Discord client | ||
| * Register events to the Discord client | ||
| * | ||
| * @param client - The Discord client | ||
| * @param events - An array of events | ||
| */ | ||
| export const loadEvents = async (client: Client, events: DiscordEvent[]): Promise<void> => { | ||
| export const registerEvents = async (client: Client, events: DiscordEvent[]): Promise<void> => { | ||
| // Loop through all events | ||
| for (const event of events) { | ||
| console.log(`Loading event: ${event.name}`); | ||
|
|
@@ -148,3 +61,26 @@ export const loadEvents = async (client: Client, events: DiscordEvent[]): Promis | |
| }); | ||
| } | ||
| }; | ||
|
|
||
| /** | ||
| * | ||
| * @returns An array of events | ||
| */ | ||
| const loadEvents = (): DiscordEvent[] => { | ||
| const events = [hasVarEvent, readyEvent, justAskEvent, interactionCreateEvent].filter( | ||
| eventPredicate | ||
| ); | ||
| return events as DiscordEvent[]; | ||
| }; | ||
|
|
||
| /** | ||
| * | ||
| * @returns A map of command names to commands | ||
| */ | ||
| const loadCommands = (): Map<string, Command> => { | ||
| const commands = [pingCommand, tipsCommands, guidesCommand, docsCommands].flat(); | ||
| return new Map(commands.filter(commandPredicate).map((command) => [command.data.name, command])); | ||
| }; | ||
|
|
||
| export const commands = loadCommands(); | ||
| export const events = loadEvents(); | ||
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(question) What i don't understand, why do you import the commands and events here, just to manipulate them, and export them?