chore: move commands into seperate file

This commit is contained in:
Jacob Nguyen
2023-05-03 21:04:10 -05:00
parent cae1f648f0
commit aacf47efab
2 changed files with 134 additions and 103 deletions

109
src/commands.ts Normal file
View File

@@ -0,0 +1,109 @@
import { ClientEvents } from "discord.js";
import { CommandType, EventType, PluginType } from "./core/structures";
import { AnyEventPlugin, ControlPlugin, InitPlugin, Plugin } from "./types/plugin";
import { Awaitable } from "./types/handler";
import { CommandModule, CommandModuleDefs, EventModule, EventModuleDefs, InputCommand, InputEvent } from "./types/module";
import { partition } from "./core/functions";
import { filename, filePath } from "./core/module-loading";
import { fileURLToPath } from "url";
export const sernMeta = Symbol('@sern/meta')
/*
* Generates a number based on CommandType.
* This corresponds to an ApplicationCommandType or ComponentType
* TextCommands are 0 as they aren't either or.
*/
function apiType(t: CommandType) {
if(t === CommandType.Both || t === CommandType.Modal) return 1;
return Math.log2(t) - 2;
}
/*
* Generates an id based on CommandType.
* A is for any ApplicationCommand. C is for any ComponentCommand
* Then, another number generated by apiType function is appended
*/
function uniqueId(t: CommandType) {
const appBitField = 0b000000011111;
const am = ((appBitField & t) !== 0) ? 'A' : 'C';
return am+apiType(t);
}
/**
* @since 1.0.0 The wrapper function to define command modules for sern
* @param mod
*/
export function commandModule(mod: InputCommand): CommandModule {
const [onEvent, plugins] = partition(
mod.plugins ?? [],
el => (el as Plugin).type === PluginType.Control,
);
const path = filePath()
const name = mod.name ?? filename(path)
return {
...mod,
name,
onEvent,
plugins,
[sernMeta]: {
id: `${name}__${uniqueId(mod.type)}`,
fullPath: fileURLToPath(path),
}
} as CommandModule;
}
/**
* @since 1.0.0
* The wrapper function to define event modules for sern
* @param mod
*/
export function eventModule(mod: InputEvent): EventModule {
const [onEvent, plugins] = partition(
mod.plugins ?? [],
el => (el as Plugin).type === PluginType.Control,
);
const path = filePath();
return {
...mod,
name: mod.name ?? filename(path),
onEvent,
plugins,
[sernMeta]: {
id: 'string'
}
} as EventModule;
}
/**
* Create event modules from discord.js client events,
* This is an {@link eventModule} for discord events,
* where typings can be very bad.
* @param mod
*/
export function discordEvent<T extends keyof ClientEvents>(mod: {
name: T;
plugins?: AnyEventPlugin[];
execute: (...args: ClientEvents[T]) => Awaitable<unknown>;
}) {
return eventModule({ type: EventType.Discord, ...mod });
}
/**
* @Experimental
* Will be refactored / changed in future
*/
export abstract class CommandExecutable<Type extends CommandType> {
abstract type: Type;
plugins: InitPlugin[] = [];
onEvent: ControlPlugin[] = [];
abstract execute: CommandModuleDefs[Type]['execute'];
}
/**
* @Experimental
* Will be refactored in future
*/
export abstract class EventExecutable<Type extends EventType> {
abstract type: Type;
plugins: InitPlugin[] = [];
onEvent: ControlPlugin[] = [];
abstract execute: EventModuleDefs[Type]['execute'];
}

View File

