fix & improve args processing

This commit is contained in:
Isaac 2021-05-10 23:10:39 +01:00
parent b8672a8906
commit de93d586fe
No known key found for this signature in database
GPG Key ID: F6812DBC6719B4E3
4 changed files with 51 additions and 8 deletions

View File

@ -30,6 +30,7 @@
"dependencies": { "dependencies": {
"@eartharoid/i18n": "^1.0.0", "@eartharoid/i18n": "^1.0.0",
"boxen": "^5.0.0", "boxen": "^5.0.0",
"command-line-args": "^5.1.1",
"cryptr": "^6.0.2", "cryptr": "^6.0.2",
"discord.js": "^12.5.1", "discord.js": "^12.5.1",
"dotenv": "^8.2.0", "dotenv": "^8.2.0",
@ -38,6 +39,7 @@
"node-fetch": "^2.6.1", "node-fetch": "^2.6.1",
"semver": "^7.3.4", "semver": "^7.3.4",
"sequelize": "^6.5.0", "sequelize": "^6.5.0",
"string-argv": "^0.3.1",
"terminal-link": "^2.1.1" "terminal-link": "^2.1.1"
}, },
"devDependencies": { "devDependencies": {

View File

@ -3,6 +3,7 @@ lockfileVersion: 5.3
specifiers: specifiers:
'@eartharoid/i18n': ^1.0.0 '@eartharoid/i18n': ^1.0.0
boxen: ^5.0.0 boxen: ^5.0.0
command-line-args: ^5.1.1
cryptr: ^6.0.2 cryptr: ^6.0.2
discord.js: ^12.5.1 discord.js: ^12.5.1
dotenv: ^8.2.0 dotenv: ^8.2.0
@ -18,12 +19,14 @@ specifiers:
semver: ^7.3.4 semver: ^7.3.4
sequelize: ^6.5.0 sequelize: ^6.5.0
sqlite3: ^5.0.2 sqlite3: ^5.0.2
string-argv: ^0.3.1
tedious: ^11.0.3 tedious: ^11.0.3
terminal-link: ^2.1.1 terminal-link: ^2.1.1
dependencies: dependencies:
'@eartharoid/i18n': 1.0.0 '@eartharoid/i18n': 1.0.0
boxen: 5.0.0 boxen: 5.0.0
command-line-args: 5.1.1
cryptr: 6.0.2 cryptr: 6.0.2
discord.js: 12.5.1 discord.js: 12.5.1
dotenv: 8.2.0 dotenv: 8.2.0
@ -32,6 +35,7 @@ dependencies:
node-fetch: 2.6.1 node-fetch: 2.6.1
semver: 7.3.4 semver: 7.3.4
sequelize: 6.5.0_fb66e8c649bde1be622cc06164c9e22d sequelize: 6.5.0_fb66e8c649bde1be622cc06164c9e22d
string-argv: 0.3.1
terminal-link: 2.1.1 terminal-link: 2.1.1
optionalDependencies: optionalDependencies:
@ -338,6 +342,11 @@ packages:
sprintf-js: 1.0.3 sprintf-js: 1.0.3
dev: true dev: true
/array-back/3.1.0:
resolution: {integrity: sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==}
engines: {node: '>=6'}
dev: false
/asn1/0.2.4: /asn1/0.2.4:
resolution: {integrity: sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==} resolution: {integrity: sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==}
dependencies: dependencies:
@ -589,6 +598,16 @@ packages:
dependencies: dependencies:
delayed-stream: 1.0.0 delayed-stream: 1.0.0
/command-line-args/5.1.1:
resolution: {integrity: sha512-hL/eG8lrll1Qy1ezvkant+trihbGnaKaeEjj6Scyr3DN+RC7iQ5Rz84IeLERfAWDGo0HBSNAakczwgCilDXnWg==}
engines: {node: '>=4.0.0'}
dependencies:
array-back: 3.1.0
find-replace: 3.0.0
lodash.camelcase: 4.3.0
typical: 4.0.0
dev: false
/concat-map/0.0.1: /concat-map/0.0.1:
resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=} resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=}
@ -955,6 +974,13 @@ packages:
to-regex-range: 5.0.1 to-regex-range: 5.0.1
dev: true dev: true
/find-replace/3.0.0:
resolution: {integrity: sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==}
engines: {node: '>=4.0.0'}
dependencies:
array-back: 3.1.0
dev: false
/flat-cache/3.0.4: /flat-cache/3.0.4:
resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==} resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==}
engines: {node: ^10.12.0 || >=12.0.0} engines: {node: ^10.12.0 || >=12.0.0}
@ -1451,6 +1477,10 @@ packages:
type-check: 0.4.0 type-check: 0.4.0
dev: true dev: true
/lodash.camelcase/4.3.0:
resolution: {integrity: sha1-soqmKIorn8ZRA1x3EfZathkDMaY=}
dev: false
/lodash/4.17.20: /lodash/4.17.20:
resolution: {integrity: sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==} resolution: {integrity: sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==}
@ -2311,6 +2341,11 @@ packages:
safer-buffer: 2.1.2 safer-buffer: 2.1.2
tweetnacl: 0.14.5 tweetnacl: 0.14.5
/string-argv/0.3.1:
resolution: {integrity: sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==}
engines: {node: '>=0.6.19'}
dev: false
/string-width/1.0.2: /string-width/1.0.2:
resolution: {integrity: sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=} resolution: {integrity: sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
@ -2571,6 +2606,11 @@ packages:
is-typedarray: 1.0.0 is-typedarray: 1.0.0
dev: true dev: true
/typical/4.0.0:
resolution: {integrity: sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==}
engines: {node: '>=8'}
dev: false
/undefsafe/2.0.3: /undefsafe/2.0.3:
resolution: {integrity: sha512-nrXZwwXrD/T/JXeygJqdCO6NZZ1L66HrxM/Z7mIq2oPanoN0F1nLx3lwJMu6AwJY69hdixaFQOuoYsMjE5/C2A==} resolution: {integrity: sha512-nrXZwwXrD/T/JXeygJqdCO6NZZ1L66HrxM/Z7mIq2oPanoN0F1nLx3lwJMu6AwJY69hdixaFQOuoYsMjE5/C2A==}
dependencies: dependencies:

View File

@ -21,7 +21,7 @@ module.exports = class Command {
* @param {boolean} [data.staff_only] - Only allow staff to use this command? * @param {boolean} [data.staff_only] - Only allow staff to use this command?
* @param {string[]} [data.permissions] - Array of permissions needed for a user to use this command * @param {string[]} [data.permissions] - Array of permissions needed for a user to use this command
* @param {boolean} [data.process_args] - Should the command handler process named arguments? * @param {boolean} [data.process_args] - Should the command handler process named arguments?
* @param {CommandArgument[]} [data.args] - The command's arguments * @param {CommandArgument[]} [data.args] - The command's arguments (see [docs](https://github.com/75lb/command-line-args/blob/master/doc/option-definition.md) if using processed args)
*/ */
constructor(client, data) { constructor(client, data) {
@ -132,7 +132,7 @@ module.exports = class Command {
const addArgs = (embed, arg) => { const addArgs = (embed, arg) => {
let required = arg.required ? '`❗` ' : ''; let required = arg.required ? '`❗` ' : '';
embed.addField(required + arg.name, `» ${i18n('cmd_usage.args.description', arg.description)}}\n» ${i18n('cmd_usage.args.example', arg.example)}`); embed.addField(required + arg.name, `» ${i18n('cmd_usage.args.description', arg.description)}\n» ${i18n('cmd_usage.args.example', arg.example)}`);
}; };
let usage, let usage,
@ -140,8 +140,8 @@ module.exports = class Command {
embed; embed;
if (this.process_args) { if (this.process_args) {
usage = `${prefix + cmd_name} ${this.args.map(arg => arg.required ? `<${arg.name};>` : `[${arg.name};]`).join(' ')}`; usage = `${prefix + cmd_name} ${this.args.map(arg => arg.required ? `<${arg.name}>` : `[${arg.name}]`).join(' ')}`;
example = `${prefix + cmd_name} ${this.args.map(arg => `${arg.name}: ${arg.example};`).join(' ')}`; example = `${prefix + cmd_name} \n${this.args.map(arg => `--${arg.name} ${arg.example}`).join('\n')}`;
embed = new MessageEmbed() embed = new MessageEmbed()
.setColor(settings.error_colour) .setColor(settings.error_colour)
.setTitle(i18n('cmd_usage.title', cmd_name)) .setTitle(i18n('cmd_usage.title', cmd_name))

View File

@ -4,6 +4,9 @@ const { Collection, Client, Message, MessageEmbed } = require('discord.js');
const fs = require('fs'); const fs = require('fs');
const { path } = require('../../utils/fs'); const { path } = require('../../utils/fs');
const { parseArgsStringToArgv: argv } = require('string-argv');
const parseArgs = require('command-line-args');
/** /**
* Manages the loading and execution of commands * Manages the loading and execution of commands
*/ */
@ -153,11 +156,9 @@ module.exports = class CommandManager {
let args = raw_args; let args = raw_args;
if (cmd.process_args) { if (cmd.process_args) {
args = {}; args = parseArgs(cmd.args, { argv: argv(raw_args) });
let data = [...raw_args.matchAll(/(?<key>\w+)\??\s?:\s?(?<value>([^;]|;{2})*);/gmi)]; // an array of argument objects
data.forEach(arg => args[arg.groups.key] = arg.groups.value.replace(/;{2}/gm, ';')); // put the data into a useful format
for (let arg of cmd.args) { for (let arg of cmd.args) {
if (arg.required && !args[arg]) { if (arg.required && args[arg.name] === undefined) {
return await cmd.sendUsage(message.channel, cmd_name); // send usage if any required arg is missing return await cmd.sendUsage(message.channel, cmd_name); // send usage if any required arg is missing
} }
} }