diff --git a/src/core/functions.ts b/src/core/functions.ts index 46e204c..02ef466 100644 --- a/src/core/functions.ts +++ b/src/core/functions.ts @@ -14,8 +14,8 @@ import { PayloadType, PluginType } from './structures/enums'; import assert from 'assert'; import type { Payload } from '../types/utility'; -export const ok = (val: unknown) => Ok(val); -export const err = (val: string) => Err(val); +export const ok = (val: unknown=undefined) => Ok(val); +export const err = (val?: string) => Err(val); export function partitionPlugins (arr: Array<{ type: PluginType }> = []): [T[], V[]] { diff --git a/src/handlers/event-utils.ts b/src/handlers/event-utils.ts index 4281458..d0babb4 100644 --- a/src/handlers/event-utils.ts +++ b/src/handlers/event-utils.ts @@ -143,7 +143,6 @@ export function createMessageHandler( ) { return createGenericHandler(source, async event => { const [prefix] = fmt(event.content, defaultPrefix); - console.log(prefix) let module= mg.get(`${prefix}_T`) ?? mg.get(`${prefix}_B`) as Module; if(!module) { return Err('Possibly undefined behavior: could not find a static id to resolve'); diff --git a/src/handlers/ready.ts b/src/handlers/ready.ts index b641ab9..e5aa8f6 100644 --- a/src/handlers/ready.ts +++ b/src/handlers/ready.ts @@ -18,18 +18,26 @@ export default async function(dir: string, deps : UnpackedDependencies) { // https://observablehq.com/@ehouais/multiple-promises-as-an-async-generator // possibly optimize to concurrently import modules for await (const path of Files.readRecursive(dir)) { - const { module } = await Files.importModule(path); + let { module } = await Files.importModule(path); const validType = module.type >= CommandType.Text && module.type <= CommandType.ChannelSelect; if(!validType) { throw Error(`Found ${module.name} at ${module.meta.absPath}, which has an incorrect \`type\``); } for(const plugin of module.plugins) { - const res = await plugin.execute({ module, absPath: module.meta.absPath }); + const res = await plugin.execute({ + module, + absPath: module.meta.absPath , + updateModule: (partial: Partial) => { + module = { ...module, ...partial }; + return module; + } + }); if(res.isErr()) { sEmitter.emit('module.register', resultPayload(PayloadType.Failure, module, SernError.PluginFailure)); throw Error("Plugin failed with controller.stop()"); } } + Object.freeze(module); // no more writing!! commands.set(module.meta.id, module); sEmitter.emit('module.register', resultPayload(PayloadType.Success, module)); } diff --git a/src/types/core-modules.ts b/src/types/core-modules.ts index c0f3556..cba3559 100644 --- a/src/types/core-modules.ts +++ b/src/types/core-modules.ts @@ -104,7 +104,7 @@ export interface ModalSubmitCommand extends Module { } export interface AutocompleteCommand - extends Omit { + extends Omit { onEvent: ControlPlugin[]; execute: (ctx: AutocompleteInteraction) => Awaitable; } @@ -117,21 +117,21 @@ export interface DiscordEventCommand Awaitable; + execute: (ctx: Context) => Awaitable; } export interface SlashCommand extends Module { type: CommandType.Slash; description: string; options?: SernOptionsData[]; - execute: (ctx: Context, args: ['slash', SlashOptions]) => Awaitable; + execute: (ctx: Context) => Awaitable; } export interface BothCommand extends Module { type: CommandType.Both; description: string; options?: SernOptionsData[]; - execute: (ctx: Context, args: Args) => Awaitable; + execute: (ctx: Context) => Awaitable; } export type EventModule = DiscordEventCommand | SernEventCommand | ExternalEventCommand | CronEventCommand; diff --git a/src/types/core-plugin.ts b/src/types/core-plugin.ts index abf3651..398decb 100644 --- a/src/types/core-plugin.ts +++ b/src/types/core-plugin.ts @@ -11,7 +11,7 @@ * Plugins are reminiscent of middleware in express. */ -import type { Err, Ok } from 'ts-results-es'; +import type { Err, Ok, Result } from 'ts-results-es'; import type { BothCommand, ButtonCommand, @@ -33,7 +33,7 @@ import type { TextCommand, UserSelectCommand, } from './core-modules'; -import type { Args, Awaitable, Payload, SlashOptions, VoidResult } from './utility'; +import type { Args, Awaitable, Payload, SlashOptions } from './utility'; import type { CommandType, EventType, PluginType } from '../core/structures/enums' import type { Context } from '../core/structures/context' import type { @@ -49,11 +49,12 @@ import type { UserSelectMenuInteraction, } from 'discord.js'; -export type PluginResult = Awaitable; +export type PluginResult = Awaitable>; export interface InitArgs> { module: T; absPath: string; + updateModule: (module: Partial) => T } export interface Controller { next: () => Ok; @@ -73,8 +74,8 @@ export interface ControlPlugin { execute: (...args: Args) => PluginResult; } -export type AnyCommandPlugin = ControlPlugin | InitPlugin<[InitArgs>]>; -export type AnyEventPlugin = ControlPlugin | InitPlugin<[InitArgs>]>; +export type AnyCommandPlugin = ControlPlugin | InitPlugin<[InitArgs>]>; +export type AnyEventPlugin = ControlPlugin | InitPlugin<[InitArgs>]>; export type CommandArgs< I extends CommandType = CommandType, @@ -88,51 +89,51 @@ export type EventArgs< I extends EventType = EventType, interface CommandArgsMatrix { [CommandType.Text]: { [PluginType.Control]: [Context, ['text', string[]]]; - [PluginType.Init]: [InitArgs>]; + [PluginType.Init]: [InitArgs>]; }; [CommandType.Slash]: { [PluginType.Control]: [Context, ['slash', /* library coupled */ SlashOptions]]; - [PluginType.Init]: [InitArgs>]; + [PluginType.Init]: [InitArgs>]; }; [CommandType.Both]: { [PluginType.Control]: [Context, Args]; - [PluginType.Init]: [InitArgs>]; + [PluginType.Init]: [InitArgs>]; }; [CommandType.CtxMsg]: { [PluginType.Control]: [/* library coupled */ MessageContextMenuCommandInteraction]; - [PluginType.Init]: [InitArgs>]; + [PluginType.Init]: [InitArgs>]; }; [CommandType.CtxUser]: { [PluginType.Control]: [/* library coupled */ UserContextMenuCommandInteraction]; - [PluginType.Init]: [InitArgs>]; + [PluginType.Init]: [InitArgs>]; }; [CommandType.Button]: { [PluginType.Control]: [/* library coupled */ ButtonInteraction]; - [PluginType.Init]: [InitArgs>]; + [PluginType.Init]: [InitArgs>]; }; [CommandType.StringSelect]: { [PluginType.Control]: [/* library coupled */ StringSelectMenuInteraction]; - [PluginType.Init]: [InitArgs>]; + [PluginType.Init]: [InitArgs>]; }; [CommandType.RoleSelect]: { [PluginType.Control]: [/* library coupled */ RoleSelectMenuInteraction]; - [PluginType.Init]: [InitArgs>]; + [PluginType.Init]: [InitArgs>]; }; [CommandType.ChannelSelect]: { [PluginType.Control]: [/* library coupled */ ChannelSelectMenuInteraction]; - [PluginType.Init]: [InitArgs>]; + [PluginType.Init]: [InitArgs>]; }; [CommandType.MentionableSelect]: { [PluginType.Control]: [/* library coupled */ MentionableSelectMenuInteraction]; - [PluginType.Init]: [InitArgs>]; + [PluginType.Init]: [InitArgs>]; }; [CommandType.UserSelect]: { [PluginType.Control]: [/* library coupled */ UserSelectMenuInteraction]; - [PluginType.Init]: [InitArgs>]; + [PluginType.Init]: [InitArgs>]; }; [CommandType.Modal]: { [PluginType.Control]: [/* library coupled */ ModalSubmitInteraction]; - [PluginType.Init]: [InitArgs>]; + [PluginType.Init]: [InitArgs>]; }; }