From d9925a4ac45449791c36fe2d9362aeceed3a8db7 Mon Sep 17 00:00:00 2001 From: mierenmanz Date: Tue, 27 Apr 2021 23:04:27 +0200 Subject: [PATCH 01/23] add basic argument parsing (Still WIP) --- src/utils/command.ts | 86 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 src/utils/command.ts diff --git a/src/utils/command.ts b/src/utils/command.ts new file mode 100644 index 0000000..30c206e --- /dev/null +++ b/src/utils/command.ts @@ -0,0 +1,86 @@ +export enum MatchTypes { + 'flag', + 'mention', + 'content', + 'rest' +} + +export interface Args { + name: string + match: MatchTypes + type?: unknown // Still needs to be implemented + defaultValue?: unknown // Still needs to be implemented + flag?: string +} + +const mentionRegex = /([0-9]{18})/g + +export function parseArgs2( + commandArgs: Args[], + messageArgs: string[] +): Record { + const messageArgsNullableCopy: Array = [...messageArgs] + const args: Record = {} + for (const entry of commandArgs) { + switch (entry.match) { + case MatchTypes.flag: + parseFlags(args, entry, messageArgsNullableCopy) + break + case MatchTypes.mention: + parseMention(args, entry, messageArgsNullableCopy) + break + case MatchTypes.content: + parseContent(args, entry, messageArgs) + break + case MatchTypes.rest: + parseRest(args, entry, messageArgsNullableCopy) + break + } + } + return args +} + +function parseFlags( + args: Record, + entry: Args, + argsNullable: Array +): void { + for (let i = 0; i < argsNullable.length; i++) { + if (entry.flag === argsNullable[i]) { + argsNullable[i] = null + args[entry.name] = true + break + } else args[entry.name] = entry.defaultValue + } + return +} + +function parseMention( + args: Record, + entry: Args, + argsNullable: Array +): void { + const index = argsNullable.findIndex((x) => typeof x === 'string') + const mention = mentionRegex.exec(argsNullable[index]!)![0] + argsNullable[index] = null + args[entry.name] = mention + return +} + +function parseContent( + args: Record, + entry: Args, + argsNonNullable: Array +): void { + args[entry.name] = + argsNonNullable.length !== 0 ? argsNonNullable : entry.defaultValue + return +} + +function parseRest( + args: Record, + entry: Args, + argsNullable: Array +): void { + args[entry.name] = argsNullable.filter((x) => typeof x === 'string') +} From 7f96dfebc3ba1598838949939b4810bafff685f7 Mon Sep 17 00:00:00 2001 From: mierenmanz Date: Wed, 28 Apr 2021 11:52:05 +0200 Subject: [PATCH 02/23] add args parser into command class (not tested) --- src/commands/client.ts | 3 ++- src/commands/command.ts | 8 ++++---- src/utils/command.ts | 7 ++++--- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/commands/client.ts b/src/commands/client.ts index 22b0117..9442f4f 100644 --- a/src/commands/client.ts +++ b/src/commands/client.ts @@ -9,6 +9,7 @@ import { CommandsManager, parseCommand } from './command.ts' +import { parseArgs } from '../utils/command.ts' import { Extension, ExtensionsManager } from './extension.ts' type PrefixReturnType = string | string[] | Promise @@ -239,7 +240,7 @@ export class CommandClient extends Client implements CommandClientOptions { client: this, name: parsed.name, prefix, - args: parsed.args, + args: parseArgs(command.args, parsed.args), argString: parsed.argString, message: msg, author: msg.author, diff --git a/src/commands/command.ts b/src/commands/command.ts index 987eaee..8601d70 100644 --- a/src/commands/command.ts +++ b/src/commands/command.ts @@ -6,7 +6,7 @@ import { Collection } from '../utils/collection.ts' import type { CommandClient } from './client.ts' import type { Extension } from './extension.ts' import { join, walk } from '../../deps.ts' - +import type { Args } from '../utils/command.ts' export interface CommandContext { /** The Client object */ client: CommandClient @@ -23,7 +23,7 @@ export interface CommandContext { /** Name of Command which was used */ name: string /** Array of Arguments used with Command */ - args: string[] + args: Record | null /** Complete Raw String of Arguments */ argString: string /** Guild which the command has called */ @@ -46,7 +46,7 @@ export interface CommandOptions { /** Usage Example of Command, only Arguments (without Prefix and Name) */ examples?: string | string[] /** Does the Command take Arguments? Maybe number of required arguments? Or list of arguments? */ - args?: number | boolean | string[] + args?: Args[] /** Permissions(s) required by both User and Bot in order to use Command */ permissions?: string | string[] /** Permission(s) required for using Command */ @@ -81,7 +81,7 @@ export class Command implements CommandOptions { extension?: Extension usage?: string | string[] examples?: string | string[] - args?: number | boolean | string[] + args?: Args[] permissions?: string | string[] userPermissions?: string | string[] botPermissions?: string | string[] diff --git a/src/utils/command.ts b/src/utils/command.ts index 30c206e..f8b34ac 100644 --- a/src/utils/command.ts +++ b/src/utils/command.ts @@ -15,10 +15,11 @@ export interface Args { const mentionRegex = /([0-9]{18})/g -export function parseArgs2( - commandArgs: Args[], +export function parseArgs( + commandArgs: Args[] | undefined, messageArgs: string[] -): Record { +): Record | null { + if (!commandArgs) return null const messageArgsNullableCopy: Array = [...messageArgs] const args: Record = {} for (const entry of commandArgs) { From ff655e0b7d83f45c71110e011789a936c6d2cdc9 Mon Sep 17 00:00:00 2001 From: mierenmanz Date: Wed, 28 Apr 2021 12:43:01 +0200 Subject: [PATCH 03/23] export utils/command.ts --- mod.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/mod.ts b/mod.ts index f2a0842..57f6488 100644 --- a/mod.ts +++ b/mod.ts @@ -191,3 +191,4 @@ export { isVoiceChannel, default as getChannelByType } from './src/utils/channel.ts' +export * from "./src/utils/command.ts" \ No newline at end of file From 8ac716d6a93eae2fe58c7b27c3ba04103146dff3 Mon Sep 17 00:00:00 2001 From: mierenmanz Date: Wed, 28 Apr 2021 12:43:16 +0200 Subject: [PATCH 04/23] change enum to type --- src/utils/command.ts | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/src/utils/command.ts b/src/utils/command.ts index f8b34ac..7323838 100644 --- a/src/utils/command.ts +++ b/src/utils/command.ts @@ -1,13 +1,8 @@ -export enum MatchTypes { - 'flag', - 'mention', - 'content', - 'rest' -} +export type CommandArgumentMatchTypes = 'flag' | 'mention' | 'content' | 'rest' export interface Args { name: string - match: MatchTypes + match: CommandArgumentMatchTypes type?: unknown // Still needs to be implemented defaultValue?: unknown // Still needs to be implemented flag?: string @@ -24,16 +19,16 @@ export function parseArgs( const args: Record = {} for (const entry of commandArgs) { switch (entry.match) { - case MatchTypes.flag: + case "flag": parseFlags(args, entry, messageArgsNullableCopy) break - case MatchTypes.mention: + case 'mention': parseMention(args, entry, messageArgsNullableCopy) break - case MatchTypes.content: + case 'content': parseContent(args, entry, messageArgs) break - case MatchTypes.rest: + case 'rest': parseRest(args, entry, messageArgsNullableCopy) break } From e7715b75cf7e72aa643e16a4ba4657a2086e6463 Mon Sep 17 00:00:00 2001 From: mierenmanz Date: Wed, 28 Apr 2021 13:50:13 +0200 Subject: [PATCH 05/23] fix lint? --- src/utils/command.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/utils/command.ts b/src/utils/command.ts index 7323838..e604427 100644 --- a/src/utils/command.ts +++ b/src/utils/command.ts @@ -14,12 +14,12 @@ export function parseArgs( commandArgs: Args[] | undefined, messageArgs: string[] ): Record | null { - if (!commandArgs) return null + if (commandArgs === undefined) return null const messageArgsNullableCopy: Array = [...messageArgs] const args: Record = {} for (const entry of commandArgs) { switch (entry.match) { - case "flag": + case 'flag': parseFlags(args, entry, messageArgsNullableCopy) break case 'mention': @@ -48,7 +48,6 @@ function parseFlags( break } else args[entry.name] = entry.defaultValue } - return } function parseMention( @@ -60,7 +59,6 @@ function parseMention( const mention = mentionRegex.exec(argsNullable[index]!)![0] argsNullable[index] = null args[entry.name] = mention - return } function parseContent( @@ -70,7 +68,6 @@ function parseContent( ): void { args[entry.name] = argsNonNullable.length !== 0 ? argsNonNullable : entry.defaultValue - return } function parseRest( From 58ad6fcd3d59c388c7350d063c9b1ccc6087864a Mon Sep 17 00:00:00 2001 From: mierenmanz Date: Wed, 28 Apr 2021 15:09:39 +0200 Subject: [PATCH 06/23] misc changes --- src/utils/command.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/utils/command.ts b/src/utils/command.ts index e604427..d4b699f 100644 --- a/src/utils/command.ts +++ b/src/utils/command.ts @@ -1,14 +1,15 @@ +import { MessageMentions } from "../structures/messageMentions.ts"; export type CommandArgumentMatchTypes = 'flag' | 'mention' | 'content' | 'rest' export interface Args { name: string match: CommandArgumentMatchTypes - type?: unknown // Still needs to be implemented - defaultValue?: unknown // Still needs to be implemented + // Still needs to be implemented + // type?: unknown + defaultValue?: string; flag?: string } -const mentionRegex = /([0-9]{18})/g export function parseArgs( commandArgs: Args[] | undefined, @@ -56,7 +57,7 @@ function parseMention( argsNullable: Array ): void { const index = argsNullable.findIndex((x) => typeof x === 'string') - const mention = mentionRegex.exec(argsNullable[index]!)![0] + const mention = MessageMentions.USER_MENTION.exec(argsNullable[index]!)![0] argsNullable[index] = null args[entry.name] = mention } From 1c25e2d3a15163375d410cfc4b7408cf602ed70a Mon Sep 17 00:00:00 2001 From: mierenmanz Date: Wed, 28 Apr 2021 15:57:59 +0200 Subject: [PATCH 07/23] add test (fails at the moment) --- test/argsparser_test.ts | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 test/argsparser_test.ts diff --git a/test/argsparser_test.ts b/test/argsparser_test.ts new file mode 100644 index 0000000..96c1a9a --- /dev/null +++ b/test/argsparser_test.ts @@ -0,0 +1,30 @@ +import { parseArgs, Args } from "../src/utils/command.ts"; +import { assertEquals } from "https://deno.land/std@0.95.0/testing/asserts.ts" + +const commandArgs: Args[] = [{ + name: "permaban", + match: "flag", + flag: "--permanent", + }, { + name: "user", + match: "mention", + }, { + name: "reason", + match: "rest", + }]; +const messageArgs: string[] = ["<@!708544768342229012>","--permanent","bye","bye","Skyler"]; +const expectedResult = { + permaban: true, + user: "708544768342229012", + reason: ["bye","bye","Skyler"] +} +Deno.test({ + name: "parse Args", + fn: () => { + const result = parseArgs(commandArgs,messageArgs); + assertEquals(result, expectedResult) + }, + sanitizeOps: true, + sanitizeResources: true, + sanitizeExit: true, +}) \ No newline at end of file From eac9c4bceb6296460bb303f607c81e2ca43f5a74 Mon Sep 17 00:00:00 2001 From: mierenmanz Date: Wed, 28 Apr 2021 16:17:39 +0200 Subject: [PATCH 08/23] fix test --- src/utils/command.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/utils/command.ts b/src/utils/command.ts index d4b699f..6debad4 100644 --- a/src/utils/command.ts +++ b/src/utils/command.ts @@ -1,4 +1,4 @@ -import { MessageMentions } from "../structures/messageMentions.ts"; +import { MessageMentions } from '../structures/messageMentions.ts' export type CommandArgumentMatchTypes = 'flag' | 'mention' | 'content' | 'rest' export interface Args { @@ -6,11 +6,10 @@ export interface Args { match: CommandArgumentMatchTypes // Still needs to be implemented // type?: unknown - defaultValue?: string; + defaultValue?: string flag?: string } - export function parseArgs( commandArgs: Args[] | undefined, messageArgs: string[] @@ -57,9 +56,12 @@ function parseMention( argsNullable: Array ): void { const index = argsNullable.findIndex((x) => typeof x === 'string') - const mention = MessageMentions.USER_MENTION.exec(argsNullable[index]!)![0] + const regexMatches = MessageMentions.USER_MENTION.exec(argsNullable[index]!) + args[entry.name] = + regexMatches !== null + ? regexMatches[0].replace(MessageMentions.USER_MENTION, '$1') + : null argsNullable[index] = null - args[entry.name] = mention } function parseContent( From 97298f17f8470e2cb125e765e7c6e0c0ebfd8334 Mon Sep 17 00:00:00 2001 From: mierenmanz Date: Wed, 28 Apr 2021 16:23:39 +0200 Subject: [PATCH 09/23] add default value --- src/utils/command.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/utils/command.ts b/src/utils/command.ts index 6debad4..3cfa939 100644 --- a/src/utils/command.ts +++ b/src/utils/command.ts @@ -43,10 +43,10 @@ function parseFlags( ): void { for (let i = 0; i < argsNullable.length; i++) { if (entry.flag === argsNullable[i]) { - argsNullable[i] = null args[entry.name] = true break - } else args[entry.name] = entry.defaultValue + } else args[entry.name] = entry.defaultValue ?? false; + argsNullable[i] = null } } @@ -60,7 +60,7 @@ function parseMention( args[entry.name] = regexMatches !== null ? regexMatches[0].replace(MessageMentions.USER_MENTION, '$1') - : null + : entry.defaultValue argsNullable[index] = null } @@ -78,5 +78,6 @@ function parseRest( entry: Args, argsNullable: Array ): void { - args[entry.name] = argsNullable.filter((x) => typeof x === 'string') + const restValues = argsNullable.filter((x) => typeof x === 'string') + args[entry.name] = restValues !== null ? restValues : entry.defaultValue; } From 9c18ec2d1f0ad8c9b3f8f0b4e20d29e87fc92708 Mon Sep 17 00:00:00 2001 From: mierenmanz Date: Wed, 28 Apr 2021 16:56:30 +0200 Subject: [PATCH 10/23] change type to allow for proper defaults --- src/utils/command.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/utils/command.ts b/src/utils/command.ts index 3cfa939..713857e 100644 --- a/src/utils/command.ts +++ b/src/utils/command.ts @@ -6,7 +6,7 @@ export interface Args { match: CommandArgumentMatchTypes // Still needs to be implemented // type?: unknown - defaultValue?: string + defaultValue?: unknown flag?: string } @@ -15,8 +15,10 @@ export function parseArgs( messageArgs: string[] ): Record | null { if (commandArgs === undefined) return null + const messageArgsNullableCopy: Array = [...messageArgs] const args: Record = {} + for (const entry of commandArgs) { switch (entry.match) { case 'flag': From e6c0c378decd7c5996e556d5d827919e3c2923de Mon Sep 17 00:00:00 2001 From: mierenmanz Date: Wed, 28 Apr 2021 20:22:54 +0200 Subject: [PATCH 11/23] added more tests --- test/argsparser_test.ts | 59 +++++++++++++++++++++++++++++++++++------ 1 file changed, 51 insertions(+), 8 deletions(-) diff --git a/test/argsparser_test.ts b/test/argsparser_test.ts index 96c1a9a..1d3b07f 100644 --- a/test/argsparser_test.ts +++ b/test/argsparser_test.ts @@ -1,28 +1,71 @@ import { parseArgs, Args } from "../src/utils/command.ts"; -import { assertEquals } from "https://deno.land/std@0.95.0/testing/asserts.ts" +import { assertEquals, assertNotEquals } from "https://deno.land/std@0.95.0/testing/asserts.ts" -const commandArgs: Args[] = [{ +// debugger +const commandArgs: Args[] = [ + { name: "permaban", match: "flag", flag: "--permanent", + defaultValue: true, }, { name: "user", match: "mention", }, { name: "reason", match: "rest", - }]; -const messageArgs: string[] = ["<@!708544768342229012>","--permanent","bye","bye","Skyler"]; -const expectedResult = { + defaultValue: "ree" + } +]; + +const messageArgs1: string[] = ["<@!708544768342229012>","--permanent","bye","bye","Skyler"]; +const expectedResult1 = { permaban: true, user: "708544768342229012", reason: ["bye","bye","Skyler"] } + Deno.test({ - name: "parse Args", + name: "parse command arguments 1 (assertEquals)", fn: () => { - const result = parseArgs(commandArgs,messageArgs); - assertEquals(result, expectedResult) + const result = parseArgs(commandArgs,messageArgs1); + assertEquals(result, expectedResult1) + }, + sanitizeOps: true, + sanitizeResources: true, + sanitizeExit: true, +}) + +const messageArgs2: string[] = ["<@!708544768342229012>","bye","bye","Skyler"]; +const expectedResult2 = { + permaban: true, + user: "708544768342229012", + reason: ["bye","bye","Skyler"] +} + +Deno.test({ + name: "parse command arguments 2 (assertEquals)", + fn: () => { + const result = parseArgs(commandArgs, messageArgs2); + assertEquals(result, expectedResult2) + }, + sanitizeOps: true, + sanitizeResources: true, + sanitizeExit: true, +}) + +const messageArgs3: string[] = ["<@!708544768342229012>","bye","bye","Skyler"]; +const expectedResult3 = { + permaban: false, + user: "708544768342229012", + reason: ["bye","bye","Skyler"] +} + +Deno.test({ + name: "parse command arguments 3 (assertNotEquals)", + fn: () => { + const result = parseArgs(commandArgs, messageArgs3); + assertNotEquals(result, expectedResult3) }, sanitizeOps: true, sanitizeResources: true, From 0a871023c8e545d8f4d011d6216afe7e5dc3bfd3 Mon Sep 17 00:00:00 2001 From: mierenmanz Date: Wed, 28 Apr 2021 20:23:06 +0200 Subject: [PATCH 12/23] fixed 2 bugs related to parsing --- src/utils/command.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utils/command.ts b/src/utils/command.ts index 713857e..06dcc1e 100644 --- a/src/utils/command.ts +++ b/src/utils/command.ts @@ -45,10 +45,10 @@ function parseFlags( ): void { for (let i = 0; i < argsNullable.length; i++) { if (entry.flag === argsNullable[i]) { + argsNullable[i] = null args[entry.name] = true break } else args[entry.name] = entry.defaultValue ?? false; - argsNullable[i] = null } } @@ -72,7 +72,7 @@ function parseContent( argsNonNullable: Array ): void { args[entry.name] = - argsNonNullable.length !== 0 ? argsNonNullable : entry.defaultValue + argsNonNullable.length > 0 ? argsNonNullable : entry.defaultValue } function parseRest( From dcbf635860b3e1cb91e6558df5353be61ef51d51 Mon Sep 17 00:00:00 2001 From: mierenmanz Date: Wed, 28 Apr 2021 20:28:19 +0200 Subject: [PATCH 13/23] formatting --- test/argsparser_test.ts | 87 +++++++++++++++++++++++++---------------- 1 file changed, 54 insertions(+), 33 deletions(-) diff --git a/test/argsparser_test.ts b/test/argsparser_test.ts index 1d3b07f..c51f749 100644 --- a/test/argsparser_test.ts +++ b/test/argsparser_test.ts @@ -1,73 +1,94 @@ -import { parseArgs, Args } from "../src/utils/command.ts"; -import { assertEquals, assertNotEquals } from "https://deno.land/std@0.95.0/testing/asserts.ts" +import { parseArgs, Args } from '../src/utils/command.ts' +import { + assertEquals, + assertNotEquals +} from 'https://deno.land/std@0.95.0/testing/asserts.ts' // debugger const commandArgs: Args[] = [ { - name: "permaban", - match: "flag", - flag: "--permanent", - defaultValue: true, - }, { - name: "user", - match: "mention", - }, { - name: "reason", - match: "rest", - defaultValue: "ree" + name: 'permaban', + match: 'flag', + flag: '--permanent', + defaultValue: true + }, + { + name: 'user', + match: 'mention' + }, + { + name: 'reason', + match: 'rest', + defaultValue: 'ree' } -]; +] -const messageArgs1: string[] = ["<@!708544768342229012>","--permanent","bye","bye","Skyler"]; +const messageArgs1: string[] = [ + '<@!708544768342229012>', + '--permanent', + 'bye', + 'bye', + 'Skyler' +] const expectedResult1 = { permaban: true, - user: "708544768342229012", - reason: ["bye","bye","Skyler"] + user: '708544768342229012', + reason: ['bye', 'bye', 'Skyler'] } Deno.test({ - name: "parse command arguments 1 (assertEquals)", + name: 'parse command arguments 1 (assertEquals)', fn: () => { - const result = parseArgs(commandArgs,messageArgs1); + const result = parseArgs(commandArgs, messageArgs1) assertEquals(result, expectedResult1) }, sanitizeOps: true, sanitizeResources: true, - sanitizeExit: true, + sanitizeExit: true }) -const messageArgs2: string[] = ["<@!708544768342229012>","bye","bye","Skyler"]; +const messageArgs2: string[] = [ + '<@!708544768342229012>', + 'bye', + 'bye', + 'Skyler' +] const expectedResult2 = { permaban: true, - user: "708544768342229012", - reason: ["bye","bye","Skyler"] + user: '708544768342229012', + reason: ['bye', 'bye', 'Skyler'] } Deno.test({ - name: "parse command arguments 2 (assertEquals)", + name: 'parse command arguments 2 (assertEquals)', fn: () => { - const result = parseArgs(commandArgs, messageArgs2); + const result = parseArgs(commandArgs, messageArgs2) assertEquals(result, expectedResult2) }, sanitizeOps: true, sanitizeResources: true, - sanitizeExit: true, + sanitizeExit: true }) -const messageArgs3: string[] = ["<@!708544768342229012>","bye","bye","Skyler"]; +const messageArgs3: string[] = [ + '<@!708544768342229012>', + 'bye', + 'bye', + 'Skyler' +] const expectedResult3 = { permaban: false, - user: "708544768342229012", - reason: ["bye","bye","Skyler"] + user: '708544768342229012', + reason: ['bye', 'bye', 'Skyler'] } Deno.test({ - name: "parse command arguments 3 (assertNotEquals)", + name: 'parse command arguments 3 (assertNotEquals)', fn: () => { - const result = parseArgs(commandArgs, messageArgs3); + const result = parseArgs(commandArgs, messageArgs3) assertNotEquals(result, expectedResult3) }, sanitizeOps: true, sanitizeResources: true, - sanitizeExit: true, -}) \ No newline at end of file + sanitizeExit: true +}) From bffead6680557b45a764a8f2e16eb4a60acb7691 Mon Sep 17 00:00:00 2001 From: mierenmanz Date: Wed, 28 Apr 2021 20:29:27 +0200 Subject: [PATCH 14/23] fmt --- src/utils/command.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/utils/command.ts b/src/utils/command.ts index 06dcc1e..24ab22c 100644 --- a/src/utils/command.ts +++ b/src/utils/command.ts @@ -15,7 +15,7 @@ export function parseArgs( messageArgs: string[] ): Record | null { if (commandArgs === undefined) return null - + const messageArgsNullableCopy: Array = [...messageArgs] const args: Record = {} @@ -48,7 +48,7 @@ function parseFlags( argsNullable[i] = null args[entry.name] = true break - } else args[entry.name] = entry.defaultValue ?? false; + } else args[entry.name] = entry.defaultValue ?? false } } @@ -81,5 +81,5 @@ function parseRest( argsNullable: Array ): void { const restValues = argsNullable.filter((x) => typeof x === 'string') - args[entry.name] = restValues !== null ? restValues : entry.defaultValue; + args[entry.name] = restValues !== null ? restValues : entry.defaultValue } From 1c9d17263b050653ae25b62488c4b13fd9ae2edf Mon Sep 17 00:00:00 2001 From: mierenmanz Date: Wed, 28 Apr 2021 21:28:09 +0200 Subject: [PATCH 15/23] extend test --- test/argsparser_test.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/test/argsparser_test.ts b/test/argsparser_test.ts index c51f749..d78ce62 100644 --- a/test/argsparser_test.ts +++ b/test/argsparser_test.ts @@ -6,6 +6,10 @@ import { // debugger const commandArgs: Args[] = [ + { + name: 'originalMessage', + match: 'content' + }, { name: 'permaban', match: 'flag', @@ -31,12 +35,20 @@ const messageArgs1: string[] = [ 'Skyler' ] const expectedResult1 = { + originalMessage: [ + '<@!708544768342229012>', + '--permanent', + 'bye', + 'bye', + 'Skyler' + ], permaban: true, user: '708544768342229012', reason: ['bye', 'bye', 'Skyler'] } Deno.test({ + only: false, name: 'parse command arguments 1 (assertEquals)', fn: () => { const result = parseArgs(commandArgs, messageArgs1) @@ -54,6 +66,7 @@ const messageArgs2: string[] = [ 'Skyler' ] const expectedResult2 = { + originalMessage: ['<@!708544768342229012>', 'bye', 'bye', 'Skyler'], permaban: true, user: '708544768342229012', reason: ['bye', 'bye', 'Skyler'] From 9d6feaff8d1375d018bffd176f38407aed91caff Mon Sep 17 00:00:00 2001 From: mierenmanz Date: Wed, 28 Apr 2021 21:28:30 +0200 Subject: [PATCH 16/23] add generic type (I give up on generated types for now) --- src/utils/command.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/utils/command.ts b/src/utils/command.ts index 24ab22c..4e963ee 100644 --- a/src/utils/command.ts +++ b/src/utils/command.ts @@ -1,12 +1,10 @@ import { MessageMentions } from '../structures/messageMentions.ts' export type CommandArgumentMatchTypes = 'flag' | 'mention' | 'content' | 'rest' -export interface Args { +export interface Args { name: string match: CommandArgumentMatchTypes - // Still needs to be implemented - // type?: unknown - defaultValue?: unknown + defaultValue?: T flag?: string } From b3220fa1550e7b9b61479a690c329291c2608fdb Mon Sep 17 00:00:00 2001 From: mierenmanz Date: Thu, 29 Apr 2021 11:05:31 +0200 Subject: [PATCH 17/23] don't assume that the first string found is a mention --- src/utils/command.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/utils/command.ts b/src/utils/command.ts index 4e963ee..11fe653 100644 --- a/src/utils/command.ts +++ b/src/utils/command.ts @@ -55,7 +55,9 @@ function parseMention( entry: Args, argsNullable: Array ): void { - const index = argsNullable.findIndex((x) => typeof x === 'string') + const index = argsNullable.findIndex( + (x) => typeof x === 'string' && x.includes('<@!') + ) const regexMatches = MessageMentions.USER_MENTION.exec(argsNullable[index]!) args[entry.name] = regexMatches !== null From 222f1d0fa8f9ac4f5be6ea1a23d5fbafb971bd29 Mon Sep 17 00:00:00 2001 From: mierenmanz Date: Thu, 29 Apr 2021 12:10:50 +0200 Subject: [PATCH 18/23] parseMention now parses channel & roles mentions --- src/utils/command.ts | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/src/utils/command.ts b/src/utils/command.ts index 11fe653..6ae5901 100644 --- a/src/utils/command.ts +++ b/src/utils/command.ts @@ -1,5 +1,23 @@ -import { MessageMentions } from '../structures/messageMentions.ts' -export type CommandArgumentMatchTypes = 'flag' | 'mention' | 'content' | 'rest' +interface MentionToRegex { + [key: string]: RegExp + mentionUser: RegExp + mentionRole: RegExp + mentionChannel: RegExp +} + +const mentionToRegex: MentionToRegex = { + mentionUser: /<@!?(\d{17,19})>/g, + mentionRole: /<@&(\d{17,19})>/g, + mentionChannel: /<#(\d{17,19})>/g +} + +export type CommandArgumentMatchTypes = + | 'flag' + | 'mentionUser' + | 'mentionRole' + | 'mentionChannel' + | 'content' + | 'rest' export interface Args { name: string @@ -22,7 +40,9 @@ export function parseArgs( case 'flag': parseFlags(args, entry, messageArgsNullableCopy) break - case 'mention': + case 'mentionUser': + case 'mentionRole': + case 'mentionChannel': parseMention(args, entry, messageArgsNullableCopy) break case 'content': @@ -55,13 +75,14 @@ function parseMention( entry: Args, argsNullable: Array ): void { + const regex = mentionToRegex[entry.match] const index = argsNullable.findIndex( - (x) => typeof x === 'string' && x.includes('<@!') + (x) => typeof x === 'string' && regex.test(x) ) - const regexMatches = MessageMentions.USER_MENTION.exec(argsNullable[index]!) + const regexMatches = regex.exec(argsNullable[index]!) args[entry.name] = regexMatches !== null - ? regexMatches[0].replace(MessageMentions.USER_MENTION, '$1') + ? regexMatches[0].replace(regex, '$1') : entry.defaultValue argsNullable[index] = null } From de4e207d85c32b4246f216ca749df582c0288822 Mon Sep 17 00:00:00 2001 From: mierenmanz Date: Thu, 29 Apr 2021 12:43:03 +0200 Subject: [PATCH 19/23] remove global to fix bug --- src/utils/command.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/utils/command.ts b/src/utils/command.ts index 6ae5901..5b26af5 100644 --- a/src/utils/command.ts +++ b/src/utils/command.ts @@ -6,9 +6,9 @@ interface MentionToRegex { } const mentionToRegex: MentionToRegex = { - mentionUser: /<@!?(\d{17,19})>/g, - mentionRole: /<@&(\d{17,19})>/g, - mentionChannel: /<#(\d{17,19})>/g + mentionUser: /<@!?(\d{17,19})>/, + mentionRole: /<@&(\d{17,19})>/, + mentionChannel: /<#(\d{17,19})>/ } export type CommandArgumentMatchTypes = From 057b3ede539d7824f9b72bb7b0ce7d52f3fca198 Mon Sep 17 00:00:00 2001 From: mierenmanz Date: Thu, 29 Apr 2021 12:43:21 +0200 Subject: [PATCH 20/23] fix test for new behavior --- test/argsparser_test.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/test/argsparser_test.ts b/test/argsparser_test.ts index d78ce62..cc877c5 100644 --- a/test/argsparser_test.ts +++ b/test/argsparser_test.ts @@ -1,10 +1,9 @@ -import { parseArgs, Args } from '../src/utils/command.ts' +import { Args, parseArgs } from '../src/utils/command.ts' import { assertEquals, assertNotEquals } from 'https://deno.land/std@0.95.0/testing/asserts.ts' -// debugger const commandArgs: Args[] = [ { name: 'originalMessage', @@ -18,7 +17,7 @@ const commandArgs: Args[] = [ }, { name: 'user', - match: 'mention' + match: 'mentionUser' }, { name: 'reason', From a8bb3cc49b84e0fbf7ecb29de1274fc5a2587920 Mon Sep 17 00:00:00 2001 From: mierenmanz Date: Thu, 29 Apr 2021 19:34:16 +0200 Subject: [PATCH 21/23] add mention tests --- test/argsparser_test.ts | 49 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/test/argsparser_test.ts b/test/argsparser_test.ts index cc877c5..bd613f9 100644 --- a/test/argsparser_test.ts +++ b/test/argsparser_test.ts @@ -95,7 +95,7 @@ const expectedResult3 = { } Deno.test({ - name: 'parse command arguments 3 (assertNotEquals)', + name: 'parse command arguments default value (assertNotEquals)', fn: () => { const result = parseArgs(commandArgs, messageArgs3) assertNotEquals(result, expectedResult3) @@ -104,3 +104,50 @@ Deno.test({ sanitizeResources: true, sanitizeExit: true }) + + + +const commandArgs2: Args[] = [ + { + name: 'user', + match: 'mentionUser' + }, + { + name: 'channel', + match: 'mentionChannel' + }, + { + name: 'role', + match: 'mentionRole', + }, + { + name: 'reason', + match: 'rest', + defaultValue: 'ree' + } + +] + +const messageArgs4: string[] = [ + '<@!708544768342229012>', + 'bye', + '<#783319033730564098>', + '<@&836715188690092032>' +] +const expectedResult4 = { + channel: "783319033730564098", + role: "836715188690092032", + user: "708544768342229012", + reason: ["bye"] +} + +Deno.test({ + name: 'parse command arguments mentions (assertEquals)', + fn: () => { + const result = parseArgs(commandArgs2, messageArgs4) + assertEquals(result, expectedResult4) + }, + sanitizeOps: true, + sanitizeResources: true, + sanitizeExit: true +}) From 52ec39a24c2630b2292a02ff5a6d0371d399aa19 Mon Sep 17 00:00:00 2001 From: mierenmanz Date: Fri, 30 Apr 2021 08:13:45 +0200 Subject: [PATCH 22/23] `rest` string[] => string --- src/utils/command.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/utils/command.ts b/src/utils/command.ts index 5b26af5..4eda5bc 100644 --- a/src/utils/command.ts +++ b/src/utils/command.ts @@ -102,5 +102,6 @@ function parseRest( argsNullable: Array ): void { const restValues = argsNullable.filter((x) => typeof x === 'string') - args[entry.name] = restValues !== null ? restValues : entry.defaultValue + args[entry.name] = + restValues !== null ? restValues?.join(' ') : entry.defaultValue } From 6e084af4a3c53f86846621de48d57dbbbd5feb6a Mon Sep 17 00:00:00 2001 From: mierenmanz Date: Fri, 30 Apr 2021 08:15:13 +0200 Subject: [PATCH 23/23] add tests aswell --- test/argsparser_test.ts | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/test/argsparser_test.ts b/test/argsparser_test.ts index bd613f9..f428246 100644 --- a/test/argsparser_test.ts +++ b/test/argsparser_test.ts @@ -43,7 +43,7 @@ const expectedResult1 = { ], permaban: true, user: '708544768342229012', - reason: ['bye', 'bye', 'Skyler'] + reason: 'bye bye Skyler' } Deno.test({ @@ -68,7 +68,7 @@ const expectedResult2 = { originalMessage: ['<@!708544768342229012>', 'bye', 'bye', 'Skyler'], permaban: true, user: '708544768342229012', - reason: ['bye', 'bye', 'Skyler'] + reason: 'bye bye Skyler' } Deno.test({ @@ -91,7 +91,7 @@ const messageArgs3: string[] = [ const expectedResult3 = { permaban: false, user: '708544768342229012', - reason: ['bye', 'bye', 'Skyler'] + reason: 'bye bye Skyler' } Deno.test({ @@ -105,10 +105,8 @@ Deno.test({ sanitizeExit: true }) - - const commandArgs2: Args[] = [ - { + { name: 'user', match: 'mentionUser' }, @@ -118,14 +116,13 @@ const commandArgs2: Args[] = [ }, { name: 'role', - match: 'mentionRole', + match: 'mentionRole' }, { name: 'reason', match: 'rest', defaultValue: 'ree' } - ] const messageArgs4: string[] = [ @@ -135,10 +132,10 @@ const messageArgs4: string[] = [ '<@&836715188690092032>' ] const expectedResult4 = { - channel: "783319033730564098", - role: "836715188690092032", - user: "708544768342229012", - reason: ["bye"] + channel: '783319033730564098', + role: '836715188690092032', + user: '708544768342229012', + reason: 'bye' } Deno.test({