refactor: update deno template and loader logic (#11060)

* refactor: update deno template and loader logic

* yeet

---------

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
This commit is contained in:
Almeida
2025-09-04 13:36:26 +01:00
committed by GitHub
parent 5a656b849f
commit 8ca279e0c3
18 changed files with 96 additions and 148 deletions

View File

@@ -1,5 +1,5 @@
import type { RESTPostAPIApplicationCommandsJSONBody, CommandInteraction } from 'npm:discord.js@^14.22.0';
import { z } from 'npm:zod@^3.25.76';
import type { CommandInteraction, RESTPostAPIApplicationCommandsJSONBody } from 'discord.js';
import { z } from 'zod';
import type { StructurePredicate } from '../util/loaders.ts';
/**

View File

@@ -1,21 +1,21 @@
import type { ClientEvents } from 'npm:discord.js@^14.22.0';
import { z } from 'npm:zod@^3.25.76';
import type { ClientEvents } from 'discord.js';
import { z } from 'zod';
import type { StructurePredicate } from '../util/loaders.ts';
/**
* Defines the structure of an event.
*/
export type Event<T extends keyof ClientEvents = keyof ClientEvents> = {
export type Event<EventName extends keyof ClientEvents = keyof ClientEvents> = {
/**
* The function to execute when the event is emitted.
*
* @param parameters - The parameters of the event
*/
execute(...parameters: ClientEvents[T]): Promise<void> | void;
execute(...parameters: ClientEvents[EventName]): Promise<void> | void;
/**
* The name of the event to listen to
*/
name: T;
name: EventName;
/**
* Whether or not the event should only be listened to once
*

View File

@@ -1,4 +1,4 @@
import { Events } from 'npm:discord.js@^14.22.0';
import { Events } from 'discord.js';
import type { Event } from './index.ts';
import { loadCommands } from '../util/loaders.ts';

View File

@@ -1,4 +1,4 @@
import { Events } from 'npm:discord.js@^14.22.0';
import { Events } from 'discord.js';
import type { Event } from './index.ts';
export default {

View File

@@ -1,6 +1,4 @@
import 'https://deno.land/std@0.223.0/dotenv/load.ts';
import { URL } from 'node:url';
import { Client, GatewayIntentBits } from 'npm:discord.js@^14.22.0';
import { Client, GatewayIntentBits } from 'discord.js';
import { loadEvents } from './util/loaders.ts';
// Initialize the client

View File

@@ -1,7 +1,5 @@
import 'https://deno.land/std@0.223.0/dotenv/load.ts';
import { URL } from 'node:url';
import { API } from 'npm:@discordjs/core@^2.2.1/http-only';
import { REST } from 'npm:discord.js@^14.22.0';
import { API } from '@discordjs/core/http-only';
import { REST } from 'discord.js';
import { loadCommands } from './loaders.ts';
const commands = await loadCommands(new URL('../commands/', import.meta.url));

View File

@@ -1,6 +1,7 @@
import type { PathLike } from 'node:fs';
import { readdir, stat } from 'node:fs/promises';
import { URL } from 'node:url';
import { glob, stat } from 'node:fs/promises';
import { resolve } from 'node:path';
import { fileURLToPath } from 'node:url';
import type { Command } from '../commands/index.ts';
import { predicate as commandPredicate } from '../commands/index.ts';
import type { Event } from '../events/index.ts';
@@ -9,7 +10,7 @@ import { predicate as eventPredicate } from '../events/index.ts';
/**
* A predicate to check if the structure is valid
*/
export type StructurePredicate<T> = (structure: unknown) => structure is T;
export type StructurePredicate<Structure> = (structure: unknown) => structure is Structure;
/**
* Loads all the structures in the provided directory
@@ -19,11 +20,11 @@ export type StructurePredicate<T> = (structure: unknown) => structure is T;
* @param recursive - Whether to recursively load the structures in the directory
* @returns
*/
export async function loadStructures<T>(
export async function loadStructures<Structure>(
dir: PathLike,
predicate: StructurePredicate<T>,
predicate: StructurePredicate<Structure>,
recursive = true,
): Promise<T[]> {
): Promise<Structure[]> {
// Get the stats of the directory
const statDir = await stat(dir);
@@ -32,34 +33,24 @@ export async function loadStructures<T>(
throw new Error(`The directory '${dir}' is not a directory.`);
}
// Get all the files in the directory
const files = await readdir(dir);
// Create an empty array to store the structures
const structures: T[] = [];
const structures: Structure[] = [];
// Loop through all the files in the directory
for (const file of files) {
const fileUrl = new URL(`${dir}/${file}`, import.meta.url);
// Create a glob pattern to match the .ts files
const basePath = dir instanceof URL ? fileURLToPath(dir) : dir.toString();
const pattern = resolve(basePath, recursive ? '**/*.ts' : '*.ts');
// Get the stats of the file
const statFile = await stat(fileUrl);
// If the file is a directory and recursive is true, recursively load the structures in the directory
if (statFile.isDirectory() && recursive) {
structures.push(...(await loadStructures(fileUrl, predicate, recursive)));
continue;
}
// If the file is index.ts or the file does not end with .ts, skip the file
if (file === 'index.ts' || !file.endsWith('.ts')) {
// Loop through all the matching files in the directory
for await (const file of glob(pattern)) {
// If the file is index.ts, skip the file
if (file.endsWith('/index.ts')) {
continue;
}
// Import the structure dynamically from the file
const structure = (await import(fileUrl.toString())).default;
const { default: structure } = await import(file);
// If the structure is a valid structure, add it
// If the default export is a valid structure, add it
if (predicate(structure)) {
structures.push(structure);
}