harmony/src/utils/command.ts

108 lines
2.6 KiB
TypeScript
Raw Normal View History

interface MentionToRegex {
[key: string]: RegExp
mentionUser: RegExp
mentionRole: RegExp
mentionChannel: RegExp
}
const mentionToRegex: MentionToRegex = {
2021-04-29 10:43:03 +00:00
mentionUser: /<@!?(\d{17,19})>/,
mentionRole: /<@&(\d{17,19})>/,
mentionChannel: /<#(\d{17,19})>/
}
export type CommandArgumentMatchTypes =
| 'flag'
| 'mentionUser'
| 'mentionRole'
| 'mentionChannel'
| 'content'
| 'rest'
2021-04-27 21:04:27 +00:00
export interface Args<T = unknown> {
2021-04-27 21:04:27 +00:00
name: string
2021-04-28 10:43:16 +00:00
match: CommandArgumentMatchTypes
defaultValue?: T
2021-04-27 21:04:27 +00:00
flag?: string
}
export function parseArgs(
commandArgs: Args[] | undefined,
2021-04-27 21:04:27 +00:00
messageArgs: string[]
): Record<string, unknown> | null {
2021-04-28 11:50:13 +00:00
if (commandArgs === undefined) return null
2021-04-28 18:29:27 +00:00
2021-04-27 21:04:27 +00:00
const messageArgsNullableCopy: Array<string | null> = [...messageArgs]
const args: Record<string, unknown> = {}
2021-04-27 21:04:27 +00:00
for (const entry of commandArgs) {
switch (entry.match) {
2021-04-28 11:50:13 +00:00
case 'flag':
2021-04-27 21:04:27 +00:00
parseFlags(args, entry, messageArgsNullableCopy)
break
case 'mentionUser':
case 'mentionRole':
case 'mentionChannel':
2021-04-27 21:04:27 +00:00
parseMention(args, entry, messageArgsNullableCopy)
break
2021-04-28 10:43:16 +00:00
case 'content':
2021-04-27 21:04:27 +00:00
parseContent(args, entry, messageArgs)
break
2021-04-28 10:43:16 +00:00
case 'rest':
2021-04-27 21:04:27 +00:00
parseRest(args, entry, messageArgsNullableCopy)
break
}
}
return args
}
function parseFlags(
args: Record<string, unknown>,
entry: Args,
argsNullable: Array<string | null>
): void {
for (let i = 0; i < argsNullable.length; i++) {
if (entry.flag === argsNullable[i]) {
2021-04-28 18:23:06 +00:00
argsNullable[i] = null
2021-04-27 21:04:27 +00:00
args[entry.name] = true
break
2021-04-28 18:29:27 +00:00
} else args[entry.name] = entry.defaultValue ?? false
2021-04-27 21:04:27 +00:00
}
}
function parseMention(
args: Record<string, unknown>,
entry: Args,
argsNullable: Array<string | null>
): void {
const regex = mentionToRegex[entry.match]
const index = argsNullable.findIndex(
(x) => typeof x === 'string' && regex.test(x)
)
const regexMatches = regex.exec(argsNullable[index]!)
2021-04-28 14:17:39 +00:00
args[entry.name] =
regexMatches !== null
? regexMatches[0].replace(regex, '$1')
2021-04-28 14:23:39 +00:00
: entry.defaultValue
2021-04-27 21:04:27 +00:00
argsNullable[index] = null
}
function parseContent(
args: Record<string, unknown>,
entry: Args,
argsNonNullable: Array<string | null>
): void {
args[entry.name] =
2021-04-28 18:23:06 +00:00
argsNonNullable.length > 0 ? argsNonNullable : entry.defaultValue
2021-04-27 21:04:27 +00:00
}
function parseRest(
args: Record<string, unknown>,
entry: Args,
argsNullable: Array<string | null>
): void {
2021-04-28 14:23:39 +00:00
const restValues = argsNullable.filter((x) => typeof x === 'string')
2021-04-30 06:13:45 +00:00
args[entry.name] =
restValues.length > 0 ? restValues?.join(' ') : entry.defaultValue
2021-04-27 21:04:27 +00:00
}