CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-vorpal

Node's first framework for building immersive CLI apps.

Pending
Overview
Eval results
Files

execution.mddocs/

Command Execution

Programmatic command execution with both synchronous and asynchronous support, plus argument parsing from process.argv.

Capabilities

Asynchronous Execution

Executes a Vorpal API command and returns response through callback or Promise.

/**
 * Executes a vorpal API command and returns response through callback or Promise
 * @param cmd - Command string to execute
 * @param args - Optional arguments object to pass to command
 * @param cb - Optional callback function (if omitted, returns Promise)
 * @returns Promise when no callback provided, or Vorpal instance for chaining
 */
function exec(cmd: string, args?: object, cb?: (err?: any, data?: any) => void): Promise<any> | Vorpal;

Usage Examples:

const vorpal = require('vorpal')();

// Register a command
vorpal
  .command('add <a> <b>', 'Adds two numbers')
  .action(function(args, callback) {
    const result = parseInt(args.a) + parseInt(args.b);
    callback(null, result);
  });

// Execute with callback
vorpal.exec('add 5 3', function(err, result) {
  if (err) {
    console.error('Error:', err);
  } else {
    console.log('Result:', result); // Result: 8
  }
});

// Execute with Promise
vorpal.exec('add 10 20')
  .then(result => {
    console.log('Result:', result); // Result: 30
  })
  .catch(err => {
    console.error('Error:', err);
  });

// Execute with async/await
async function runCommand() {
  try {
    const result = await vorpal.exec('add 7 8');
    console.log('Result:', result); // Result: 15
  } catch (err) {
    console.error('Error:', err);
  }
}

Synchronous Execution

Executes a Vorpal command synchronously and returns the result immediately.

/**
 * Executes a Vorpal command synchronously
 * @param cmd - Command string to execute
 * @param options - Optional execution options
 * @returns Command execution result
 */
function execSync(cmd: string, options?: ExecSyncOptions): any;

interface ExecSyncOptions {
  fatal?: boolean;    // Whether to throw on errors
  [key: string]: any; // Additional options
}

Usage Example:

const vorpal = require('vorpal')();

// Register a synchronous command
vorpal
  .command('multiply <a> <b>', 'Multiplies two numbers')
  .action(function(args, callback) {
    const result = parseInt(args.a) * parseInt(args.b);
    callback(null, result);
  });

// Execute synchronously
try {
  const result = vorpal.execSync('multiply 4 5');
  console.log('Result:', result); // Result: 20
} catch (err) {
  console.error('Sync execution error:', err);
}

Process Arguments Parsing

Parses process.argv and executes a Vorpal command based on it.

/**
 * Parses process.argv and executes a Vorpal command based on it
 * @param argv - Array of command line arguments (typically process.argv)
 * @param options - Optional parsing options
 * @returns Parsed result or Vorpal instance
 */
function parse(argv: string[], options?: ParseOptions): any;

interface ParseOptions {
  use?: 'minimist';  // Use minimist for parsing instead of default
  [key: string]: any; // Additional parsing options
}

Usage Examples:

const vorpal = require('vorpal')();

// Register commands
vorpal
  .command('start [port]', 'Starts the server')
  .option('-d, --daemon', 'Run as daemon')
  .action(function(args, callback) {
    const port = args.port || 3000;
    const daemon = args.options.daemon;
    
    this.log(`Starting server on port ${port}`);
    if (daemon) {
      this.log('Running in daemon mode');
    }
    callback();
  });

// Parse command line arguments
// If called with: node app.js start 8080 --daemon
vorpal.parse(process.argv);

// Parse with minimist
vorpal.parse(process.argv, { use: 'minimist' });

// Parse custom arguments
const customArgs = ['node', 'app.js', 'start', '9000', '--daemon'];
vorpal.parse(customArgs);

Execution Context

Command Instance Context

When commands are executed, the action function receives a this context that provides access to various utilities and methods.

interface CommandInstance {
  // Logging within command context
  log(...args: any[]): void;
  
  // Cancel the running command
  cancel(): void;
  
  // Prompt user from within command
  prompt(options?: object, callback?: function): any;
  
  // Set delimiter from within command
  delimiter(delimiter?: string): any;
  
  // Show help from within command
  help(): any;
  
  // Match autocomplete from within command
  match(str: string, arr: string[]): string;
  
  // Properties
  command: string;           // Command name
  commandObject: Command;    // Command instance reference
  args: CommandArgs;         // Parsed command arguments
  session: Session;          // Session instance
  parent: Vorpal;           // Parent Vorpal instance
}

