mirror of
https://github.com/sern-handler/handler
synced 2026-06-06 01:16:55 +00:00
93 lines
2.7 KiB
TypeScript
93 lines
2.7 KiB
TypeScript
import { ClientEvents } from 'discord.js';
|
|
import { CommandType, EventType, PluginType } from './core/structures';
|
|
import { AnyEventPlugin, Plugin } from './types/plugin';
|
|
import { CommandModule, EventModule, InputCommand, InputEvent } from './types/module';
|
|
import { partition } from './core/functions';
|
|
import { filename, filePath } from './core/module-loading';
|
|
import { Awaitable } from './types/handler';
|
|
export const sernMeta = Symbol('@sern/meta');
|
|
const appBitField = 0b000000011111;
|
|
/*
|
|
* 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;
|
|
const log = Math.log2(t);
|
|
return (appBitField & t) !== 0 ? log : log - 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 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 fullPath = filePath();
|
|
const name = mod.name ?? filename(fullPath);
|
|
return {
|
|
...mod,
|
|
description: mod.description ?? '...',
|
|
name,
|
|
onEvent,
|
|
plugins,
|
|
[sernMeta]: {
|
|
id: `${name}__${uniqueId(mod.type)}`,
|
|
fullPath,
|
|
},
|
|
} 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 fullPath = filePath();
|
|
return {
|
|
name: mod.name ?? filename(fullPath),
|
|
onEvent,
|
|
plugins,
|
|
[sernMeta]: {
|
|
id: 'no-id',
|
|
fullPath,
|
|
},
|
|
...mod,
|
|
} as EventModule;
|
|
}
|
|
|
|
/** Create event modules from discord.js client events,
|
|
* This is an {@link eventModule} for discord events,
|
|
* where typings can be very bad.
|
|
* @Experimental
|
|
* @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,
|
|
});
|
|
}
|