feat : update module loader for extensibility

This commit is contained in:
Jacob Nguyen
2022-03-16 14:41:22 -05:00
parent 4102c7102d
commit 5b53d4203e
6 changed files with 37 additions and 25 deletions

View File

@@ -2,8 +2,10 @@ import { concatMap, first, from, fromEvent, map, pipe, tap } from "rxjs";
import { basename } from 'path';
import * as Files from '../utilities/readFile';
import type Wrapper from '../structures/wrapper';
import type { Command } from "../structures/commands/command";
import type { ApplicationCommandOptionData } from "discord.js";
import type { Modules } from "../structures/structxports";
import type { HandlerCallback, ModuleDefs, ModuleHandlers, ModuleStates, ModuleType } from "../structures/commands/moduleHandler";
import { CommandType } from "../sern";
export const onReady = ( wrapper : Wrapper ) => {
const { client, init, commands, } = wrapper;
fromEvent(client, 'ready')
@@ -20,17 +22,32 @@ export const onReady = ( wrapper : Wrapper ) => {
.subscribe( () => console.log(Files.Commands));
}
function setCommands ( { mod, absPath } : { mod : Command, absPath : string } ) {
const options = mod.getOptions() ?? [] as ApplicationCommandOptionData[];
const name = mod.getName() ?? Files.fmtFileName(basename(absPath));
const handler = ( name : string ) =>
({
[CommandType.TEXT] : mod => {
mod.alias.forEach ( a => Files.Alias.set(a,mod));
Files.Commands.set( name, mod );
},
[CommandType.SLASH]: mod => {
Files.Commands.set( name, mod);
},
[CommandType.BOTH] : mod => {
Files.Commands.set ( name, mod);
mod.alias.forEach (a => Files.Alias.set(a, mod));
}
}) as ModuleHandlers;
mod.getAlias()?.forEach( n => Files.Alias.set( n, { mod, options } ));
const registerModules = <T extends ModuleType >(name : string, mod : ModuleStates[T]) =>
(handler(name)[mod.type] as HandlerCallback<T>)(mod);
Files.Commands.set(name, { mod, options });
function setCommands ( { mod, absPath } : { mod : Modules.Module, absPath : string } ) {
const name = mod.name ?? Files.fmtFileName(basename(absPath));
registerModules(name, mod);
}
async function createCommandCache(
arr: Promise<{mod: Command, absPath: string}[]>
arr: Promise<{mod: Modules.Module, absPath: string}[]>
) {
console.log(await arr);
from(await arr).subscribe ( setCommands );
}

View File

@@ -1,4 +1,4 @@
import type { ApplicationCommandOptionData, Awaitable } from "discord.js";
import type { ApplicationCommandOptionData, Awaitable, PartialWebhookMixin } from "discord.js";
import type { possibleOutput } from "../../../types/handler";
import type { CommandType } from "../../sern";
@@ -15,7 +15,7 @@ export type Slash = { type : CommandType.SLASH; options : ApplicationCommandOpti
export type Both = { type : CommandType.BOTH; alias : string[] | []; options : ApplicationCommandOptionData[] | [] }
export type Module =
(BaseModule & Slash) | (BaseModule & Both) | (BaseModule & Text);
(BaseModule & Slash) | (BaseModule & Both) | (BaseModule & Text);

View File

@@ -15,8 +15,7 @@ export type ModuleType = keyof ModuleDefs;
// The keys mapped to a constructed union with its type
export type ModuleStates = { [ K in ModuleType ] : { type : K } & ModuleDefs[K] };
// A handler callback that is called on each ModuleDef
export type HandlerCallback<K extends ModuleType>= ( params : ModuleStates[K] ) => unknown;
export type HandlerCallback<K extends ModuleType> = ( params : ModuleStates[K] ) => unknown;
//An object that acts as the mapped object to handler
export type ModuleHandlers = { [K in ModuleType] : HandlerCallback<K> };

View File

@@ -1,4 +1,4 @@
import type { Message } from 'discord.js';
import { ChannelType, Message } from 'discord.js';
/**
* @param message The message object
@@ -8,7 +8,7 @@ import type { Message } from 'discord.js';
*/
export function isNotFromDM ( message: Message ) {
return message.channel.type !== 'DM';
return message.channel.type !== ChannelType.DM;
}
/**

View File

@@ -2,15 +2,11 @@ import type { ApplicationCommandOptionData } from 'discord.js';
import { readdirSync, statSync } from 'fs';
import { join } from 'path';
import type { Command } from '../structures/commands/command';
import type { Module } from '../structures/commands/module';
export type CommandVal = {
mod: Command;
options: ApplicationCommandOptionData[];
};
export const Commands = new Map<string, CommandVal>();
export const Alias = new Map<string, Exclude< CommandVal, 'options' >>();
export const Commands = new Map<string, Module>();
export const Alias = new Map<string, Module>();
// Courtesy @Townsy45
function readPath(dir: string, arrayOfFiles: string[] = []): string[] {
@@ -37,13 +33,13 @@ export const fmtFileName = (n: string) => n.substring(0, n.length - 3);
export async function buildData(commandDir: string ): Promise<
{
mod: Command;
mod: Module;
absPath: string;
}[]
> {
return Promise.all(
getCommands(commandDir).map( async (absPath) => {
return { mod: (await import(absPath)).default as Command, absPath };
return { mod: (await import(absPath)).module as Module, absPath };
}),
);
}

View File

@@ -7,13 +7,13 @@ import type {
Awaitable,
} from 'discord.js';
import type Module from '../handler/structures/module';
import type { Modules } from '../handler/structures/structxports';
export type Visibility = 'private' | 'public';
// Anything that can be sent in a `<TextChannel>#send` or `<CommandInteraction>#reply`
export type possibleOutput<T = string> = T | (MessagePayload & MessageOptions);
export type execute = Module<unknown>['execute'];
export type execute = Modules.Module['execute'];
// Thanks @cursorsdottsx
export type ParseType<T> = {