chore: prettier reformat

This commit is contained in:
jacoobes
2022-05-13 14:45:06 -05:00
parent 88dcdee818
commit 3dedba3493
9 changed files with 663 additions and 613 deletions

View File

@@ -9,141 +9,140 @@ import type {
ReplyMessageOptions,
Snowflake,
TextBasedChannel,
User
User,
} from 'discord.js';
import { None, Option, Some } from 'ts-results';
import type { Nullish } from '../../types/handler';
function firstSome<T>(...args : Option<T>[]) : Nullish<T> {
for ( const op of args ) {
function firstSome<T>(...args: Option<T>[]): Nullish<T> {
for (const op of args) {
if (op.some) return op.val;
}
return null;
}
//
//Will need refactoring after applying context in practice
//
export default class Context {
private constructor(
private oMsg: Option<Message> = None,
private oInterac: Option<ChatInputCommandInteraction> = None
private oInterac: Option<ChatInputCommandInteraction> = None,
) {
this.oMsg = oMsg;
this.oInterac = oInterac;
}
static wrap(
wrappable: ChatInputCommandInteraction|Message
) : Context {
if ( 'token' in wrappable ) {
return new Context( None, Some(wrappable));
static wrap(wrappable: ChatInputCommandInteraction | Message): Context {
if ('token' in wrappable) {
return new Context(None, Some(wrappable));
}
return new Context(Some(wrappable), None);
}
public isEmpty() {
return this.oMsg.none && this.oInterac.none;
}
public get message() {
public get message() {
return this.oMsg.unwrap();
}
public get interaction() {
return this.oInterac.unwrap();
}
public get id() : Snowflake {
return firstSome(
this.oInterac.map( i => i.id),
this.oMsg.map(m => m.id)
)!;
}
public get channel() : Nullish<TextBasedChannel> {
return firstSome(
this.oMsg.map(m => m.channel),
this.oInterac.map(i => i.channel)
);
}
public get user(): User {
public get id(): Snowflake {
return firstSome(
this.oMsg.map(m => m.author),
this.oInterac.map(i => i.user)
)!;
}
public get createdTimestamp() : number {
return firstSome(
this.oMsg.map(m => m.createdTimestamp),
this.oInterac.map(i => i.createdTimestamp)
this.oInterac.map(i => i.id),
this.oMsg.map(m => m.id),
)!;
}
public get guild() : Guild {
public get channel(): Nullish<TextBasedChannel> {
return firstSome(
this.oMsg.map(m => m.guild),
this.oInterac.map(i => i.guild)
this.oMsg.map(m => m.channel),
this.oInterac.map(i => i.channel),
);
}
public get user(): User {
return firstSome(
this.oMsg.map(m => m.author),
this.oInterac.map(i => i.user),
)!;
}
public get guildId() : Snowflake {
public get createdTimestamp(): number {
return firstSome(
this.oMsg.map(m => m.guildId),
this.oInterac.map(i => i.guildId)
)!;
this.oMsg.map(m => m.createdTimestamp),
this.oInterac.map(i => i.createdTimestamp),
)!;
}
public get guild(): Guild {
return firstSome(
this.oMsg.map(m => m.guild),
this.oInterac.map(i => i.guild),
)!;
}
public get guildId(): Snowflake {
return firstSome(
this.oMsg.map(m => m.guildId),
this.oInterac.map(i => i.guildId),
)!;
}
/*
* interactions can return APIGuildMember if the guild it is emitted from is not cached
*/
public get member() : Nullish<GuildMember|APIGuildMember> {
return firstSome(
this.oMsg.map(m => m.member),
this.oInterac.map(i => i.member)
);
*/
public get member(): Nullish<GuildMember | APIGuildMember> {
return firstSome(
this.oMsg.map(m => m.member),
this.oInterac.map(i => i.member),
);
}
/*
* Returns the underlying Context but allows for doing other operations
*/
public onInteraction(
onInteraction : ( interaction : ChatInputCommandInteraction ) => Awaitable<void>,
): Context {
if (this.oInterac.some) {
onInteraction(this.oInterac.val);
return Context.wrap(this.oInterac.val);
}
return this;
public onInteraction(onInteraction: (interaction: ChatInputCommandInteraction) => Awaitable<void>): Context {
if (this.oInterac.some) {
onInteraction(this.oInterac.val);
return Context.wrap(this.oInterac.val);
}
return this;
}
public onMessage(
onMessage : ( message : Message ) => Awaitable<void>
): Context {
if (this.oMsg.some) {
onMessage(this.oMsg.val);
return Context.wrap(this.oMsg.val);
}
return this;
public onMessage(onMessage: (message: Message) => Awaitable<void>): Context {
if (this.oMsg.some) {
onMessage(this.oMsg.val);
return Context.wrap(this.oMsg.val);
}
return this;
}
public takeInteractionValue<T>(
extract : (interaction : ChatInputCommandInteraction) => T
): Nullish<T> {
if(this.oInterac.none) return null;
return extract(this.oInterac.val);
}
public takeMessageValue<T>(
extract : (message: Message) => T
): Nullish<T> {
if(this.oMsg.none) return null;
return extract(this.oMsg.val);
}
public takeInteractionValue<T>(extract: (interaction: ChatInputCommandInteraction) => T): Nullish<T> {
if (this.oInterac.none) return null;
return extract(this.oInterac.val);
}
public reply(
content : Omit<InteractionReplyOptions, 'fetchReply'> | ReplyMessageOptions
): Promise<Context> {
return firstSome(
this.oInterac.map(async i => {
await i.reply( content as InteractionReplyOptions);
return new Context(Some(await i.fetchReply() as Message), Some(i));
}),
this.oMsg.map(async m => {
const reply = await m.reply( content as ReplyMessageOptions );
return new Context(Some(reply), this.oInterac);
})
)!;
}
public takeMessageValue<T>(extract: (message: Message) => T): Nullish<T> {
if (this.oMsg.none) return null;
return extract(this.oMsg.val);
}
public reply(content: Omit<InteractionReplyOptions, 'fetchReply'> | ReplyMessageOptions): Promise<Context> {
return firstSome(
this.oInterac.map(async i => {
await i.reply(content as InteractionReplyOptions);
return new Context(Some((await i.fetchReply()) as Message), Some(i));
}),
this.oMsg.map(async m => {
const reply = await m.reply(content as ReplyMessageOptions);
return new Context(Some(reply), this.oInterac);
}),
)!;
}
}

View File

@@ -3,5 +3,5 @@ export enum SernError {
NoAlias = 'You cannot provide an array with elements to a slash command.',
NonValidModuleType = 'Detected an unknown module type',
UndefinedModule = `A module could not be detected at`,
MismatchModule = `A module type mismatched with event emitted!`
MismatchModule = `A module type mismatched with event emitted!`,
}

View File

@@ -1,47 +1,50 @@
import type { ApplicationCommandOptionData, Awaitable, ButtonInteraction, ContextMenuCommandInteraction, MessageContextMenuCommandInteraction, SelectMenuInteraction } from 'discord.js';
import type {
ApplicationCommandOptionData,
Awaitable,
ButtonInteraction,
ContextMenuCommandInteraction,
MessageContextMenuCommandInteraction,
SelectMenuInteraction,
} from 'discord.js';
import type { Override } from '../../../../types/handler';
import type { CommandType } from '../../../sern';
import type { BaseModule } from '../module';
//possible refactoring to interfaces and not types
export type TextCommand = {
type : CommandType.Text;
alias : string[] | [],
type: CommandType.Text;
alias: string[] | [];
} & BaseModule;
export type SlashCommand = {
type : CommandType.Slash;
options : ApplicationCommandOptionData[] | [],
} & BaseModule;
type: CommandType.Slash;
options: ApplicationCommandOptionData[] | [];
} & BaseModule;
export type BothCommand = {
type : CommandType.Both;
alias : string[] | [];
options : ApplicationCommandOptionData[] | [],
type: CommandType.Both;
alias: string[] | [];
options: ApplicationCommandOptionData[] | [];
} & BaseModule;
export type ContextMenuUser = {
type : CommandType.MenuUser;
} & Override<BaseModule, { execute : ( ctx: ContextMenuCommandInteraction ) => Awaitable<void> }>;
type: CommandType.MenuUser;
} & Override<BaseModule, { execute: (ctx: ContextMenuCommandInteraction) => Awaitable<void> }>;
export type ContextMenuMsg = {
type : CommandType.MenuMsg;
} & Override<BaseModule, { execute : ( ctx: MessageContextMenuCommandInteraction ) => Awaitable<void> }>;
type: CommandType.MenuMsg;
} & Override<BaseModule, { execute: (ctx: MessageContextMenuCommandInteraction) => Awaitable<void> }>;
export type ButtonCommand = {
type : CommandType.Button;
} & Override<BaseModule, { execute : (ctx :ButtonInteraction ) => Awaitable<void> }>;
type: CommandType.Button;
} & Override<BaseModule, { execute: (ctx: ButtonInteraction) => Awaitable<void> }>;
export type SelectMenuCommand = {
type : CommandType.MenuSelect;
} & Override<BaseModule, { execute : (ctx : SelectMenuInteraction ) => Awaitable<void> }>;
type: CommandType.MenuSelect;
} & Override<BaseModule, { execute: (ctx: SelectMenuInteraction) => Awaitable<void> }>;
export type Module = (
TextCommand
| SlashCommand
export type Module =
| TextCommand
| SlashCommand
| BothCommand
| ContextMenuUser
| ContextMenuMsg
| ButtonCommand
| SelectMenuCommand
);
| SelectMenuCommand;

View File

@@ -1,12 +1,5 @@
import Context from './context';
import type { SlashCommand, TextCommand, BothCommand, Module } from '../structures/modules/commands/module';
import type { BothCommand, Module, SlashCommand, TextCommand } from './modules/commands/module';
import type Wrapper from './wrapper';
export {
Context,
SlashCommand,
TextCommand,
BothCommand,
Module,
Wrapper
};
export { Context, SlashCommand, TextCommand, BothCommand, Module, Wrapper };

View File

@@ -14,7 +14,7 @@ interface Wrapper {
readonly client: Client;
readonly defaultPrefix?: string;
readonly commands: string;
readonly events? : DiscordEvent[];
readonly events?: DiscordEvent[];
}
export default Wrapper;

File diff suppressed because it is too large Load Diff

View File

@@ -10,6 +10,7 @@ import type { Message } from 'discord.js';
export function isNotFromBot(message: Message) {
return !message.author.bot;
}
/**
* Checks if the message **starts** with the prefix
* @param message The message to check
@@ -21,6 +22,7 @@ export function isNotFromBot(message: Message) {
export function hasPrefix(message: Message, prefix?: string) {
return message.content.startsWith(prefix!);
}
/**
* Removes the first character(s) _[depending on prefix length]_ of the message
* @param msg

View File

@@ -1,40 +1,38 @@
import { ApplicationCommandType, ComponentType, InteractionType, MessageComponentInteraction, MessageComponentType } from 'discord.js';
import { ApplicationCommandType, ComponentType } from 'discord.js';
import { readdirSync, statSync } from 'fs';
import { join } from 'path';
import { from, Observable } from 'rxjs';
import { CommandType } from '../sern';
import type { PluggedModule } from '../structures/modules/module';
export const BothCommand = new Map<string, PluggedModule>();
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, PluggedModule>(),
[ApplicationCommandType.Message]: new Map<string, PluggedModule>(),
[ApplicationCommandType.ChatInput]: new Map<string, PluggedModule>(),
} as { [K in ApplicationCommandType]: Map<string, PluggedModule> };
export const MessageCompCommandStore = {
[ComponentType.Button] : new Map<string, PluggedModule>(),
[ComponentType.SelectMenu] : new Map<string, PluggedModule>()
[ComponentType.Button]: new Map<string, PluggedModule>(),
[ComponentType.SelectMenu]: new Map<string, PluggedModule>(),
};
export const TextCommandStore = {
text : new Map<string, PluggedModule>(),
aliases : new Map<string, PluggedModule>()
text: new Map<string, PluggedModule>(),
aliases: new Map<string, PluggedModule>(),
};
// Courtesy @Townsy45
function readPath(dir: string, arrayOfFiles: string[] = []): string[] {
try {
const files = readdirSync(dir);
for (const file of files) {
if (statSync(dir + '/' + file).isDirectory()) readPath(dir + '/' + file, arrayOfFiles);
else arrayOfFiles.push(join(dir, '/', file));
try {
const files = readdirSync(dir);
for (const file of files) {
if (statSync(dir + '/' + file).isDirectory()) readPath(dir + '/' + file, arrayOfFiles);
else arrayOfFiles.push(join(dir, '/', file));
}
} catch (err) {
throw err;
}
} catch (err) {
throw err;
}
return arrayOfFiles;
return arrayOfFiles;
}
export const fmtFileName = (n: string) => n.substring(0, n.length - 3);
@@ -45,18 +43,19 @@ export const fmtFileName = (n: string) => n.substring(0, n.length - 3);
* @param commandDir
*/
export function buildData(commandDir: string ): Observable<
{
export function buildData(commandDir: string): Observable<{
plugged: PluggedModule;
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 };
}));
}> {
return from(
getCommands(commandDir).map(absPath => {
// eslint-disable-next-line @typescript-eslint/no-var-requires
const plugged = <PluggedModule>require(absPath).module;
return { plugged, absPath };
}),
);
}
export function getCommands(dir: string): string[] {
return readPath(join(process.cwd(), dir));
return readPath(join(process.cwd(), dir));
}

View File

@@ -1,10 +1,9 @@
import type {
CommandInteractionOptionResolver,
MessagePayload,
MessageOptions,
ClientEvents,
Awaitable,
ClientEvents,
CommandInteractionOptionResolver,
MessageOptions,
MessagePayload,
} from 'discord.js';
// Anything that can be sent in a `<TextChannel>#send` or `<CommandInteraction>#reply`
@@ -15,15 +14,11 @@ export type ParseType<T> = {
[K in keyof T]: T[K] extends unknown ? [k: K, args: T[K]] : never;
}[keyof T];
export type Args = ParseType<{ text: string[]; slash: SlashOptions }>;
export type DiscordEvent =
ParseType< { [K in keyof ClientEvents ] : (...args : ClientEvents[K]) => Awaitable<void> }>;
export type DiscordEvent = ParseType<{ [K in keyof ClientEvents]: (...args: ClientEvents[K]) => Awaitable<void> }>;
export type SlashOptions = Omit<CommandInteractionOptionResolver, 'getMessage' | 'getFocused'>;
//https://dev.to/vborodulin/ts-how-to-override-properties-with-type-intersection-554l
export type Override<T1, T2> = Omit<T1, keyof T2> & T2;