mirror of
https://github.com/sern-handler/handler
synced 2026-06-06 01:16:55 +00:00
fix: plugins for class modules and module loader
This commit is contained in:
@@ -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<T> = Promise<Result<ImportPayload<T>, SernError>>;
|
||||
|
||||
|
||||
function isClassModule(m: unknown): m is typeof CommandExecutable {
|
||||
return m != undefined && Reflect.has(m, clazz);
|
||||
}
|
||||
|
||||
export async function importModule<T>(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<T extends Module>(absPath: string): ModuleResult<T> {
|
||||
let module = await importModule<T>(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 });
|
||||
}
|
||||
|
||||
@@ -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<CommandModule>(path)),
|
||||
.filter(([id]) => !(Number.parseInt(id.at(-1)!) & publishable))
|
||||
.map(([, path]) => importModule<CommandModule>(path))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<T extends keyof ClientEvents>(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<T extends keyof ClientEvents>(mod: {
|
||||
* @Experimental
|
||||
* Will be refactored / changed in future
|
||||
*/
|
||||
export abstract class CommandExecutable<const Type extends CommandType> {
|
||||
export abstract class CommandExecutable<const Type extends CommandType = CommandType> {
|
||||
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<const Type extends CommandType> {
|
||||
*/
|
||||
export abstract class EventExecutable<Type extends EventType> {
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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<T extends Processed<AnyModule>>(
|
||||
|
||||
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
|
||||
) {
|
||||
|
||||
Reference in New Issue
Block a user