diff --git a/src/core/module-loading.ts b/src/core/module-loading.ts index bacf73b..d0717fc 100644 --- a/src/core/module-loading.ts +++ b/src/core/module-loading.ts @@ -5,27 +5,29 @@ import { type Observable, from, mergeMap, ObservableInput } from 'rxjs'; import { readdir, stat } from 'fs/promises'; import { basename, extname, join, resolve } from 'path'; import { ImportPayload } from '../handler/types'; -import * as assert from 'node:assert'; -import { clazz } from '../handler/commands'; +import { CommandExecutable, clazz } from '../handler/commands'; export type ModuleResult = Promise, SernError>>; + +function isClassModule(m: unknown): m is typeof CommandExecutable { + return m != undefined && Reflect.has(m, clazz); +} + export async function importModule(absPath: string) { + let module = /// #if MODE === 'esm' - return import(absPath).then(i => i.default as T); + import(absPath).then(i => i.default); // eslint-disable-line /// #elif MODE === 'cjs' - return require(absPath).default as T; // eslint-disable-line + require(absPath).default; // eslint-disable-line /// #endif + return module.then(m => isClassModule(m) ? m.getInstance():m) as T; } export async function defaultModuleLoader(absPath: string): ModuleResult { let module = await importModule(absPath); if (module === undefined) { return Err(SernError.UndefinedModule); } - if(Reflect.has(module, clazz)) { - //@ts-ignore - module = module.getInstance(); - } //todo readd class modules return Ok({ module, absPath }); } diff --git a/src/core/structures/services/module-manager.ts b/src/core/structures/services/module-manager.ts index eb34a24..84ff640 100644 --- a/src/core/structures/services/module-manager.ts +++ b/src/core/structures/services/module-manager.ts @@ -1,3 +1,4 @@ +import { clazz } from '../../../handler/commands'; import { CoreModuleStore, ModuleManager } from '../../contracts'; import { importModule } from '../../module-loading'; import { CommandMeta, CommandModule, Module } from '../../types/modules'; @@ -36,8 +37,8 @@ export class DefaultModuleManager implements ModuleManager { const publishable = 0b000000110; return Promise.all( Array.from(entries) - .filter(([id]) => (Number.parseInt(id.at(-1)!) & publishable) !== 0) - .map(([, path]) => importModule(path)), + .filter(([id]) => !(Number.parseInt(id.at(-1)!) & publishable)) + .map(([, path]) => importModule(path)) ); } } diff --git a/src/handler/commands.ts b/src/handler/commands.ts index d645b50..e2fe14f 100644 --- a/src/handler/commands.ts +++ b/src/handler/commands.ts @@ -1,7 +1,7 @@ import { ClientEvents } from 'discord.js'; import { CommandType, EventType, PluginType } from '../core/structures'; -import { AnyCommandPlugin, AnyEventPlugin, CommandArgs, ControlPlugin, EventArgs } from '../core/types/plugins'; -import { CommandModule, EventModule, InputCommand, InputEvent } from '../core/types/modules'; +import { AnyCommandPlugin, AnyEventPlugin, CommandArgs, ControlPlugin, EventArgs, InitPlugin } from '../core/types/plugins'; +import { CommandModule, EventModule, InputCommand, InputEvent, Module } from '../core/types/modules'; import { partitionPlugins } from '../core/functions'; import { Awaitable } from '../shared'; @@ -27,9 +27,9 @@ export function commandModule(mod: InputCommand): CommandModule { export function eventModule(mod: InputEvent): EventModule { const [onEvent, plugins] = partitionPlugins(mod.plugins); return { - onEvent, - plugins, ...mod, + plugins, + onEvent } as EventModule; } @@ -50,7 +50,11 @@ export function discordEvent(mod: { }); } - +function prepareClassPlugins(c: Module) { + const [onEvent, initPlugins] = partitionPlugins(c.plugins); + c.plugins = initPlugins as InitPlugin[]; + c.onEvent = onEvent as ControlPlugin[]; +} // // Class modules: // Can be refactored. @@ -59,27 +63,17 @@ export function discordEvent(mod: { * @Experimental * Will be refactored / changed in future */ -export abstract class CommandExecutable { +export abstract class CommandExecutable { abstract type: Type; - plugins?: AnyCommandPlugin[]; - onEvent?: ControlPlugin[] + plugins: AnyCommandPlugin[] = []; private static _instance : CommandModule; static readonly [clazz] = true; - constructor() { - if(this.onEvent) { - console.warn('Put control plugins in `onEvent` into the `plugins` field, as it\'s automatically handled in v3.'); - } else { - const [onEvent, plugins] = partitionPlugins(this.plugins); - this.plugins = plugins as AnyCommandPlugin[]; - Reflect.set(this, 'onEvent', onEvent); - } - } - static getInstance() { if (!CommandExecutable._instance) { //@ts-ignore CommandExecutable._instance = new this(); + prepareClassPlugins(CommandExecutable._instance); } return CommandExecutable._instance; } @@ -94,23 +88,14 @@ export abstract class CommandExecutable { */ export abstract class EventExecutable { abstract type: Type; - plugins?: AnyEventPlugin[]; + plugins: AnyEventPlugin[] = []; static readonly [clazz] = true; - onEvent?: ControlPlugin[] private static _instance : EventModule; - constructor() { - if(this.onEvent) { - console.warn('Put control plugins in `onEvent` into the `plugins` field, as it\'s automatically handled in v3.'); - } else { - const [onEvent, plugins] = partitionPlugins(this.plugins); - this.plugins = plugins as AnyEventPlugin[]; - Reflect.set(this, 'onEvent', onEvent); - } - } static getInstance() { if (!EventExecutable._instance) { //@ts-ignore EventExecutable._instance = new this(); + prepareClassPlugins(EventExecutable._instance); } return EventExecutable._instance; } diff --git a/src/handler/events/ready.ts b/src/handler/events/ready.ts index 969bbc9..fc876c1 100644 --- a/src/handler/events/ready.ts +++ b/src/handler/events/ready.ts @@ -30,7 +30,7 @@ export function startReadyEvent( .subscribe(module => { const result = registerModule(moduleManager, module); if (result.err) { - throw Error(SernError.InvalidModuleType); + throw Error(SernError.InvalidModuleType + " " + result.val); } }); } @@ -42,7 +42,7 @@ function registerModule>( const { id, fullPath } = manager.getMetadata(module); - assert.ok(module.type > 0 && module.type < 1<<10, `Found ${module}, which does not have a valid type`); + assert.ok(module.type > 0 && module.type < 1<<10, `Found ${module.name} at ${fullPath}, which does not have a valid type`); if (module.type === CommandType.Both || module.type === CommandType.Text ) {