mirror of
https://github.com/sern-handler/handler
synced 2026-06-19 22:32:14 +00:00
update locals api, docs, tests
This commit is contained in:
@@ -14,11 +14,10 @@ import type { Awaitable } from '../types/utility';
|
||||
*/
|
||||
export function commandModule(mod: InputCommand): Module {
|
||||
const [onEvent, plugins] = partitionPlugins(mod.plugins);
|
||||
return {
|
||||
...mod,
|
||||
onEvent,
|
||||
plugins,
|
||||
} as Module;
|
||||
return { ...mod,
|
||||
onEvent,
|
||||
plugins,
|
||||
locals: {} } as Module;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -29,7 +28,9 @@ export function commandModule(mod: InputCommand): Module {
|
||||
export function eventModule(mod: InputEvent): Module {
|
||||
const [onEvent, plugins] = partitionPlugins(mod.plugins);
|
||||
if(onEvent.length !== 0) throw Error("Event modules cannot have ControlPlugins");
|
||||
return { ...mod, plugins } as Module;
|
||||
return { ...mod,
|
||||
plugins,
|
||||
locals: {} } as Module;
|
||||
}
|
||||
|
||||
/** Create event modules from discord.js client events,
|
||||
|
||||
@@ -17,6 +17,7 @@ import { CommandType } from '../core/structures/enums'
|
||||
import { inspect } from 'node:util'
|
||||
import { disposeAll } from '../core/ioc';
|
||||
import { resultPayload, isAutocomplete, treeSearch, fmt } from '../core/functions'
|
||||
import merge from 'deepmerge'
|
||||
|
||||
function handleError<C>(crashHandler: ErrorHandling, emitter: Emitter, logging?: Logging) {
|
||||
return (pload: unknown, caught: Observable<C>) => {
|
||||
@@ -213,25 +214,26 @@ export function createResultResolver<Output>(config: {
|
||||
};
|
||||
};
|
||||
|
||||
export async function callInitPlugins(module: Module, deps: Dependencies, emit?: boolean) {
|
||||
let _module = module;
|
||||
function isObject(item: unknown) {
|
||||
return (item && typeof item === 'object' && !Array.isArray(item));
|
||||
}
|
||||
|
||||
//_module is frozen, preventing from mutations
|
||||
export async function callInitPlugins(_module: Module, deps: Dependencies, emit?: boolean) {
|
||||
let module = _module;
|
||||
const emitter = deps['@sern/emitter'];
|
||||
for(const plugin of _module.plugins ?? []) {
|
||||
const res = await plugin.execute({
|
||||
module: _module,
|
||||
absPath: _module.meta.absPath,
|
||||
deps
|
||||
});
|
||||
if (!res) throw Error("Plugin did not return anything. " + inspect(plugin, false, Infinity, true));
|
||||
if(res.isErr()) {
|
||||
for(const plugin of module.plugins ?? []) {
|
||||
const result = await plugin.execute({ module, absPath: module.meta.absPath, deps });
|
||||
if (!result) throw Error("Plugin did not return anything. " + inspect(plugin, false, Infinity, true));
|
||||
if(result.isErr()) {
|
||||
if(emit) {
|
||||
emitter?.emit('module.register',
|
||||
resultPayload('failure', module, res.error ?? SernError.PluginFailure));
|
||||
resultPayload('failure', module, result.error ?? SernError.PluginFailure));
|
||||
}
|
||||
throw Error(res.error ?? SernError.PluginFailure);
|
||||
throw Error(result.error ?? SernError.PluginFailure);
|
||||
}
|
||||
}
|
||||
return _module
|
||||
return module
|
||||
}
|
||||
|
||||
async function callPlugins({ args, module, deps, params }: ExecutePayload) {
|
||||
@@ -241,8 +243,8 @@ async function callPlugins({ args, module, deps, params }: ExecutePayload) {
|
||||
if(result.isErr()) {
|
||||
return result;
|
||||
}
|
||||
if(typeof result.value === 'object' && result.value !== null) {
|
||||
state = { ...state, ...result.value, };
|
||||
if(isObject(result.value)) {
|
||||
state = merge(state, result.value!);
|
||||
}
|
||||
}
|
||||
return Ok(state);
|
||||
|
||||
@@ -23,8 +23,8 @@ export default async function(dir: string, deps : UnpackedDependencies) {
|
||||
if(!validType) {
|
||||
throw Error(`Found ${module.name} at ${module.meta.absPath}, which has incorrect \`type\``);
|
||||
}
|
||||
const resultModule = await callInitPlugins(module, deps, true);
|
||||
// FREEZE! no more writing!!
|
||||
const resultModule = await callInitPlugins(module, deps, true); // FREEZE! no more writing!!
|
||||
|
||||
commands.set(resultModule.meta.id, Object.freeze(resultModule));
|
||||
sEmitter.emit('module.register', resultPayload('success', resultModule));
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ import type {
|
||||
} from 'discord.js';
|
||||
import type { CommandType, EventType } from '../core/structures/enums';
|
||||
import { Context } from '../core/structures/context'
|
||||
import { AnyPlugin, ControlPlugin, InitPlugin } from './core-plugin';
|
||||
import { ControlPlugin, InitPlugin, Plugin } from './core-plugin';
|
||||
import { Awaitable, SernEventsMapping } from './utility';
|
||||
|
||||
//state, deps, type (very original)
|
||||
@@ -41,6 +41,7 @@ export interface Module {
|
||||
id: string;
|
||||
absPath: string;
|
||||
}
|
||||
locals: Record<string,unknown>
|
||||
execute(...args: any[]): Awaitable<any>;
|
||||
}
|
||||
|
||||
@@ -191,10 +192,10 @@ export interface SernAutocompleteData
|
||||
}
|
||||
|
||||
type CommandModuleNoPlugins = {
|
||||
[T in CommandType]: Omit<CommandModuleDefs[T], 'plugins' | 'onEvent' | 'meta'>;
|
||||
[T in CommandType]: Omit<CommandModuleDefs[T], 'plugins' | 'onEvent' | 'meta' | 'locals'>;
|
||||
};
|
||||
type EventModulesNoPlugins = {
|
||||
[T in EventType]: Omit<EventModuleDefs[T], 'plugins' | 'onEvent' | 'meta'> ;
|
||||
[T in EventType]: Omit<EventModuleDefs[T], 'plugins' | 'onEvent' | 'meta' | 'locals'> ;
|
||||
};
|
||||
|
||||
export type InputEvent = {
|
||||
@@ -206,7 +207,7 @@ export type InputEvent = {
|
||||
|
||||
export type InputCommand = {
|
||||
[T in CommandType]: CommandModuleNoPlugins[T] & {
|
||||
plugins?: AnyPlugin[];
|
||||
plugins?: Plugin[];
|
||||
};
|
||||
}[CommandType];
|
||||
|
||||
|
||||
@@ -33,7 +33,6 @@ import type {
|
||||
} from 'discord.js';
|
||||
|
||||
export type PluginResult = Awaitable<Result<Record<string,unknown>|undefined, string|undefined>>;
|
||||
|
||||
export interface InitArgs<T extends Processed<Module> = Processed<Module>> {
|
||||
module: T;
|
||||
absPath: string;
|
||||
@@ -46,6 +45,7 @@ export interface Plugin<Args extends any[] = any[]> {
|
||||
|
||||
export interface InitPlugin<Args extends any[] = any[]> extends Plugin<Args> {
|
||||
type: PluginType.Init;
|
||||
execute: (...args: Args) => PluginResult;
|
||||
}
|
||||
export interface ControlPlugin<Args extends any[] = any[]> extends Plugin<Args> {
|
||||
type: PluginType.Control;
|
||||
|
||||
15
src/types/dependencies.d.ts
vendored
15
src/types/dependencies.d.ts
vendored
@@ -7,6 +7,21 @@
|
||||
import { CoreDependencies } from './ioc';
|
||||
|
||||
declare global {
|
||||
/**
|
||||
* discord.js client.
|
||||
* '@sern/client': Client
|
||||
* sern emitter listens to events that happen throughout
|
||||
* the handler. some include module.register, module.activate.
|
||||
* '@sern/emitter': Contracts.Emitter;
|
||||
* An error handler which is the final step before
|
||||
* the sern process actually crashes.
|
||||
'@sern/errors': Contracts.ErrorHandling;
|
||||
* Optional logger. Performs ... logging
|
||||
* '@sern/logger'?: Contracts.Logging;
|
||||
* Readonly module store. sern stores these
|
||||
* by module.meta.id -> Module
|
||||
* '@sern/modules': Map<string, Module>;
|
||||
*/
|
||||
interface Dependencies extends CoreDependencies {}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,10 +6,28 @@ import { Module } from './core-modules';
|
||||
|
||||
|
||||
export interface CoreDependencies {
|
||||
/**
|
||||
* discord.js client.
|
||||
*/
|
||||
'@sern/client': Client;
|
||||
/**
|
||||
* sern emitter listens to events that happen throughout
|
||||
* the handler. some include module.register, module.activate.
|
||||
*/
|
||||
'@sern/emitter': Contracts.Emitter;
|
||||
/**
|
||||
* An error handler which is the final step before
|
||||
* the sern process actually crashes.
|
||||
*/
|
||||
'@sern/errors': Contracts.ErrorHandling;
|
||||
/**
|
||||
* Optional logger. Performs ... logging
|
||||
*/
|
||||
'@sern/logger'?: Contracts.Logging;
|
||||
/**
|
||||
* Readonly module store. sern stores these
|
||||
* by module.meta.id -> Module
|
||||
*/
|
||||
'@sern/modules': Map<string, Module>;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user