-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Closed
Labels
Description
I would like to parse an argument that is expected to equal an index to an array that can only be read asynchronously. Currently, I see no better way than to use an async argument parser and handle the promise it returns in the action handler. Here is a simple example with lowdb:
import { Command, InvalidArgumentError } from 'commander';
import { Low } from 'lowdb';
import { JSONFile } from 'lowdb/node';
const adapter = new JSONFile('test.json');
const db = new Low(adapter, ['foo', 'bar']);
await db.read();
await db.write();
const indexParser = async (val) => {
if (val) {
val = Number(val);
if (Number.isInteger(val) && val >= 0) {
await db.read();
if (val < db.data.length) return val;
}
}
throw new InvalidArgumentError('Index out of bounds');
};
const program = new Command()
.argument('index', 'Array element to access', indexParser)
.action(function(indexPromise) {
indexPromise.then(async function(index) {
await db.read();
console.log(db.data[index]);
});
});
// go modify test.json manually or whatever...
setTimeout(() => program.parse(), 10000);Obviously, it would be better and more intuitive if the action handler execution were deferred until after the promise is resolved.
Possible implementations:
-
explicit, something along these lines:
program.addArgument(new Argument('index').argParser(indexParser).async())
-
defer action handler execution whenever parser returns a thenable object
- if a certain new method was called on the command, e.g.
program.respectAsyncArgParsers(true) - or if the
parseAsync()method was called (breaking)
- if a certain new method was called on the command, e.g.
Reactions are currently unavailable