mirror of
https://github.com/sern-handler/handler
synced 2026-06-25 01:02:17 +00:00
refactor: Remove PluggedModule, change Module signature to support event plugins
This commit is contained in:
@@ -8,37 +8,39 @@ import type {
|
||||
import { concatMap, fromEvent, Observable, of, throwError } from 'rxjs';
|
||||
import type Wrapper from '../structures/wrapper';
|
||||
import * as Files from '../utilities/readFile';
|
||||
import { isEventPlugin } from './readyEvent';
|
||||
import { match, P } from 'ts-pattern';
|
||||
import { SernError } from '../structures/errors';
|
||||
import Context from '../structures/context';
|
||||
import type { Result } from 'ts-results';
|
||||
import type { PluggedModule } from '../structures/modules/module';
|
||||
import { CommandType, controller } from '../sern';
|
||||
import type { Args } from '../../types/handler';
|
||||
import type { MessageComponentInteraction } from 'discord.js';
|
||||
import { ComponentType } from 'discord.js';
|
||||
import type { UnionToTuple } from '../utilities/resolveParameters';
|
||||
import type { Module } from '../structures/modules/commands/module';
|
||||
import type { EventPlugin } from '../plugins/plugin';
|
||||
|
||||
|
||||
function isChatInputCommand(i : CommandInteraction) : i is ChatInputCommandInteraction {
|
||||
return i.isChatInputCommand();
|
||||
}
|
||||
function applicationCommandHandler(plugged: PluggedModule| undefined, interaction: CommandInteraction) {
|
||||
if (plugged === undefined) {
|
||||
function applicationCommandHandler(mod: Module | undefined, interaction: CommandInteraction) {
|
||||
if (mod === undefined) {
|
||||
return throwError(() => SernError.UndefinedModule);
|
||||
}
|
||||
const eventPlugins = plugged.plugins.filter(isEventPlugin);
|
||||
const eventPlugins = mod.onEvent;
|
||||
|
||||
return match(interaction)
|
||||
.when(isChatInputCommand, i => {
|
||||
const ctx = Context.wrap(i);
|
||||
const res = eventPlugins.map(e => {
|
||||
return e.execute(
|
||||
const res = eventPlugins.map(e => {
|
||||
return (<EventPlugin<CommandType.Both>>e).execute(
|
||||
[ctx, <Args>['slash', i.options]]
|
||||
, controller);
|
||||
}) as Awaited<Result<void, void>>[];
|
||||
//Possible unsafe cast
|
||||
// could result in the promises not being resolved
|
||||
return of({ type : plugged.mod.type, res, plugged, ctx });
|
||||
return of({ type : mod.type, res, plugged: mod, ctx });
|
||||
},
|
||||
)
|
||||
.when(
|
||||
@@ -50,20 +52,20 @@ function applicationCommandHandler(plugged: PluggedModule| undefined, interactio
|
||||
[ctx] as UnionToTuple<CommandType.MenuMsg | CommandType.MenuUser>
|
||||
, controller);
|
||||
}) as Awaited<Result<void, void>>[];
|
||||
return of({ type : plugged.mod.type, res, plugged, ctx });
|
||||
return of({ type : mod.type, res, plugged: mod, ctx });
|
||||
},
|
||||
)
|
||||
.run();
|
||||
}
|
||||
|
||||
function messageComponentInteractionHandler(
|
||||
plugged: PluggedModule | undefined,
|
||||
mod: Module | undefined,
|
||||
interaction: MessageComponentInteraction,
|
||||
) {
|
||||
if (plugged === undefined) {
|
||||
if (mod === undefined) {
|
||||
return throwError(() => SernError.UndefinedModule);
|
||||
}
|
||||
const eventPlugins = plugged.plugins.filter(isEventPlugin);
|
||||
const eventPlugins = mod.onEvent;
|
||||
return match(interaction)
|
||||
.with({
|
||||
componentType : P.union(ComponentType.Button, ComponentType.SelectMenu)
|
||||
@@ -71,7 +73,7 @@ function messageComponentInteractionHandler(
|
||||
const res = eventPlugins.map(e => {
|
||||
return e.execute([ctx] as UnionToTuple<CommandType.Button | CommandType.MenuSelect>, controller);
|
||||
}) as Awaited<Result<void, void>>[];
|
||||
return of({ type : plugged.mod.type, res, plugged, ctx });
|
||||
return of({ type : mod.type, res, plugged: mod, ctx });
|
||||
})
|
||||
.otherwise(() => throwError( () => SernError.NotSupportedInteraction) );
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ import type Wrapper from '../structures/wrapper';
|
||||
import { fmt } from '../utilities/messageHelpers';
|
||||
import * as Files from '../utilities/readFile';
|
||||
import { filterCorrectModule, ignoreNonBot } from './observableHandling';
|
||||
import { isEventPlugin } from './readyEvent';
|
||||
|
||||
export const onMessageCreate = (wrapper: Wrapper) => {
|
||||
const { client, defaultPrefix } = wrapper;
|
||||
@@ -40,25 +39,24 @@ export const onMessageCreate = (wrapper: Wrapper) => {
|
||||
);
|
||||
|
||||
const processEventPlugins$ = ensureModuleType$.pipe(
|
||||
concatMap(({ ctx, args, mod: plugged }) => {
|
||||
const eventPlugins = plugged.plugins.filter(isEventPlugin);
|
||||
concatMap(({ ctx, args, mod }) => {
|
||||
const res = Promise.all(
|
||||
eventPlugins.map(ePlug => {
|
||||
if ((ePlug.modType & plugged.mod.type) === 0) {
|
||||
mod.onEvent.map(ePlug => {
|
||||
if ((ePlug.modType & mod.type) === 0) {
|
||||
return Err.EMPTY;
|
||||
}
|
||||
return ePlug.execute([ctx, args], controller);
|
||||
}),
|
||||
);
|
||||
return from(res).pipe(map(res => ({ plugged, ctx, args, res })));
|
||||
return from(res).pipe(map(res => ({ mod, ctx, args, res })));
|
||||
}),
|
||||
);
|
||||
|
||||
processEventPlugins$.subscribe(({ plugged, ctx, args, res }) => {
|
||||
processEventPlugins$.subscribe(({ mod, ctx, args, res }) => {
|
||||
if (res.every(pl => pl.ok)) {
|
||||
Promise.resolve(plugged.mod.execute(ctx, args)).then(() => console.log(plugged));
|
||||
Promise.resolve(mod.execute(ctx, args)).then(() => console.log(mod));
|
||||
} else {
|
||||
console.log(plugged, 'failed');
|
||||
console.log(mod, 'failed');
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -3,25 +3,24 @@ import { Observable, throwError } from 'rxjs';
|
||||
import type { ModuleDefs } from '../structures/modules/commands/moduleHandler';
|
||||
import { SernError } from '../structures/errors';
|
||||
import { isNotFromBot } from '../utilities/messageHelpers';
|
||||
import type { PluggedModule } from '../structures/modules/module';
|
||||
import type { SernPlugin } from '../plugins/plugin';
|
||||
import type { Module } from '../structures/modules/commands/module';
|
||||
|
||||
export function correctModuleType<T extends keyof ModuleDefs>(
|
||||
plug: PluggedModule | undefined,
|
||||
plug: Module | undefined,
|
||||
type: T,
|
||||
): plug is { mod: ModuleDefs[T]; plugins: SernPlugin[] } {
|
||||
return plug !== undefined && plug.mod.type === type;
|
||||
): plug is ModuleDefs[T] {
|
||||
return plug !== undefined && plug.type === type;
|
||||
}
|
||||
|
||||
export function filterCorrectModule<T extends keyof ModuleDefs>(cmdType: T) {
|
||||
return (src: Observable<PluggedModule | undefined>) =>
|
||||
new Observable<{ mod: ModuleDefs[T]; plugins: SernPlugin[] }>(subscriber => {
|
||||
return (src: Observable<Module | undefined>) =>
|
||||
new Observable<ModuleDefs[T]>(subscriber => {
|
||||
return src.subscribe({
|
||||
next(plug) {
|
||||
if (correctModuleType(plug, cmdType)) {
|
||||
subscriber.next({ mod: plug.mod, plugins: plug.plugins });
|
||||
next(mod) {
|
||||
if (correctModuleType(mod, cmdType)) {
|
||||
subscriber.next(mod);
|
||||
} else {
|
||||
if (plug === undefined) {
|
||||
if (mod === undefined) {
|
||||
return throwError(() => SernError.UndefinedModule);
|
||||
}
|
||||
return throwError(() => SernError.MismatchModule);
|
||||
|
||||
@@ -9,28 +9,26 @@ import type {
|
||||
ModuleType,
|
||||
} from '../structures/modules/commands/moduleHandler';
|
||||
import { CommandType } from '../sern';
|
||||
import { CommandPlugin, EventPlugin, PluginType, SernPlugin } from '../plugins/plugin';
|
||||
import { partition } from '../utilities/partition';
|
||||
import type { PluginType } from '../plugins/plugin';
|
||||
import { Err, Ok, Result } from 'ts-results';
|
||||
import type { PluggedModule } from '../structures/modules/module';
|
||||
import type { Awaitable } from 'discord.js';
|
||||
import type { Module } from '../structures/modules/commands/module';
|
||||
|
||||
export const onReady = (wrapper: Wrapper) => {
|
||||
const { client, commands } = wrapper;
|
||||
const ready$ = fromEvent(client, 'ready').pipe(take(1), skip(1));
|
||||
const processCommandFiles$ = Files.buildData(commands).pipe(
|
||||
map(({ plugged, absPath }) => {
|
||||
const name = plugged.mod?.name ?? Files.fmtFileName(basename(absPath));
|
||||
if (plugged.mod?.name === undefined) {
|
||||
return { mod: { name, ...plugged.mod }, plugins: plugged.plugins };
|
||||
map(({ mod, absPath }) => {
|
||||
const name = mod?.name ?? Files.fmtFileName(basename(absPath));
|
||||
if (mod?.name === undefined) {
|
||||
return { name, ...mod } ;
|
||||
}
|
||||
return plugged;
|
||||
return mod;
|
||||
}),
|
||||
);
|
||||
const processPlugins$ = processCommandFiles$.pipe(
|
||||
concatMap(({ mod, plugins: allPlugins }) => {
|
||||
const [cmdPlugins, eventPlugins] = partition(isCmdPlugin, allPlugins);
|
||||
const cmdPluginsRes = cmdPlugins.map(plug => {
|
||||
concatMap(( mod ) => {
|
||||
const cmdPluginsRes = mod.plugins.map(plug => {
|
||||
return {
|
||||
...plug,
|
||||
name: plug?.name ?? 'Unnamed Plugin',
|
||||
@@ -40,13 +38,13 @@ export const onReady = (wrapper: Wrapper) => {
|
||||
}),
|
||||
};
|
||||
});
|
||||
return of({ plugged: <PluggedModule>{ mod, plugins: eventPlugins }, cmdPluginsRes });
|
||||
return of({ mod , cmdPluginsRes });
|
||||
}),
|
||||
);
|
||||
|
||||
(
|
||||
concat(ready$, processPlugins$) as Observable<{
|
||||
plugged: PluggedModule;
|
||||
mod: Module;
|
||||
cmdPluginsRes: {
|
||||
execute: Awaitable<Result<void, void>>;
|
||||
type: PluginType.Command;
|
||||
@@ -62,11 +60,10 @@ export const onReady = (wrapper: Wrapper) => {
|
||||
),
|
||||
),
|
||||
)
|
||||
.subscribe(({ plugged, cmdPluginsRes }) => {
|
||||
.subscribe(({ mod, cmdPluginsRes }) => {
|
||||
const loadedPluginsCorrectly = cmdPluginsRes.every(res => res.execute.ok);
|
||||
const { mod, plugins } = plugged;
|
||||
if (loadedPluginsCorrectly) {
|
||||
registerModule(mod.name!, mod, plugins);
|
||||
registerModule(mod.name!, mod);
|
||||
} else {
|
||||
console.log(`Failed to load command ${mod.name!}`);
|
||||
console.log(mod);
|
||||
@@ -76,40 +73,32 @@ export const onReady = (wrapper: Wrapper) => {
|
||||
|
||||
function handler(name: string): ModuleHandlers {
|
||||
return {
|
||||
[CommandType.Text]: (mod, plugins) => {
|
||||
mod.alias.forEach(a => Files.TextCommandStore.aliases.set(a, { mod, plugins }));
|
||||
Files.TextCommandStore.text.set(name, { mod, plugins });
|
||||
[CommandType.Text]: (mod) => {
|
||||
mod.alias.forEach(a => Files.TextCommandStore.aliases.set(a, mod));
|
||||
Files.TextCommandStore.text.set(name, mod);
|
||||
},
|
||||
[CommandType.Slash]: (mod, plugins) => {
|
||||
Files.ApplicationCommandStore[1].set(name, { mod, plugins });
|
||||
[CommandType.Slash]: (mod) => {
|
||||
Files.ApplicationCommandStore[1].set(name, mod);
|
||||
},
|
||||
[CommandType.Both]: (mod, plugins) => {
|
||||
Files.BothCommand.set(name, { mod, plugins });
|
||||
mod.alias.forEach(a => Files.TextCommandStore.aliases.set(a, { mod, plugins }));
|
||||
[CommandType.Both]: (mod) => {
|
||||
Files.BothCommand.set(name, mod);
|
||||
mod.alias.forEach(a => Files.TextCommandStore.aliases.set(a, mod));
|
||||
},
|
||||
[CommandType.MenuUser]: (mod, plugins) => {
|
||||
Files.ApplicationCommandStore[2].set(name, { mod, plugins });
|
||||
[CommandType.MenuUser]: (mod) => {
|
||||
Files.ApplicationCommandStore[2].set(name, mod);
|
||||
},
|
||||
[CommandType.MenuMsg]: (mod, plugins) => {
|
||||
Files.ApplicationCommandStore[3].set(name, { mod, plugins });
|
||||
[CommandType.MenuMsg]: (mod) => {
|
||||
Files.ApplicationCommandStore[3].set(name, mod);
|
||||
},
|
||||
[CommandType.Button]: (mod, plugins) => {
|
||||
Files.MessageCompCommandStore[2].set(name, { mod, plugins });
|
||||
[CommandType.Button]: (mod) => {
|
||||
Files.MessageCompCommandStore[2].set(name, mod);
|
||||
},
|
||||
[CommandType.MenuSelect]: (mod, plugins) => {
|
||||
Files.MessageCompCommandStore[2].set(name, { mod, plugins });
|
||||
[CommandType.MenuSelect]: (mod) => {
|
||||
Files.MessageCompCommandStore[2].set(name, mod);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function isCmdPlugin(p: SernPlugin): p is CommandPlugin {
|
||||
return (p.type & PluginType.Command) !== 0;
|
||||
}
|
||||
|
||||
export function isEventPlugin<T extends CommandType>(p: SernPlugin): p is EventPlugin {
|
||||
return (p.type & PluginType.Event) !== 0;
|
||||
}
|
||||
|
||||
function registerModule<T extends ModuleType>(name: string, mod: ModuleStates[T], plugins: SernPlugin[]) {
|
||||
return (<HandlerCallback<CommandType>>handler(name)[mod.type])(mod, plugins);
|
||||
function registerModule<T extends ModuleType>(name: string, mod: ModuleStates[T]) {
|
||||
return (<HandlerCallback<CommandType>>handler(name)[mod.type])(mod);
|
||||
}
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
// The goal of plugins is to organize commands and
|
||||
// provide extensions to repetitive patterns
|
||||
// examples include refreshing modules,
|
||||
// categorizing commands, cooldowns, permissions, etc
|
||||
// Plugins are reminisce of middleware in express.
|
||||
// categorizing commands, cooldowns, permissions, etc.
|
||||
// Plugins are reminiscent of middleware in express.
|
||||
//
|
||||
|
||||
import type { Awaitable, Client } from 'discord.js';
|
||||
@@ -16,7 +16,7 @@ import type { Err, Ok, Result } from 'ts-results';
|
||||
import type { Module, Override, Wrapper } from '../..';
|
||||
import type { CommandType } from '../sern';
|
||||
import type { ModuleDefs } from '../structures/modules/commands/moduleHandler';
|
||||
import type { BaseModule, PluggedModule } from '../structures/modules/module';
|
||||
import type { BaseModule } from '../structures/modules/module';
|
||||
|
||||
export enum PluginType {
|
||||
Command = 0b01,
|
||||
@@ -45,7 +45,7 @@ export type CommandPlugin = {
|
||||
|
||||
//TODO: rn adding the modType check a little hackish. Find better way to determine the
|
||||
// module type of the event plugin
|
||||
export type EventPlugin<T extends CommandType = CommandType> = {
|
||||
export type EventPlugin<T extends CommandType> = {
|
||||
type: PluginType.Event;
|
||||
modType: T;
|
||||
} & Override<
|
||||
@@ -54,16 +54,13 @@ export type EventPlugin<T extends CommandType = CommandType> = {
|
||||
execute: (event: Parameters<ModuleDefs[T]['execute']>, controller: Controller) => Awaitable<Result<void, void>>;
|
||||
}
|
||||
>;
|
||||
export function plugins(...plug: CommandPlugin[]) : CommandPlugin[];
|
||||
export function plugins<T extends CommandType>(...plug: EventPlugin<T>[]): EventPlugin<T>[];
|
||||
|
||||
export type SernPlugin = CommandPlugin | EventPlugin;
|
||||
|
||||
export function plugins(...plug: SernPlugin[]) {
|
||||
export function plugins<T extends CommandType>(...plug : CommandPlugin[] | EventPlugin<T>[]) {
|
||||
return plug;
|
||||
}
|
||||
|
||||
export function sernModule(plugins: SernPlugin[] , mod: Module): PluggedModule {
|
||||
return {
|
||||
mod,
|
||||
plugins,
|
||||
};
|
||||
export function sernModule(mod: Module): Module {
|
||||
return mod;
|
||||
}
|
||||
|
||||
@@ -9,37 +9,53 @@ import type { Override } from '../../../../types/handler';
|
||||
import type { CommandType } from '../../../sern';
|
||||
import type { BaseModule } from '../module';
|
||||
import type { UserContextMenuCommandInteraction } from 'discord.js';
|
||||
import type { CommandPlugin, EventPlugin } from '../../../plugins/plugin';
|
||||
|
||||
//possible refactoring to interfaces and not types
|
||||
//possible refactoring types into interfaces and not types
|
||||
export type TextCommand = {
|
||||
type: CommandType.Text;
|
||||
onEvent : EventPlugin<CommandType.Text>[];
|
||||
plugins : CommandPlugin[];
|
||||
alias: string[] | [];
|
||||
} & BaseModule;
|
||||
|
||||
export type SlashCommand = {
|
||||
type: CommandType.Slash;
|
||||
onEvent : EventPlugin<CommandType.Slash>[];
|
||||
plugins : CommandPlugin[];
|
||||
options: ApplicationCommandOptionData[] | [];
|
||||
} & BaseModule;
|
||||
|
||||
export type BothCommand = {
|
||||
type: CommandType.Both;
|
||||
onEvent : EventPlugin<CommandType.Both>[]
|
||||
plugins : CommandPlugin[]
|
||||
alias: string[] | [];
|
||||
options: ApplicationCommandOptionData[] | [];
|
||||
} & BaseModule;
|
||||
|
||||
export type ContextMenuUser = {
|
||||
type: CommandType.MenuUser;
|
||||
onEvent : EventPlugin<CommandType.MenuUser>[];
|
||||
plugins : CommandPlugin[];
|
||||
} & Override<BaseModule, { execute: (ctx: UserContextMenuCommandInteraction) => Awaitable<void> }>;
|
||||
|
||||
export type ContextMenuMsg = {
|
||||
type: CommandType.MenuMsg;
|
||||
onEvent : EventPlugin<CommandType.MenuUser>[];
|
||||
plugins : CommandPlugin[];
|
||||
} & Override<BaseModule, { execute: (ctx: MessageContextMenuCommandInteraction) => Awaitable<void> }>;
|
||||
|
||||
export type ButtonCommand = {
|
||||
type: CommandType.Button;
|
||||
onEvent : EventPlugin<CommandType.Button>[];
|
||||
plugins : CommandPlugin[];
|
||||
} & Override<BaseModule, { execute: (ctx: ButtonInteraction) => Awaitable<void> }>;
|
||||
|
||||
export type SelectMenuCommand = {
|
||||
type: CommandType.MenuSelect;
|
||||
onEvent : EventPlugin<CommandType.MenuSelect>[];
|
||||
plugins :CommandPlugin[];
|
||||
} & Override<BaseModule, { execute: (ctx: SelectMenuInteraction) => Awaitable<void> }>;
|
||||
|
||||
export type Module =
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import type { SernPlugin } from '../../../plugins/plugin';
|
||||
import { CommandType } from '../../../sern';
|
||||
import type {
|
||||
BothCommand,
|
||||
@@ -28,6 +27,6 @@ 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> = (mod: ModuleStates[K], plugins: SernPlugin[]) => unknown;
|
||||
export type HandlerCallback<K extends ModuleType> = (mod: ModuleStates[K]) => unknown;
|
||||
//An object that acts as the mapped object to handler
|
||||
export type ModuleHandlers = { [K in ModuleType]: HandlerCallback<K> };
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import type { Awaitable } from 'discord.js';
|
||||
import type { Args, Module } from '../../..';
|
||||
import type { SernPlugin } from '../../plugins/plugin';
|
||||
import type { Args } from '../../..';
|
||||
import type Context from '../context';
|
||||
|
||||
export interface BaseModule {
|
||||
@@ -8,8 +7,3 @@ export interface BaseModule {
|
||||
description: string;
|
||||
execute: (ctx: Context, args: Args) => Awaitable<void>;
|
||||
}
|
||||
|
||||
export interface PluggedModule {
|
||||
mod: Module;
|
||||
plugins: SernPlugin[];
|
||||
}
|
||||
|
||||
@@ -2,23 +2,23 @@ import { ApplicationCommandType, ComponentType } from 'discord.js';
|
||||
import { readdirSync, statSync } from 'fs';
|
||||
import { join } from 'path';
|
||||
import { from, Observable } from 'rxjs';
|
||||
import type { PluggedModule } from '../structures/modules/module';
|
||||
import type { Module } from '../structures/modules/commands/module';
|
||||
|
||||
export const BothCommand = new Map<string, PluggedModule>();
|
||||
export const BothCommand = new Map<string, Module>();
|
||||
export const ApplicationCommandStore = {
|
||||
[ApplicationCommandType.User]: new Map<string, PluggedModule>(),
|
||||
[ApplicationCommandType.Message]: new Map<string, PluggedModule>(),
|
||||
[ApplicationCommandType.ChatInput]: new Map<string, PluggedModule>(),
|
||||
} as { [K in ApplicationCommandType]: Map<string, PluggedModule> };
|
||||
[ApplicationCommandType.User]: new Map<string, Module>(),
|
||||
[ApplicationCommandType.Message]: new Map<string, Module>(),
|
||||
[ApplicationCommandType.ChatInput]: new Map<string, Module>(),
|
||||
} as { [K in ApplicationCommandType]: Map<string, Module> };
|
||||
|
||||
export const MessageCompCommandStore = {
|
||||
[ComponentType.Button]: new Map<string, PluggedModule>(),
|
||||
[ComponentType.SelectMenu]: new Map<string, PluggedModule>(),
|
||||
[ComponentType.TextInput] : new Map<string, PluggedModule>()
|
||||
[ComponentType.Button]: new Map<string, Module>(),
|
||||
[ComponentType.SelectMenu]: new Map<string, Module>(),
|
||||
[ComponentType.TextInput] : new Map<string, Module>()
|
||||
};
|
||||
export const TextCommandStore = {
|
||||
text: new Map<string, PluggedModule>(),
|
||||
aliases: new Map<string, PluggedModule>(),
|
||||
text: new Map<string, Module>(),
|
||||
aliases: new Map<string, Module>(),
|
||||
};
|
||||
|
||||
// Courtesy @Townsy45
|
||||
@@ -40,19 +40,19 @@ export const fmtFileName = (n: string) => n.substring(0, n.length - 3);
|
||||
|
||||
/**
|
||||
*
|
||||
* @returns {Observable<{ mod: PluggedModule; absPath: string; }[]>} data from command files
|
||||
* @returns {Observable<{ mod: Module; absPath: string; }[]>} data from command files
|
||||
* @param commandDir
|
||||
*/
|
||||
|
||||
export function buildData(commandDir: string): Observable<{
|
||||
plugged: PluggedModule;
|
||||
mod: Module;
|
||||
absPath: string;
|
||||
}> {
|
||||
return from(
|
||||
getCommands(commandDir).map(absPath => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const plugged = <PluggedModule>require(absPath).module;
|
||||
return { plugged, absPath };
|
||||
const mod = <Module>require(absPath).module;
|
||||
return { mod, absPath };
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user