diff --git a/src/commands.ts b/src/commands.ts new file mode 100644 index 0000000..b311640 --- /dev/null +++ b/src/commands.ts @@ -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(mod: { + name: T; + plugins?: AnyEventPlugin[]; + execute: (...args: ClientEvents[T]) => Awaitable; +}) { + return eventModule({ type: EventType.Discord, ...mod }); +} + + +/** + * @Experimental + * Will be refactored / changed in future + */ +export abstract class CommandExecutable { + abstract type: Type; + plugins: InitPlugin[] = []; + onEvent: ControlPlugin[] = []; + abstract execute: CommandModuleDefs[Type]['execute']; +} +/** + * @Experimental + * Will be refactored in future + */ +export abstract class EventExecutable { + abstract type: Type; + plugins: InitPlugin[] = []; + onEvent: ControlPlugin[] = []; + abstract execute: EventModuleDefs[Type]['execute']; +} diff --git a/src/handler/sern.ts b/src/handler/sern.ts index 65a109e..7e6a749 100644 --- a/src/handler/sern.ts +++ b/src/handler/sern.ts @@ -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(mod: { - name: T; - plugins?: AnyEventPlugin[]; - execute: (...args: ClientEvents[T]) => Awaitable; -}) { - 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(conf: Dependen return useContainer(); } -/** - * @Experimental - * Will be refactored / changed in future - */ -export abstract class CommandExecutable { - abstract type: Type; - plugins: InitPlugin[] = []; - onEvent: ControlPlugin[] = []; - abstract execute: CommandModuleDefs[Type]['execute']; -} -/** - * @Experimental - * Will be refactored in future - */ -export abstract class EventExecutable { - abstract type: Type; - plugins: InitPlugin[] = []; - onEvent: ControlPlugin[] = []; - abstract execute: EventModuleDefs[Type]['execute']; -} +