diff options
Diffstat (limited to 'lib/arguments')
-rw-r--r-- | lib/arguments/abbreviatedNumber.ts | 13 | ||||
-rw-r--r-- | lib/arguments/contentWithDuration.ts | 5 | ||||
-rw-r--r-- | lib/arguments/discordEmoji.ts | 14 | ||||
-rw-r--r-- | lib/arguments/duration.ts | 5 | ||||
-rw-r--r-- | lib/arguments/durationSeconds.ts | 6 | ||||
-rw-r--r-- | lib/arguments/globalUser.ts | 7 | ||||
-rw-r--r-- | lib/arguments/index.ts | 10 | ||||
-rw-r--r-- | lib/arguments/messageLink.ts | 20 | ||||
-rw-r--r-- | lib/arguments/permission.ts | 12 | ||||
-rw-r--r-- | lib/arguments/roleWithDuration.ts | 17 | ||||
-rw-r--r-- | lib/arguments/snowflake.ts | 8 | ||||
-rw-r--r-- | lib/arguments/tinyColor.ts | 10 |
12 files changed, 127 insertions, 0 deletions
diff --git a/lib/arguments/abbreviatedNumber.ts b/lib/arguments/abbreviatedNumber.ts new file mode 100644 index 0000000..a7d8ce5 --- /dev/null +++ b/lib/arguments/abbreviatedNumber.ts @@ -0,0 +1,13 @@ +import type { BushArgumentTypeCaster } from '#lib'; +import assert from 'assert/strict'; +import numeral from 'numeral'; +assert(typeof numeral === 'function'); + +export const abbreviatedNumber: BushArgumentTypeCaster<number | null> = (_, phrase) => { + if (!phrase) return null; + const num = numeral(phrase?.toLowerCase()).value(); + + if (typeof num !== 'number' || isNaN(num)) return null; + + return num; +}; diff --git a/lib/arguments/contentWithDuration.ts b/lib/arguments/contentWithDuration.ts new file mode 100644 index 0000000..0efba39 --- /dev/null +++ b/lib/arguments/contentWithDuration.ts @@ -0,0 +1,5 @@ +import { parseDuration, type BushArgumentTypeCaster, type ParsedDuration } from '#lib'; + +export const contentWithDuration: BushArgumentTypeCaster<Promise<ParsedDuration>> = async (_, phrase) => { + return parseDuration(phrase); +}; diff --git a/lib/arguments/discordEmoji.ts b/lib/arguments/discordEmoji.ts new file mode 100644 index 0000000..92d6502 --- /dev/null +++ b/lib/arguments/discordEmoji.ts @@ -0,0 +1,14 @@ +import { regex, type BushArgumentTypeCaster } from '#lib'; +import type { Snowflake } from 'discord.js'; + +export const discordEmoji: BushArgumentTypeCaster<DiscordEmojiInfo | null> = (_, phrase) => { + if (!phrase) return null; + const validEmoji: RegExpExecArray | null = regex.discordEmoji.exec(phrase); + if (!validEmoji || !validEmoji.groups) return null; + return { name: validEmoji.groups.name, id: validEmoji.groups.id }; +}; + +export interface DiscordEmojiInfo { + name: string; + id: Snowflake; +} diff --git a/lib/arguments/duration.ts b/lib/arguments/duration.ts new file mode 100644 index 0000000..09dd3d5 --- /dev/null +++ b/lib/arguments/duration.ts @@ -0,0 +1,5 @@ +import { parseDuration, type BushArgumentTypeCaster } from '#lib'; + +export const duration: BushArgumentTypeCaster<number | null> = (_, phrase) => { + return parseDuration(phrase).duration; +}; diff --git a/lib/arguments/durationSeconds.ts b/lib/arguments/durationSeconds.ts new file mode 100644 index 0000000..d8d6749 --- /dev/null +++ b/lib/arguments/durationSeconds.ts @@ -0,0 +1,6 @@ +import { parseDuration, type BushArgumentTypeCaster } from '#lib'; + +export const durationSeconds: BushArgumentTypeCaster<number | null> = (_, phrase) => { + phrase += 's'; + return parseDuration(phrase).duration; +}; diff --git a/lib/arguments/globalUser.ts b/lib/arguments/globalUser.ts new file mode 100644 index 0000000..4324aa9 --- /dev/null +++ b/lib/arguments/globalUser.ts @@ -0,0 +1,7 @@ +import type { BushArgumentTypeCaster } from '#lib'; +import type { User } from 'discord.js'; + +// resolve non-cached users +export const globalUser: BushArgumentTypeCaster<Promise<User | null>> = async (message, phrase) => { + return message.client.users.resolve(phrase) ?? (await message.client.users.fetch(`${phrase}`).catch(() => null)); +}; diff --git a/lib/arguments/index.ts b/lib/arguments/index.ts new file mode 100644 index 0000000..eebf0a2 --- /dev/null +++ b/lib/arguments/index.ts @@ -0,0 +1,10 @@ +export * from './abbreviatedNumber.js'; +export * from './contentWithDuration.js'; +export * from './discordEmoji.js'; +export * from './duration.js'; +export * from './durationSeconds.js'; +export * from './globalUser.js'; +export * from './messageLink.js'; +export * from './permission.js'; +export * from './roleWithDuration.js'; +export * from './snowflake.js'; diff --git a/lib/arguments/messageLink.ts b/lib/arguments/messageLink.ts new file mode 100644 index 0000000..c95e42d --- /dev/null +++ b/lib/arguments/messageLink.ts @@ -0,0 +1,20 @@ +import { BushArgumentTypeCaster, regex } from '#lib'; +import type { Message } from 'discord.js'; + +export const messageLink: BushArgumentTypeCaster<Promise<Message | null>> = async (message, phrase) => { + const match = new RegExp(regex.messageLink).exec(phrase); + if (!match || !match.groups) return null; + + const { guild_id, channel_id, message_id } = match.groups; + + if (!guild_id || !channel_id || message_id) return null; + + const guild = message.client.guilds.cache.get(guild_id); + if (!guild) return null; + + const channel = guild.channels.cache.get(channel_id); + if (!channel || (!channel.isTextBased() && !channel.isThread())) return null; + + const msg = await channel.messages.fetch(message_id).catch(() => null); + return msg; +}; diff --git a/lib/arguments/permission.ts b/lib/arguments/permission.ts new file mode 100644 index 0000000..98bfe74 --- /dev/null +++ b/lib/arguments/permission.ts @@ -0,0 +1,12 @@ +import type { BushArgumentTypeCaster } from '#lib'; +import { PermissionFlagsBits, type PermissionsString } from 'discord.js'; + +export const permission: BushArgumentTypeCaster<PermissionsString | null> = (_, phrase) => { + if (!phrase) return null; + phrase = phrase.toUpperCase().replace(/ /g, '_'); + if (!(phrase in PermissionFlagsBits)) { + return null; + } else { + return phrase as PermissionsString; + } +}; diff --git a/lib/arguments/roleWithDuration.ts b/lib/arguments/roleWithDuration.ts new file mode 100644 index 0000000..b97f205 --- /dev/null +++ b/lib/arguments/roleWithDuration.ts @@ -0,0 +1,17 @@ +import { Arg, BushArgumentTypeCaster, parseDuration } from '#lib'; +import type { Role } from 'discord.js'; + +export const roleWithDuration: BushArgumentTypeCaster<Promise<RoleWithDuration | null>> = async (message, phrase) => { + // eslint-disable-next-line prefer-const + let { duration, content } = parseDuration(phrase); + if (content === null || content === undefined) return null; + content = content.trim(); + const role = await Arg.cast('role', message, content); + if (!role) return null; + return { duration, role }; +}; + +export interface RoleWithDuration { + duration: number | null; + role: Role | null; +} diff --git a/lib/arguments/snowflake.ts b/lib/arguments/snowflake.ts new file mode 100644 index 0000000..b98a20f --- /dev/null +++ b/lib/arguments/snowflake.ts @@ -0,0 +1,8 @@ +import { BushArgumentTypeCaster, regex } from '#lib'; +import type { Snowflake } from 'discord.js'; + +export const snowflake: BushArgumentTypeCaster<Snowflake | null> = (_, phrase) => { + if (!phrase) return null; + if (regex.snowflake.test(phrase)) return phrase; + return null; +}; diff --git a/lib/arguments/tinyColor.ts b/lib/arguments/tinyColor.ts new file mode 100644 index 0000000..148c078 --- /dev/null +++ b/lib/arguments/tinyColor.ts @@ -0,0 +1,10 @@ +import type { BushArgumentTypeCaster } from '#lib'; +import assert from 'assert/strict'; +import tinycolorModule from 'tinycolor2'; +assert(tinycolorModule); + +export const tinyColor: BushArgumentTypeCaster<string | null> = (_message, phrase) => { + // if the phase is a number it converts it to hex incase it could be representing a color in decimal + const newPhase = isNaN(phrase as any) ? phrase : `#${Number(phrase).toString(16)}`; + return tinycolorModule(newPhase).isValid() ? newPhase : null; +}; |