Files
handler/src/core/functions.ts
Jacob Nguyen 0fbabea428 seems to work
2023-09-10 00:36:32 -05:00

84 lines
3.1 KiB
TypeScript

import { Err, Ok } from 'ts-results-es';
import { ApplicationCommandOptionType, AutocompleteInteraction } from 'discord.js';
import type { SernAutocompleteData, SernOptionsData } from '../types/core-modules';
import type { AnyCommandPlugin, AnyEventPlugin, Plugin } from '../types/core-plugin';
import { PluginType } from './structures';
import assert from 'assert';
//function wrappers for empty ok / err
export const ok = /* @__PURE__*/ () => Ok.EMPTY;
export const err = /* @__PURE__*/ () => Err.EMPTY;
export function partitionPlugins(
arr: (AnyEventPlugin | AnyCommandPlugin)[] = [],
): [Plugin[], Plugin[]] {
const controlPlugins = [];
const initPlugins = [];
for (const el of arr) {
switch (el.type) {
case PluginType.Control:
controlPlugins.push(el);
break;
case PluginType.Init:
initPlugins.push(el);
break;
}
}
return [controlPlugins, initPlugins];
}
/**
* Uses an iterative DFS to check if an autocomplete node exists on the option tree
* @param iAutocomplete
* @param options
*/
export function treeSearch(
iAutocomplete: AutocompleteInteraction,
options: SernOptionsData[] | undefined,
): SernAutocompleteData & { parent?: string } | undefined {
if (options === undefined) return undefined;
//clone to prevent mutation of original command module
const _options = options.map(a => ({ ...a }));
let subcommands = new Set();
while (_options.length > 0) {
const cur = _options.pop()!;
switch (cur.type) {
case ApplicationCommandOptionType.Subcommand:
{
subcommands.add(cur.name);
for (const option of cur.options ?? []) _options.push(option);
}
break;
case ApplicationCommandOptionType.SubcommandGroup:
{
for (const command of cur.options ?? []) _options.push(command);
}
break;
default:
{
if ('autocomplete' in cur && cur.autocomplete) {
const choice = iAutocomplete.options.getFocused(true);
assert(
'command' in cur,
'No command property found for autocomplete option',
);
if (subcommands.size > 0) {
const parent = iAutocomplete.options.getSubcommand();
const parentAndOptionMatches =
subcommands.has(parent) && cur.name === choice.name;
if (parentAndOptionMatches) {
return { ...cur, parent };
}
} else {
if (cur.name === choice.name) {
return { ...cur, parent: undefined };
}
}
}
}
break;
}
}
}