@@ -1,24 +1,12 @@
import { Wrapper, CommandType, EventType, PluginType } from '../core/structures';
import { DispatchType } from '../core/platform';
import { makeEventsHandler } from './events/userDefinedEventsHandling';
import { AnyEventPlugin, ControlPlugin, InitPlugin, type Plugin } from '../types/plugin';
import { makeInteractionCreate } from './events/interactionHandler';
import { makeReadyEvent } from './events/readyHandler';
import { makeMessageCreate } from './events/messageHandler';
import type {
CommandModule,
CommandModuleDefs,
EventModule,
EventModuleDefs,
InputCommand,
InputEvent,
} from '../types/module';
import type { AnyDependencies, Dependencies, DependencyConfiguration } from '../types/handler';
import { composeRoot, makeFetcher, useContainer } from '../core/dependencies/provider';
import type { Logging } from '../core/contracts';
import { err, ok, partition } from '../core/utilities/functions';
import type { Awaitable, ClientEvents } from 'discord.js';
import { AnyWrapper, isServerless } from '../core/structures/wrapper';
import { makeEventsHandler } from './events/userDefined';
import { makeInteractionCreate } from './events/interactions';
import { makeReadyEvent } from './events/ready';
import { makeMessageCreate } from './events/messages';
import type { AnyDependencies, DependencyConfiguration } from '../types/handler';
import { composeRoot, makeFetcher, useContainer } from '../core/dependencies';
import { err, ok } from '../core/functions';
import { DefaultWrapper } from '../core/structures/wrapper';
import { discordjs } from '../core';
/**
* @since 1.0.0
* @param wrapper Options to pass into sern.
@@ -26,7 +14,7 @@ import { AnyWrapper, isServerless } from '../core/structures/wrapper';
* @example
* ```ts title="src/index.ts"
* Sern.init({
* defaultPrefix: '!',
* platform: djs('!'),
* commands: 'dist/commands',
* events: 'dist/events',
* containerConfig : {
@@ -35,25 +23,22 @@ import { AnyWrapper, isServerless } from '../core/structures/wrapper';
* })
* ```
*/
export function init(wrapper: AnyWrapper) {
const logger = wrapper.containerConfig.get('@sern/logger')[0] as Logging | undefined;
const requiredDependenciesAnd = makeFetcher(wrapper);
export function init(wrapper: DefaultWrapper) {
const dependenciesAnd = makeFetcher(wrapper.containerConfig);
const startTime = performance.now();
if(isServerless(wrapper)) {
} else {
const dependencies = requiredDependenciesAnd(['@sern/modules']);
const { events } = wrapper;
if (events !== undefined) {
makeEventsHandler(requiredDependenciesAnd([]), events, wrapper.containerConfig);
}
makeReadyEvent(dependencies, wrapper.commands);
makeMessageCreate(dependencies, wrapper?.defaultPrefix ?? wrapper.platform.defaultPrefix);
makeInteractionCreate(dependencies);
const endTime = performance.now();
logger?.info({ message: `sern : ${(endTime - startTime).toFixed(2)} ms` });
const dependencies = dependenciesAnd(['@sern/modules', '@sern/client']);
if (wrapper.events !== undefined) {
makeEventsHandler(
dependenciesAnd(['@sern/client']), wrapper.events, wrapper.containerConfig
);
}
const platform = discordjs(wrapper.defaultPrefix);
makeReadyEvent(dependencies, wrapper.commands, platform);
makeMessageCreate(dependencies, platform);
makeInteractionCreate(dependencies, platform);
const endTime = performance.now();
dependencies[2]?.info({ message: `sern : ${(endTime - startTime).toFixed(2)} ms` });
}
/**
@@ -65,51 +50,7 @@ export const controller = {
stop: err,
};
/**
* @since 1.0.0 The wrapper function to define command modules for sern
* @param mod
*/
export function commandModule(mod: InputCommand): CommandModule {
const [onEvent, plugins] = partition(
mod.plugins ?? [],
el => (el as Plugin).type === PluginType.Control,
);
return {
...mod,
onEvent,
plugins,
} as CommandModule;
}
/**
* @since 1.0.0
* The wrapper function to define event modules for sern
* @param mod
*/
export function eventModule(mod: InputEvent): EventModule {
const [onEvent, plugins] = partition(
mod.plugins ?? [],
el => (el as Plugin).type === PluginType.Control,
);
return {
...mod,
onEvent,
plugins,
} as EventModule;
}
/**
* Create event modules from discord.js client events,
* This is an {@link eventModule} for discord events,
* where typings can be very bad.
* @param mod
*/
export function discordEvent<T extends keyof ClientEvents>(mod: {
name: T;
plugins?: AnyEventPlugin[];
execute: (...args: ClientEvents[T]) => Awaitable<unknown>;
}) {
return eventModule({ type: EventType.Discord, ...mod });
}
/**
* @since 2.0.0
* @param conf a configuration for creating your project dependencies
@@ -120,23 +61,4 @@ export function makeDependencies<const T extends AnyDependencies>(conf: Dependen
return useContainer<T>();
}
/**
* @Experimental
* Will be refactored / changed in future
*/
export abstract class CommandExecutable<Type extends CommandType> {
abstract type: Type;
plugins: InitPlugin[] = [];
onEvent: ControlPlugin[] = [];
abstract execute: CommandModuleDefs[Type]['execute'];
}
/**
* @Experimental
* Will be refactored in future
*/
export abstract class EventExecutable<Type extends EventType> {
abstract type: Type;
plugins: InitPlugin[] = [];
onEvent: ControlPlugin[] = [];
abstract execute: EventModuleDefs[Type]['execute'];
}