From 3dedba3493e53aa01bcf6401c8287d264b7c9cda Mon Sep 17 00:00:00 2001 From: jacoobes Date: Fri, 13 May 2022 14:45:06 -0500 Subject: [PATCH] chore: prettier reformat --- src/handler/structures/context.ts | 175 ++-- src/handler/structures/errors.ts | 2 +- .../structures/modules/commands/module.ts | 53 +- src/handler/structures/structxports.ts | 11 +- src/handler/structures/wrapper.ts | 2 +- src/handler/utilities/markup.ts | 959 ++++++++++-------- src/handler/utilities/messageHelpers.ts | 2 + src/handler/utilities/readFile.ts | 57 +- src/types/handler.ts | 15 +- 9 files changed, 663 insertions(+), 613 deletions(-) diff --git a/src/handler/structures/context.ts b/src/handler/structures/context.ts index 5080b46..3e6e022 100644 --- a/src/handler/structures/context.ts +++ b/src/handler/structures/context.ts @@ -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(...args : Option[]) : Nullish { - for ( const op of args ) { +function firstSome(...args: Option[]): Nullish { + 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 = None, - private oInterac: Option = None + private oInterac: Option = 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 { - 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 { 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 { - return firstSome( - this.oMsg.map(m => m.member), - this.oInterac.map(i => i.member) - ); + */ + public get member(): Nullish { + 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, - ): Context { - if (this.oInterac.some) { - onInteraction(this.oInterac.val); - return Context.wrap(this.oInterac.val); - } - return this; + public onInteraction(onInteraction: (interaction: ChatInputCommandInteraction) => Awaitable): Context { + if (this.oInterac.some) { + onInteraction(this.oInterac.val); + return Context.wrap(this.oInterac.val); + } + return this; } - public onMessage( - onMessage : ( message : Message ) => Awaitable - ): Context { - if (this.oMsg.some) { - onMessage(this.oMsg.val); - return Context.wrap(this.oMsg.val); - } - return this; + + public onMessage(onMessage: (message: Message) => Awaitable): Context { + if (this.oMsg.some) { + onMessage(this.oMsg.val); + return Context.wrap(this.oMsg.val); + } + return this; } - public takeInteractionValue( - extract : (interaction : ChatInputCommandInteraction) => T - ): Nullish { - if(this.oInterac.none) return null; - return extract(this.oInterac.val); - } - public takeMessageValue( - extract : (message: Message) => T - ): Nullish { - if(this.oMsg.none) return null; - return extract(this.oMsg.val); - } + public takeInteractionValue(extract: (interaction: ChatInputCommandInteraction) => T): Nullish { + if (this.oInterac.none) return null; + return extract(this.oInterac.val); + } - public reply( - content : Omit | ReplyMessageOptions - ): Promise { - 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(extract: (message: Message) => T): Nullish { + if (this.oMsg.none) return null; + return extract(this.oMsg.val); + } + + public reply(content: Omit | ReplyMessageOptions): Promise { + 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); + }), + )!; + } } - - diff --git a/src/handler/structures/errors.ts b/src/handler/structures/errors.ts index 869b2cd..68aa695 100644 --- a/src/handler/structures/errors.ts +++ b/src/handler/structures/errors.ts @@ -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!`, } diff --git a/src/handler/structures/modules/commands/module.ts b/src/handler/structures/modules/commands/module.ts index 006a614..e013a7d 100644 --- a/src/handler/structures/modules/commands/module.ts +++ b/src/handler/structures/modules/commands/module.ts @@ -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 Awaitable }>; + type: CommandType.MenuUser; +} & Override Awaitable }>; export type ContextMenuMsg = { - type : CommandType.MenuMsg; -} & Override Awaitable }>; + type: CommandType.MenuMsg; +} & Override Awaitable }>; export type ButtonCommand = { - type : CommandType.Button; -} & Override Awaitable }>; + type: CommandType.Button; +} & Override Awaitable }>; export type SelectMenuCommand = { - type : CommandType.MenuSelect; -} & Override Awaitable }>; + type: CommandType.MenuSelect; +} & Override Awaitable }>; - -export type Module = ( - TextCommand - | SlashCommand +export type Module = + | TextCommand + | SlashCommand | BothCommand | ContextMenuUser | ContextMenuMsg | ButtonCommand - | SelectMenuCommand -); + | SelectMenuCommand; diff --git a/src/handler/structures/structxports.ts b/src/handler/structures/structxports.ts index 1ae6997..70bdc7a 100644 --- a/src/handler/structures/structxports.ts +++ b/src/handler/structures/structxports.ts @@ -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 }; diff --git a/src/handler/structures/wrapper.ts b/src/handler/structures/wrapper.ts index 8da6e2b..4bfc76c 100644 --- a/src/handler/structures/wrapper.ts +++ b/src/handler/structures/wrapper.ts @@ -14,7 +14,7 @@ interface Wrapper { readonly client: Client; readonly defaultPrefix?: string; readonly commands: string; - readonly events? : DiscordEvent[]; + readonly events?: DiscordEvent[]; } export default Wrapper; diff --git a/src/handler/utilities/markup.ts b/src/handler/utilities/markup.ts index 4dba827..d15c105 100644 --- a/src/handler/utilities/markup.ts +++ b/src/handler/utilities/markup.ts @@ -1,30 +1,30 @@ - /** - * An enumeration of all the valid Discord timestamp styles. - */ - export enum TimestampStyles { +/** + * An enumeration of all the valid Discord timestamp styles. + */ +export enum TimestampStyles { BOTH_LONG = 'F', BOTH_SHORT = 'f', DATE_LONG = 'D', DATE_SHORT = 'd', RELATIVE = 'R', TIME_LONG = 'T', - TIME_SHORT = 't' - } - /** - * Utility to cut messages by bytes and not characters - */ - export function trueSlice(text: string, limit?: number): string { + TIME_SHORT = 't', +} + +/** + * Utility to cut messages by bytes and not characters + */ +export function trueSlice(text: string, limit?: number): string { if (limit) { - return new TextDecoder().decode( - new TextEncoder().encode(text).slice(0, limit) - ); + return new TextDecoder().decode(new TextEncoder().encode(text).slice(0, limit)); } return text; - } - /** - * Object that holds all the Discord Markup identifiers. - */ - export const Strings = { +} + +/** + * Object that holds all the Discord Markup identifiers. + */ +export const Strings = { BOLD: '**', CODEBLOCK: '```', CODESTRING: '`', @@ -33,12 +33,12 @@ ITALICS: '_', SPOILER: '||', STRIKE: '~~', - UNDERLINE: '__' - }; - /** - * Object that maps all the Discord Markup identifiers to their respective RegExp matchers. - */ - const Regexes = { + UNDERLINE: '__', +}; +/** + * Object that maps all the Discord Markup identifiers to their respective RegExp matchers. + */ +const Regexes = { [Strings.BOLD]: /\*\*/g, [Strings.CODEBLOCK]: new RegExp(Strings.CODEBLOCK, 'g'), [Strings.CODESTRING]: new RegExp(Strings.CODESTRING, 'g'), @@ -51,12 +51,12 @@ LINK: /\]\(/g, MENTION: /<@([!&]?[0-9]{16,21})>/g, MENTION_HARDCORE: /@/g, - URL: /\)/g - }; - /** - * Object to replace Discord Markup identifiers with when escaping strings. - */ - const Replacements = { + URL: /\)/g, +}; +/** + * Object to replace Discord Markup identifiers with when escaping strings. + */ +const Replacements = { [Strings.BOLD]: '\\*\\*', [Strings.CODEBLOCK]: '``\u200b`', [Strings.CODESTRING]: '\\`', @@ -65,42 +65,42 @@ [Strings.SPOILER]: '\\|\\|', [Strings.STRIKE]: '\\~\\~', [Strings.UNDERLINE]: '\\_\\_', - MENTION: '\u200b' - }; - /** - * Utility to escape some Discord Markup Identifier - */ - function EscapeBasic(raw: string, key: keyof typeof Strings) { + MENTION: '\u200b', +}; + +/** + * Utility to escape some Discord Markup Identifier + */ +function EscapeBasic(raw: string, key: keyof typeof Strings) { return raw.replace(Regexes[key], Replacements[key]); - } - /** - * Object of all the Escape functions used to apply mixed markup - */ - export const Escape: Record< - keyof typeof Strings, - typeof EscapeBasic - > = (Object.keys(Strings) as Array).reduce( +} + +/** + * Object of all the Escape functions used to apply mixed markup + */ +export const Escape: Record = ( + Object.keys(Strings) as Array +).reduce( (p, v) => Object.assign(p, { [v]: (raw: string) => EscapeBasic(raw, v) }), - {} as Record - ); - /** - * String formatting for freezing Discord timestamps that have the Relative (R) flag - */ - const FrozenTimestampStyles: Record = { - [TimestampStyles.BOTH_LONG]: - '{day}, {month} {date}, {year} {hour}:{minute} {meridian}', - [TimestampStyles.BOTH_SHORT]: - '{month} {date}, {year} {hour}:{minute} {meridian}', + {} as Record, +); +/** + * String formatting for freezing Discord timestamps that have the Relative (R) flag + */ +const FrozenTimestampStyles: Record = { + [TimestampStyles.BOTH_LONG]: '{day}, {month} {date}, {year} {hour}:{minute} {meridian}', + [TimestampStyles.BOTH_SHORT]: '{month} {date}, {year} {hour}:{minute} {meridian}', [TimestampStyles.DATE_LONG]: '{month} {date}, {year}', [TimestampStyles.DATE_SHORT]: '{month_short}/{date}/{year}', [TimestampStyles.RELATIVE]: '{relative}', [TimestampStyles.TIME_LONG]: '{hour}:{minute}:{second} {meridian}', - [TimestampStyles.TIME_SHORT]: '{hour}:{minute} {meridian}' - }; - /** - * Holds metadata and string conversions of a UNIX Timestamp - */ - interface Timestamp { + [TimestampStyles.TIME_SHORT]: '{hour}:{minute} {meridian}', +}; + +/** + * Holds metadata and string conversions of a UNIX Timestamp + */ +interface Timestamp { raw: number; month: string; month_short: string; @@ -112,23 +112,24 @@ minute: string; day: string; relative: string; - } - /** - * Converter for number to Days of the Week - */ - const Days: Record = { +} + +/** + * Converter for number to Days of the Week + */ +const Days: Record = { 0: 'Sunday', 1: 'Monday', 2: 'Tuesday', 3: 'Wednesday', 4: 'Thursday', 5: 'Friday', - 6: 'Saturday' - }; - /** - * Converter for number to Months of the Year - */ - const Months: Record = { + 6: 'Saturday', +}; +/** + * Converter for number to Months of the Year + */ +const Months: Record = { 0: 'January', 1: 'February', 2: 'March', @@ -140,55 +141,47 @@ 8: 'September', 9: 'October', 10: 'November', - 11: 'December' - }; - /** - * Converts a Date object to a Timestamp object - */ - function formatDate(date: Date): Timestamp { + 11: 'December', +}; + +/** + * Converts a Date object to a Timestamp object + */ +function formatDate(date: Date): Timestamp { return { - relative: toTimeString(date.getTime(), TimestampUnits), - raw: date.getTime(), - date: date - .getDate() - .toString() - .padStart(2, '0'), - day: Days[date.getDay()], - hour: date - .getHours() - .toString() - .padStart(2, '0'), - meridian: date.getHours() > 12 ? 'PM' : 'AM', - minute: date - .getMinutes() - .toString() - .padStart(2, '0'), - month: Months[date.getMonth()], - month_short: (date.getMonth() + 1).toString().padStart(2, '0'), - second: date - .getSeconds() - .toString() - .padStart(2, '0'), - year: date.getFullYear().toString() + relative: toTimeString(date.getTime(), TimestampUnits), + raw: date.getTime(), + date: date.getDate().toString().padStart(2, '0'), + day: Days[date.getDay()], + hour: date.getHours().toString().padStart(2, '0'), + meridian: date.getHours() > 12 ? 'PM' : 'AM', + minute: date.getMinutes().toString().padStart(2, '0'), + month: Months[date.getMonth()], + month_short: (date.getMonth() + 1).toString().padStart(2, '0'), + second: date.getSeconds().toString().padStart(2, '0'), + year: date.getFullYear().toString(), }; - } - /** - * Collectively multiplies bigints together - */ - function multiplyLarge(...nums: Array): bigint { +} + +/** + * Collectively multiplies bigints together + */ +function multiplyLarge(...nums: Array): bigint { return nums.map(BigInt).reduce((p, v) => (p *= v), 1n); - } - /** - * Get the absolute value of a bigint - */ - function bigintAbs(int: bigint) { +} + +/** + * Get the absolute value of a bigint + */ +function bigintAbs(int: bigint) { if (int < 0) return -int; return int; - } - /** - * Object of Units matched with their string representations. - */ - const TimestampUnits = { +} + +/** + * Object of Units matched with their string representations. + */ +const TimestampUnits = { myriad: multiplyLarge(10, 10, 10, 10, 12, 4, 7, 24, 60, 1000), millenium: multiplyLarge(10, 10, 10, 12, 4, 7, 24, 60, 1000), century: multiplyLarge(10, 10, 12, 4, 7, 24, 60, 1000), @@ -200,21 +193,22 @@ hour: multiplyLarge(60, 60, 1000), minute: multiplyLarge(60, 1000), second: multiplyLarge(1000), - millisecond: multiplyLarge(1) - }; - /** - * Utility type. Used to force Object.entries to allow non-strings. - */ - type ObjectEntries = Array<[K, V]>; - /** - * Converts a UNIX timestamp to a Relative String - */ - function toTimeString( + millisecond: multiplyLarge(1), +}; +/** + * Utility type. Used to force Object.entries to allow non-strings. + */ +type ObjectEntries = Array<[K, V]>; + +/** + * Converts a UNIX timestamp to a Relative String + */ +function toTimeString( unix: bigint | number, units: Record, isFromNow = false, - limit?: number - ) { + limit?: number, +) { if (typeof unix === 'number') unix = BigInt(unix); if (isFromNow) unix = bigintAbs(unix - BigInt(Date.now())); @@ -225,175 +219,200 @@ let run = unix; for (const [unit, value] of unitList) { - if (run < value) continue; - const runs = run / value + 1n; + if (run < value) continue; + const runs = run / value + 1n; - for (let loop = 0; loop <= runs; loop++) { - if (run < value) break; - const item = formatted.get(unit); + for (let loop = 0; loop <= runs; loop++) { + if (run < value) break; + const item = formatted.get(unit); - if (item) formatted.set(unit, item + 1); - else formatted.set(unit, 1); + if (item) formatted.set(unit, item + 1); + else formatted.set(unit, 1); - run -= value; - } + run -= value; + } } let returned: Array = []; for (const [key, value] of formatted) { - const unit = key + (value === 1 ? '' : 's'); - returned.push(`${value} ${unit}`); + const unit = key + (value === 1 ? '' : 's'); + returned.push(`${value} ${unit}`); } if (limit !== undefined) { - returned = returned.slice(0, limit); + returned = returned.slice(0, limit); } return returned.join(', '); - } - /** - * Freezes a UNIT timestamp into some time string based on the Timestamp Style - */ - function freezeUnix(unix: number, style: TimestampStyles) { +} + +/** + * Freezes a UNIT timestamp into some time string based on the Timestamp Style + */ +function freezeUnix(unix: number, style: TimestampStyles) { const date = new Date(unix); const timestamp = formatDate(date); let ret = FrozenTimestampStyles[style]; for (const [key, value] of Object.entries(timestamp)) { - ret = ret.split(`{${key}}`).join(value); + ret = ret.split(`{${key}}`).join(value); } return ret; - } - /** - * Instanced Class for formatting strings into their Markup variants - */ - class FormatInner { +} + +/** + * Instanced Class for formatting strings into their Markup variants + */ +class FormatInner { public raw: string; public static: typeof FormatInner = FormatInner; + constructor(raw: string | FormatInner) { - if (raw instanceof FormatInner) { - raw = raw.raw; - } - this.raw = raw; + if (raw instanceof FormatInner) { + raw = raw.raw; + } + this.raw = raw; } + toString() { - return this.raw; + return this.raw; } + valueOf() { - return this.raw; + return this.raw; } + italics() { - return this.build('ITALICS', this.raw); + return this.build('ITALICS', this.raw); } + bold() { - return this.build('BOLD', this.raw); + return this.build('BOLD', this.raw); } + codestring() { - const useDouble = this.raw.includes(Strings.CODESTRING); - if (useDouble) { - return this.codestringDouble(); - } - return this.codestringSingle(); + const useDouble = this.raw.includes(Strings.CODESTRING); + if (useDouble) { + return this.codestringDouble(); + } + return this.codestringSingle(); } + codestringDouble() { - return this.build('CODESTRING_DOUBLE', this.raw); + return this.build('CODESTRING_DOUBLE', this.raw); } + codestringSingle() { - return this.build('CODESTRING', this.raw); + return this.build('CODESTRING', this.raw); } + codeblock(language?: string) { - let full = ''; - if (language) { - full += language + '\n'; - } - full += this.raw; - return this.build('CODEBLOCK', full); + let full = ''; + if (language) { + full += language + '\n'; + } + full += this.raw; + return this.build('CODEBLOCK', full); } + spoiler() { - return this.build('SPOILER', this.raw); + return this.build('SPOILER', this.raw); } + strike() { - return this.build('STRIKE', this.raw); + return this.build('STRIKE', this.raw); } + underline() { - return this.build('UNDERLINE', this.raw); + return this.build('UNDERLINE', this.raw); } build(key: keyof typeof Strings, w: string) { - const escaped = Escape[key](w, key); - const ret = this.static.wrap(escaped, Strings[key]); - return new this.static(ret); + const escaped = Escape[key](w, key); + const ret = this.static.wrap(escaped, Strings[key]); + return new this.static(ret); } + static wrap(raw: string, what: string) { - return `${what}${raw}${what}`; + return `${what}${raw}${what}`; } - } - /** - * Formats strings into their Markup Variants - */ - export class Format extends FormatInner { +} + +/** + * Formats strings into their Markup Variants + */ +export class Format extends FormatInner { static bold(text: string) { - return new this(text).bold(); + return new this(text).bold(); } + static build(text: string, key: keyof typeof Strings) { - return new this(text).build(key, text); + return new this(text).build(key, text); } + static codeblock(text: string, language?: string) { - return new this(text).codeblock(language); + return new this(text).codeblock(language); } + static codestring(text: string) { - return new this(text).codestring(); + return new this(text).codestring(); } + static codestringSingle(text: string) { - return new this(text).codestringSingle(); + return new this(text).codestringSingle(); } + static codestringDouble(text: string) { - return new this(text).codestringDouble(); + return new this(text).codestringDouble(); } + static italics(text: string) { - return new this(text).italics(); + return new this(text).italics(); } + static spoiler(text: string) { - return new this(text).spoiler(); + return new this(text).spoiler(); } + static strike(text: string) { - return new this(text).strike(); + return new this(text).strike(); } + static underline(text: string) { - return new this(text).underline(); + return new this(text).underline(); } + static timestamp( - unix: number | Date | string, - format: TimestampStyles = TimestampStyles.BOTH_SHORT, - isSeconds = false + unix: number | Date | string, + format: TimestampStyles = TimestampStyles.BOTH_SHORT, + isSeconds = false, ) { - if (typeof unix === 'string') unix = Number(unix); - if (unix instanceof Date) unix = unix.getTime(); + if (typeof unix === 'string') unix = Number(unix); + if (unix instanceof Date) unix = unix.getTime(); - if (!isSeconds) { - unix /= 1000; - } - unix = Math.floor(unix); - return new this(``); + if (!isSeconds) { + unix /= 1000; + } + unix = Math.floor(unix); + return new this(``); } - static date( - unix: number | Date | string, - format: TimestampStyles = TimestampStyles.BOTH_SHORT, - isSeconds = false - ) { - if (typeof unix === 'string') unix = Number(unix); - if (unix instanceof Date) unix = unix.getTime(); - if (isSeconds) { - unix *= 1000; - } - return new this(freezeUnix(unix, format)); + static date(unix: number | Date | string, format: TimestampStyles = TimestampStyles.BOTH_SHORT, isSeconds = false) { + if (typeof unix === 'string') unix = Number(unix); + if (unix instanceof Date) unix = unix.getTime(); + + if (isSeconds) { + unix *= 1000; + } + return new this(freezeUnix(unix, format)); } + static link(text: string, url: string | URL) { - if (url instanceof URL) url = url.href; - return new this(`[${text}](${url})`); + if (url instanceof URL) url = url.href; + return new this(`[${text}](${url})`); } - } - /** - * Enumeration of names used in the Matching process - */ - enum DiscordRegexNames { +} + +/** + * Enumeration of names used in the Matching process + */ +enum DiscordRegexNames { EMOJI = 'EMOJI', JUMP_CHANNEL = 'JUMP_CHANNEL', JUMP_CHANNEL_MESSAGE = 'JUMP_CHANNEL_MESSAGE', @@ -408,15 +427,18 @@ TEXT_SPOILER = 'TEXT_SPOILER', TEXT_STRIKE = 'TEXT_STRIKE', TEXT_UNDERLINE = 'TEXT_UNDERLINE', - TEXT_URL = 'TEXT_URL' - } - /** - * Mapping of Matching Names to their respective Regular Expressions - */ - export const DiscordRegex = { + TEXT_URL = 'TEXT_URL', +} + +/** + * Mapping of Matching Names to their respective Regular Expressions + */ +export const DiscordRegex = { [DiscordRegexNames.EMOJI]: //g, - [DiscordRegexNames.JUMP_CHANNEL]: /^(?:https?):\/\/(?:(?:(?:canary|ptb)\.)?(?:discord|discordapp)\.com\/channels\/)(\@me|\d+)\/(\d+)$/g, - [DiscordRegexNames.JUMP_CHANNEL_MESSAGE]: /^(?:https?):\/\/(?:(?:(?:canary|ptb)\.)?(?:discord|discordapp)\.com\/channels\/)(\@me|\d+)\/(\d+)\/(\d+)$/g, + [DiscordRegexNames.JUMP_CHANNEL]: + /^(?:https?):\/\/(?:(?:(?:canary|ptb)\.)?(?:discord|discordapp)\.com\/channels\/)(\@me|\d+)\/(\d+)$/g, + [DiscordRegexNames.JUMP_CHANNEL_MESSAGE]: + /^(?:https?):\/\/(?:(?:(?:canary|ptb)\.)?(?:discord|discordapp)\.com\/channels\/)(\@me|\d+)\/(\d+)\/(\d+)$/g, [DiscordRegexNames.MENTION_CHANNEL]: /<#(\d+)>/g, [DiscordRegexNames.MENTION_ROLE]: /<@&(\d+)>/g, [DiscordRegexNames.MENTION_USER]: /<@(!?)(\d+)>/g, @@ -428,12 +450,13 @@ [DiscordRegexNames.TEXT_SPOILER]: /\|\|([\s\S]+?)\|\|/g, [DiscordRegexNames.TEXT_STRIKE]: /~~([\s\S]+?)~~(?!_)/g, [DiscordRegexNames.TEXT_UNDERLINE]: /__([\s\S]+?)__/g, - [DiscordRegexNames.TEXT_URL]: /((?:https?):\/\/[^\s<]+[^<.,:;"'\]\s])/g - }; - /** - * Object containing all the data from some Matching sequence - */ - export interface DiscordRegexMatch { + [DiscordRegexNames.TEXT_URL]: /((?:https?):\/\/[^\s<]+[^<.,:;"'\]\s])/g, +}; + +/** + * Object containing all the data from some Matching sequence + */ +export interface DiscordRegexMatch { animated?: boolean; channelId?: string; guildId?: string; @@ -445,286 +468,322 @@ name?: string; text?: string; species: DiscordRegexNames; - } - /** - * The result of a matched string. - */ - export interface DiscordRegexPayload { +} + +/** + * The result of a matched string. + */ +export interface DiscordRegexPayload { match: { - regex: RegExp; - type: string; + regex: RegExp; + type: string; }; matches: Array; - } - export interface EmojiMatch extends DiscordRegexMatch { +} + +export interface EmojiMatch extends DiscordRegexMatch { name: string; id: string; animated: boolean; species: DiscordRegexNames.EMOJI; - } - export interface JumpMatch extends DiscordRegexMatch { +} + +export interface JumpMatch extends DiscordRegexMatch { guildId: string; - species: - | DiscordRegexNames.JUMP_CHANNEL - | DiscordRegexNames.JUMP_CHANNEL_MESSAGE; - } - export interface JumpChannelMatch extends JumpMatch { + species: DiscordRegexNames.JUMP_CHANNEL | DiscordRegexNames.JUMP_CHANNEL_MESSAGE; +} + +export interface JumpChannelMatch extends JumpMatch { channelId: string; species: DiscordRegexNames.JUMP_CHANNEL; - } - export interface JumpChannelMessageMatch extends JumpMatch { +} + +export interface JumpChannelMessageMatch extends JumpMatch { channelId: string; messageId: string; species: DiscordRegexNames.JUMP_CHANNEL_MESSAGE; - } - export interface MentionableMatch extends DiscordRegexMatch { +} + +export interface MentionableMatch extends DiscordRegexMatch { id: string; - species: - | DiscordRegexNames.MENTION_CHANNEL - | DiscordRegexNames.MENTION_ROLE - | DiscordRegexNames.MENTION_USER; - } - export interface MentionChannelMatch extends MentionableMatch { + species: DiscordRegexNames.MENTION_CHANNEL | DiscordRegexNames.MENTION_ROLE | DiscordRegexNames.MENTION_USER; +} + +export interface MentionChannelMatch extends MentionableMatch { species: DiscordRegexNames.MENTION_CHANNEL; - } - export interface MentionRoleMatch extends MentionableMatch { +} + +export interface MentionRoleMatch extends MentionableMatch { species: DiscordRegexNames.MENTION_ROLE; - } - export interface MentionUserMatch extends MentionableMatch { +} + +export interface MentionUserMatch extends MentionableMatch { mentionType: string; species: DiscordRegexNames.MENTION_USER; - } - export interface TextMatch extends DiscordRegexMatch { +} + +export interface TextMatch extends DiscordRegexMatch { text: string; species: - | DiscordRegexNames.TEXT_BOLD - | DiscordRegexNames.TEXT_CODEBLOCK - | DiscordRegexNames.TEXT_CODESTRING - | DiscordRegexNames.TEXT_ITALICS - | DiscordRegexNames.TEXT_SNOWFLAKE - | DiscordRegexNames.TEXT_SPOILER - | DiscordRegexNames.TEXT_STRIKE - | DiscordRegexNames.TEXT_UNDERLINE - | DiscordRegexNames.TEXT_URL; - } - export interface TextCodeblockMatch extends TextMatch { + | DiscordRegexNames.TEXT_BOLD + | DiscordRegexNames.TEXT_CODEBLOCK + | DiscordRegexNames.TEXT_CODESTRING + | DiscordRegexNames.TEXT_ITALICS + | DiscordRegexNames.TEXT_SNOWFLAKE + | DiscordRegexNames.TEXT_SPOILER + | DiscordRegexNames.TEXT_STRIKE + | DiscordRegexNames.TEXT_UNDERLINE + | DiscordRegexNames.TEXT_URL; +} + +export interface TextCodeblockMatch extends TextMatch { language: string; species: DiscordRegexNames.TEXT_CODEBLOCK; - } - export interface TextBoldMatch extends TextMatch { - species: DiscordRegexNames.TEXT_BOLD; - } - export interface TextCodestringMatch extends TextMatch { - species: DiscordRegexNames.TEXT_CODESTRING; - } - export interface TextItalicsMatch extends TextMatch { - species: DiscordRegexNames.TEXT_ITALICS; - } - export interface TextSnowflakeMatch extends TextMatch { - species: DiscordRegexNames.TEXT_SNOWFLAKE; - } - export interface TextSpoilerMatch extends TextMatch { - species: DiscordRegexNames.TEXT_SPOILER; - } - export interface TextStrikeMatch extends TextMatch { - species: DiscordRegexNames.TEXT_STRIKE; - } - export interface TextUnderlineMatch extends TextMatch { - species: DiscordRegexNames.TEXT_UNDERLINE; - } - export interface TextUrlMatch extends TextMatch { - species: DiscordRegexNames.TEXT_URL; - } +} - class MatchInner { +export interface TextBoldMatch extends TextMatch { + species: DiscordRegexNames.TEXT_BOLD; +} + +export interface TextCodestringMatch extends TextMatch { + species: DiscordRegexNames.TEXT_CODESTRING; +} + +export interface TextItalicsMatch extends TextMatch { + species: DiscordRegexNames.TEXT_ITALICS; +} + +export interface TextSnowflakeMatch extends TextMatch { + species: DiscordRegexNames.TEXT_SNOWFLAKE; +} + +export interface TextSpoilerMatch extends TextMatch { + species: DiscordRegexNames.TEXT_SPOILER; +} + +export interface TextStrikeMatch extends TextMatch { + species: DiscordRegexNames.TEXT_STRIKE; +} + +export interface TextUnderlineMatch extends TextMatch { + species: DiscordRegexNames.TEXT_UNDERLINE; +} + +export interface TextUrlMatch extends TextMatch { + species: DiscordRegexNames.TEXT_URL; +} + +class MatchInner { public raw: string; public static: typeof MatchInner = MatchInner; constructor(raw: string) { - this.raw = raw; + this.raw = raw; } emoji(): DiscordRegexPayload { - return this.match(DiscordRegexNames.EMOJI); + return this.match(DiscordRegexNames.EMOJI); } + jumpChannel(): DiscordRegexPayload { - return this.match(DiscordRegexNames.JUMP_CHANNEL); + return this.match(DiscordRegexNames.JUMP_CHANNEL); } + jumpChannelMessage(): DiscordRegexPayload { - return this.match(DiscordRegexNames.JUMP_CHANNEL_MESSAGE); + return this.match(DiscordRegexNames.JUMP_CHANNEL_MESSAGE); } + mentionChannel(): DiscordRegexPayload { - return this.match(DiscordRegexNames.MENTION_CHANNEL); + return this.match(DiscordRegexNames.MENTION_CHANNEL); } + mentionRole(): DiscordRegexPayload { - return this.match(DiscordRegexNames.MENTION_ROLE); + return this.match(DiscordRegexNames.MENTION_ROLE); } + mentionUser(): DiscordRegexPayload { - return this.match(DiscordRegexNames.MENTION_USER); + return this.match(DiscordRegexNames.MENTION_USER); } + codeblock(): DiscordRegexPayload { - return this.match(DiscordRegexNames.TEXT_CODEBLOCK); + return this.match(DiscordRegexNames.TEXT_CODEBLOCK); } + bold(): DiscordRegexPayload { - return this.match(DiscordRegexNames.TEXT_BOLD); + return this.match(DiscordRegexNames.TEXT_BOLD); } + codestring(): DiscordRegexPayload { - return this.match(DiscordRegexNames.TEXT_CODESTRING); + return this.match(DiscordRegexNames.TEXT_CODESTRING); } + italics(): DiscordRegexPayload { - return this.match(DiscordRegexNames.TEXT_ITALICS); + return this.match(DiscordRegexNames.TEXT_ITALICS); } + snowflake(): DiscordRegexPayload { - return this.match(DiscordRegexNames.TEXT_SNOWFLAKE); + return this.match(DiscordRegexNames.TEXT_SNOWFLAKE); } + spoiler(): DiscordRegexPayload { - return this.match(DiscordRegexNames.TEXT_SPOILER); + return this.match(DiscordRegexNames.TEXT_SPOILER); } + strike(): DiscordRegexPayload { - return this.match(DiscordRegexNames.TEXT_STRIKE); + return this.match(DiscordRegexNames.TEXT_STRIKE); } + underline(): DiscordRegexPayload { - return this.match(DiscordRegexNames.TEXT_UNDERLINE); + return this.match(DiscordRegexNames.TEXT_UNDERLINE); } + url(): DiscordRegexPayload { - return this.match(DiscordRegexNames.TEXT_URL); + return this.match(DiscordRegexNames.TEXT_URL); } - match( - type: DiscordRegexNames, - onlyFirst = false - ): DiscordRegexPayload { - const regex = DiscordRegex[type]; - if (regex === undefined) { - throw new global.Error(`Unknown regex type: ${type}`); - } - regex.lastIndex = 0; - - const payload: DiscordRegexPayload = { - match: { regex, type }, - matches: [] - }; - - let match: RegExpExecArray | null = null; - while ((match = regex.exec(this.raw))) { - const result: DiscordRegexMatch = { matched: match[0], species: type }; - switch (type) { - case DiscordRegexNames.EMOJI: - { - result.name = match[1] as string; - result.id = match[2] as string; - result.animated = this.raw.startsWith('(type: DiscordRegexNames, onlyFirst = false): DiscordRegexPayload { + const regex = DiscordRegex[type]; + if (regex === undefined) { throw new global.Error(`Unknown regex type: ${type}`); - } } - payload.matches.push(result as T); + regex.lastIndex = 0; - if (onlyFirst) { - break; + const payload: DiscordRegexPayload = { + match: { regex, type }, + matches: [], + }; + + let match: RegExpExecArray | null = null; + while ((match = regex.exec(this.raw))) { + const result: DiscordRegexMatch = { matched: match[0], species: type }; + switch (type) { + case DiscordRegexNames.EMOJI: + { + result.name = match[1] as string; + result.id = match[2] as string; + result.animated = this.raw.startsWith('(); export const ApplicationCommandStore = { - [ApplicationCommandType.User] : new Map(), - [ApplicationCommandType.Message] : new Map(), - [ApplicationCommandType.ChatInput] : new Map(), -} as {[K in ApplicationCommandType] : Map }; + [ApplicationCommandType.User]: new Map(), + [ApplicationCommandType.Message]: new Map(), + [ApplicationCommandType.ChatInput]: new Map(), +} as { [K in ApplicationCommandType]: Map }; export const MessageCompCommandStore = { - [ComponentType.Button] : new Map(), - [ComponentType.SelectMenu] : new Map() + [ComponentType.Button]: new Map(), + [ComponentType.SelectMenu]: new Map(), }; export const TextCommandStore = { - text : new Map(), - aliases : new Map() + text: new Map(), + aliases: new Map(), }; // 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 = ( require(absPath).module); - return { plugged, absPath }; - })); +}> { + return from( + getCommands(commandDir).map(absPath => { + // eslint-disable-next-line @typescript-eslint/no-var-requires + const plugged = require(absPath).module; + return { plugged, absPath }; + }), + ); } export function getCommands(dir: string): string[] { - return readPath(join(process.cwd(), dir)); + return readPath(join(process.cwd(), dir)); } diff --git a/src/types/handler.ts b/src/types/handler.ts index 1fdfcc5..05d79c6 100644 --- a/src/types/handler.ts +++ b/src/types/handler.ts @@ -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 `#send` or `#reply` @@ -15,15 +14,11 @@ export type ParseType = { [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 }>; - +export type DiscordEvent = ParseType<{ [K in keyof ClientEvents]: (...args: ClientEvents[K]) => Awaitable }>; export type SlashOptions = Omit; //https://dev.to/vborodulin/ts-how-to-override-properties-with-type-intersection-554l export type Override = Omit & T2; -