Usage Example:

vorpal
  .command('interactive', 'Interactive command demo')
  .action(function(args, callback) {
    // Access command context
    this.log('Command:', this.command);
    this.log('Parent Vorpal:', this.parent.constructor.name);
    
    // Prompt user
    this.prompt({
      type: 'input',
      name: 'name',
      message: 'What is your name?'
    }, (result) => {
      this.log(`Hello, ${result.name}!`);
      callback();
    });
  });

Error Handling

Execution Errors

Commands can handle and propagate errors through callbacks or Promise rejections.

vorpal
  .command('risky', 'A command that might fail')
  .action(function(args, callback) {
    // Simulate an error condition
    if (Math.random() < 0.5) {
      callback(new Error('Random failure occurred'));
    } else {
      callback(null, 'Success!');
    }
  });

// Handle with callback
vorpal.exec('risky', function(err, result) {
  if (err) {
    console.error('Command failed:', err.message);
  } else {
    console.log('Command succeeded:', result);
  }
});

// Handle with Promise
vorpal.exec('risky')
  .then(result => console.log('Success:', result))
  .catch(err => console.error('Failed:', err.message));

Validation Errors

Commands with validation can prevent execution and provide error messages.

vorpal
  .command('validate-demo <number>', 'Validates input')
  .validate(function(args) {
    const num = parseInt(args.number);
    if (isNaN(num)) {
      return 'Argument must be a valid number';
    }
    if (num < 0) {
      return 'Number must be positive';
    }
    return true;
  })
  .action(function(args, callback) {
    this.log(`Valid number: ${args.number}`);
    callback();
  });

// This will fail validation
vorpal.exec('validate-demo abc')
  .catch(err => console.log('Validation error:', err.message));

Batch Execution

Execute multiple commands in sequence:

async function batchExecute() {
  const commands = [
    'command1 arg1',
    'command2 arg2 --option',
    'command3'
  ];
  
  for (const cmd of commands) {
    try {
      const result = await vorpal.exec(cmd);
      console.log(`${cmd} completed:`, result);
    } catch (err) {
      console.error(`${cmd} failed:`, err.message);
      break; // Stop on first error
    }
  }
}

Complete Execution Example

const vorpal = require('vorpal')();

// Setup commands
vorpal
  .command('calculate <operation> <a> <b>', 'Perform calculations')
  .validate(function(args) {
    const ops = ['add', 'subtract', 'multiply', 'divide'];
    if (!ops.includes(args.operation)) {
      return `Operation must be one of: ${ops.join(', ')}`;
    }
    
    const a = parseFloat(args.a);
    const b = parseFloat(args.b);
    
    if (isNaN(a) || isNaN(b)) {
      return 'Both operands must be valid numbers';
    }
    
    if (args.operation === 'divide' && b === 0) {
      return 'Cannot divide by zero';
    }
    
    return true;
  })
  .action(function(args, callback) {
    const a = parseFloat(args.a);
    const b = parseFloat(args.b);
    let result;
    
    switch (args.operation) {
      case 'add':
        result = a + b;
        break;
      case 'subtract':
        result = a - b;
        break;
      case 'multiply':
        result = a * b;
        break;
      case 'divide':
        result = a / b;
        break;
    }
    
    this.log(`${a} ${args.operation} ${b} = ${result}`);
    callback(null, result);
  });

// Different execution methods
async function demonstrateExecution() {
  // Callback style
  vorpal.exec('calculate add 10 5', (err, result) => {
    console.log('Callback result:', result);
  });
  
  // Promise style
  vorpal.exec('calculate multiply 7 8')
    .then(result => console.log('Promise result:', result));
  
  // Async/await style
  try {
    const result = await vorpal.exec('calculate divide 20 4');
    console.log('Async/await result:', result);
  } catch (err) {
    console.error('Execution error:', err.message);
  }
  
  // Synchronous style
  const syncResult = vorpal.execSync('calculate subtract 15 3');
  console.log('Sync result:', syncResult);
}

// Parse command line arguments if running as CLI
if (require.main === module) {
  vorpal.parse(process.argv);
} else {
  // Export for programmatic use
  module.exports = vorpal;
}

Install with Tessl CLI

npx tessl i tessl/npm-vorpal

docs

commands.md

configuration.md

events.md

execution.md

extensions.md

index.md

storage.md

ui.md

tile.json