0
# Command Execution
1
2
Programmatic command execution with both synchronous and asynchronous support, plus argument parsing from process.argv.
3
4
## Capabilities
5
6
### Asynchronous Execution
7
8
Executes a Vorpal API command and returns response through callback or Promise.
9
10
```javascript { .api }
11
/**
12
* Executes a vorpal API command and returns response through callback or Promise
13
* @param cmd - Command string to execute
14
* @param args - Optional arguments object to pass to command
15
* @param cb - Optional callback function (if omitted, returns Promise)
16
* @returns Promise when no callback provided, or Vorpal instance for chaining
17
*/
18
function exec(cmd: string, args?: object, cb?: (err?: any, data?: any) => void): Promise<any> | Vorpal;
19
```
20
21
**Usage Examples:**
22
23
```javascript
24
const vorpal = require('vorpal')();
25
26
// Register a command
27
vorpal
28
.command('add <a> <b>', 'Adds two numbers')
29
.action(function(args, callback) {
30
const result = parseInt(args.a) + parseInt(args.b);
31
callback(null, result);
32
});
33
34
// Execute with callback
35
vorpal.exec('add 5 3', function(err, result) {
36
if (err) {
37
console.error('Error:', err);
38
} else {
39
console.log('Result:', result); // Result: 8
40
}
41
});
42
43
// Execute with Promise
44
vorpal.exec('add 10 20')
45
.then(result => {
46
console.log('Result:', result); // Result: 30
47
})
48
.catch(err => {
49
console.error('Error:', err);
50
});
51
52
// Execute with async/await
53
async function runCommand() {
54
try {
55
const result = await vorpal.exec('add 7 8');
56
console.log('Result:', result); // Result: 15
57
} catch (err) {
58
console.error('Error:', err);
59
}
60
}
61
```
62
63
### Synchronous Execution
64
65
Executes a Vorpal command synchronously and returns the result immediately.
66
67
```javascript { .api }
68
/**
69
* Executes a Vorpal command synchronously
70
* @param cmd - Command string to execute
71
* @param options - Optional execution options
72
* @returns Command execution result
73
*/
74
function execSync(cmd: string, options?: ExecSyncOptions): any;
75
76
interface ExecSyncOptions {
77
fatal?: boolean; // Whether to throw on errors
78
[key: string]: any; // Additional options
79
}
80
```
81
82
**Usage Example:**
83
84
```javascript
85
const vorpal = require('vorpal')();
86
87
// Register a synchronous command
88
vorpal
89
.command('multiply <a> <b>', 'Multiplies two numbers')
90
.action(function(args, callback) {
91
const result = parseInt(args.a) * parseInt(args.b);
92
callback(null, result);
93
});
94
95
// Execute synchronously
96
try {
97
const result = vorpal.execSync('multiply 4 5');
98
console.log('Result:', result); // Result: 20
99
} catch (err) {
100
console.error('Sync execution error:', err);
101
}
102
```
103
104
### Process Arguments Parsing
105
106
Parses `process.argv` and executes a Vorpal command based on it.
107
108
```javascript { .api }
109
/**
110
* Parses process.argv and executes a Vorpal command based on it
111
* @param argv - Array of command line arguments (typically process.argv)
112
* @param options - Optional parsing options
113
* @returns Parsed result or Vorpal instance
114
*/
115
function parse(argv: string[], options?: ParseOptions): any;
116
117
interface ParseOptions {
118
use?: 'minimist'; // Use minimist for parsing instead of default
119
[key: string]: any; // Additional parsing options
120
}
121
```
122
123
**Usage Examples:**
124
125
```javascript
126
const vorpal = require('vorpal')();
127
128
// Register commands
129
vorpal
130
.command('start [port]', 'Starts the server')
131
.option('-d, --daemon', 'Run as daemon')
132
.action(function(args, callback) {
133
const port = args.port || 3000;
134
const daemon = args.options.daemon;
135
136
this.log(`Starting server on port ${port}`);
137
if (daemon) {
138
this.log('Running in daemon mode');
139
}
140
callback();
141
});
142
143
// Parse command line arguments
144
// If called with: node app.js start 8080 --daemon
145
vorpal.parse(process.argv);
146
147
// Parse with minimist
148
vorpal.parse(process.argv, { use: 'minimist' });
149
150
// Parse custom arguments
151
const customArgs = ['node', 'app.js', 'start', '9000', '--daemon'];
152
vorpal.parse(customArgs);
153
```
154
155
## Execution Context
156
157
### Command Instance Context
158
159
When commands are executed, the action function receives a `this` context that provides access to various utilities and methods.
160
161
```javascript { .api }
162
interface CommandInstance {
163
// Logging within command context
164
log(...args: any[]): void;
165
166
// Cancel the running command
167
cancel(): void;
168
169
// Prompt user from within command
170
prompt(options?: object, callback?: function): any;
171
172
// Set delimiter from within command
173
delimiter(delimiter?: string): any;
174
175
// Show help from within command
176
help(): any;
177
178
// Match autocomplete from within command
179
match(str: string, arr: string[]): string;
180
181
// Properties
182
command: string; // Command name
183
commandObject: Command; // Command instance reference
184
args: CommandArgs; // Parsed command arguments
185
session: Session; // Session instance
186
parent: Vorpal; // Parent Vorpal instance
187
}
188
```
189
190
**Usage Example:**
191
192
```javascript
193
vorpal
194
.command('interactive', 'Interactive command demo')
195
.action(function(args, callback) {
196
// Access command context
197
this.log('Command:', this.command);
198
this.log('Parent Vorpal:', this.parent.constructor.name);
199
200
// Prompt user
201
this.prompt({
202
type: 'input',
203
name: 'name',
204
message: 'What is your name?'
205
}, (result) => {
206
this.log(`Hello, ${result.name}!`);
207
callback();
208
});
209
});
210
```
211
212
## Error Handling
213
214
### Execution Errors
215
216
Commands can handle and propagate errors through callbacks or Promise rejections.
217
218
```javascript
219
vorpal
220
.command('risky', 'A command that might fail')
221
.action(function(args, callback) {
222
// Simulate an error condition
223
if (Math.random() < 0.5) {
224
callback(new Error('Random failure occurred'));
225
} else {
226
callback(null, 'Success!');
227
}
228
});
229
230
// Handle with callback
231
vorpal.exec('risky', function(err, result) {
232
if (err) {
233
console.error('Command failed:', err.message);
234
} else {
235
console.log('Command succeeded:', result);
236
}
237
});
238
239
// Handle with Promise
240
vorpal.exec('risky')
241
.then(result => console.log('Success:', result))
242
.catch(err => console.error('Failed:', err.message));
243
```
244
245
### Validation Errors
246
247
Commands with validation can prevent execution and provide error messages.
248
249
```javascript
250
vorpal
251
.command('validate-demo <number>', 'Validates input')
252
.validate(function(args) {
253
const num = parseInt(args.number);
254
if (isNaN(num)) {
255
return 'Argument must be a valid number';
256
}
257
if (num < 0) {
258
return 'Number must be positive';
259
}
260
return true;
261
})
262
.action(function(args, callback) {
263
this.log(`Valid number: ${args.number}`);
264
callback();
265
});
266
267
// This will fail validation
268
vorpal.exec('validate-demo abc')
269
.catch(err => console.log('Validation error:', err.message));
270
```
271
272
## Batch Execution
273
274
Execute multiple commands in sequence:
275
276
```javascript
277
async function batchExecute() {
278
const commands = [
279
'command1 arg1',
280
'command2 arg2 --option',
281
'command3'
282
];
283
284
for (const cmd of commands) {
285
try {
286
const result = await vorpal.exec(cmd);
287
console.log(`${cmd} completed:`, result);
288
} catch (err) {
289
console.error(`${cmd} failed:`, err.message);
290
break; // Stop on first error
291
}
292
}
293
}
294
```
295
296
## Complete Execution Example
297
298
```javascript
299
const vorpal = require('vorpal')();
300
301
// Setup commands
302
vorpal
303
.command('calculate <operation> <a> <b>', 'Perform calculations')
304
.validate(function(args) {
305
const ops = ['add', 'subtract', 'multiply', 'divide'];
306
if (!ops.includes(args.operation)) {
307
return `Operation must be one of: ${ops.join(', ')}`;
308
}
309
310
const a = parseFloat(args.a);
311
const b = parseFloat(args.b);
312
313
if (isNaN(a) || isNaN(b)) {
314
return 'Both operands must be valid numbers';
315
}
316
317
if (args.operation === 'divide' && b === 0) {
318
return 'Cannot divide by zero';
319
}
320
321
return true;
322
})
323
.action(function(args, callback) {
324
const a = parseFloat(args.a);
325
const b = parseFloat(args.b);
326
let result;
327
328
switch (args.operation) {
329
case 'add':
330
result = a + b;
331
break;
332
case 'subtract':
333
result = a - b;
334
break;
335
case 'multiply':
336
result = a * b;
337
break;
338
case 'divide':
339
result = a / b;
340
break;
341
}
342
343
this.log(`${a} ${args.operation} ${b} = ${result}`);
344
callback(null, result);
345
});
346
347
// Different execution methods
348
async function demonstrateExecution() {
349
// Callback style
350
vorpal.exec('calculate add 10 5', (err, result) => {
351
console.log('Callback result:', result);
352
});
353
354
// Promise style
355
vorpal.exec('calculate multiply 7 8')
356
.then(result => console.log('Promise result:', result));
357
358
// Async/await style
359
try {
360
const result = await vorpal.exec('calculate divide 20 4');
361
console.log('Async/await result:', result);
362
} catch (err) {
363
console.error('Execution error:', err.message);
364
}
365
366
// Synchronous style
367
const syncResult = vorpal.execSync('calculate subtract 15 3');
368
console.log('Sync result:', syncResult);
369
}
370
371
// Parse command line arguments if running as CLI
372
if (require.main === module) {
373
vorpal.parse(process.argv);
374
} else {
375
// Export for programmatic use
376
module.exports = vorpal;
377
}
378
```