or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-prompt

A beautiful command-line prompt for node.js with validation, defaults, and password hiding capabilities

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/prompt@1.3.x

To install, run

npx @tessl/cli install tessl/npm-prompt@1.3.0

index.mddocs/

Prompt

Prompt is a comprehensive command-line prompting library for Node.js applications that enables developers to interactively collect user input with built-in validation, default values, and password hiding capabilities. It offers a simple yet powerful API with methods like prompt.get() and prompt.addProperties() for gathering user input, supports complex property validation through revalidator integration, provides extensive customization options including colors and formatting, and includes robust error handling and async/await support for modern JavaScript development patterns.

Package Information

  • Package Name: prompt
  • Package Type: npm
  • Language: JavaScript
  • Installation: npm install prompt

Core Imports

const prompt = require('prompt');

ESM import:

import prompt from 'prompt';

Basic Usage

const prompt = require('prompt');

// Start the prompt system
prompt.start();

// Get simple input
prompt.get(['username', 'email'], function (err, result) {
  if (err) return console.error(err);
  console.log('Username:', result.username);
  console.log('Email:', result.email);
});

// Using Promises (modern approach)
async function getUserInfo() {
  prompt.start();
  try {
    const result = await prompt.get(['username', 'email']);
    console.log('Username:', result.username);
    console.log('Email:', result.email);
  } catch (err) {
    console.error('Error:', err);
  }
}

Callback vs Promise Usage

Prompt supports both callback-based and Promise-based APIs for modern JavaScript development:

Callback Style (Traditional):

prompt.get(['username', 'email'], function(err, result) {
  if (err) return console.error(err);
  console.log('Result:', result);
});

Promise Style (Modern/Async-Await):

// Using Promises
prompt.get(['username', 'email'])
  .then(result => console.log('Result:', result))
  .catch(err => console.error(err));

// Using async/await
async function getUserInfo() {
  try {
    const result = await prompt.get(['username', 'email']);
    console.log('Result:', result);
  } catch (err) {
    console.error(err);
  }
}

Important Notes:

  • When no callback is provided, methods return a Promise
  • When a callback is provided, methods return the prompt object for chaining
  • All main methods (get, addProperties) support both patterns
  • confirm always requires a callback and does not return a Promise

Architecture

Prompt is built around several key components:

  • Core Prompt System: Main prompt object providing all user interaction methods
  • Schema Validation: Integration with revalidator for complex input validation
  • Event System: EventEmitter-based architecture for handling prompt lifecycle events
  • Stream Management: Flexible input/output stream handling with default process.stdin/stdout
  • History System: Built-in memory of previous prompt/answer pairs for reference
  • Cross-Platform Support: Handles platform-specific differences (Windows vs Unix)

Capabilities

Prompt Initialization

Initialize the prompt system with configuration options.

/**
 * Starts the prompt by listening to the appropriate events on stdin/stdout
 * @param {Object} options - Optional configuration options
 * @param {ReadableStream} options.stdin - Input stream (default: process.stdin)
 * @param {WritableStream} options.stdout - Output stream (default: process.stdout)
 * @param {number} options.memory - Number of previous prompts to remember (default: 10)
 * @param {boolean} options.allowEmpty - Allow empty responses globally (default: false)
 * @param {string} options.message - Default message prefix (default: 'prompt')
 * @param {string} options.delimiter - Default delimiter (default: ': ')
 * @param {boolean} options.colors - Enable colors (default: true)
 * @param {boolean} options.noHandleSIGINT - Disable SIGINT handling (default: false)
 * @returns {Object} prompt object for chaining
 */
function start(options);

Usage Example:

const prompt = require('prompt');

// Basic initialization
prompt.start();

// Custom configuration
prompt.start({
  message: 'myapp',
  delimiter: ' > ',
  colors: false,
  allowEmpty: true
});

Input Collection

Get user input using simple property names or complex validation schemas.

/**
 * Gets input from the user via stdin for specified message(s)
 * @param {string|string[]|PropertySchema|FullSchema} schema - Set of variables to get input for
 * @param {(err: Error|null, result?: Object) => void} callback - Optional callback function
 * @returns {Promise<Object>|typeof prompt} Promise when no callback provided, otherwise prompt object
 */
function get(schema, callback);

/** Complete schema object with properties */
interface FullSchema {
  properties: {
    [propertyName: string]: PropertySchema;
  };
}

Schema Types:

  • String: Simple property name
  • Array: List of property names
  • Object: Complex validation schema with properties

Usage Examples:

// Simple property names
const result = await prompt.get(['name', 'age']);

// Array of properties
const result = await prompt.get(['username', 'password', 'email']);

// Complex validation schema
const schema = {
  properties: {
    name: {
      pattern: /^[a-zA-Z\s\-]+$/,
      message: 'Name must be only letters, spaces, or dashes',
      required: true
    },
    password: {
      hidden: true,
      replace: '*'
    },
    age: {
      type: 'integer',
      minimum: 0,
      maximum: 120,
      message: 'Age must be between 0 and 120'
    }
  }
};

const result = await prompt.get(schema);

Property Addition

Add missing properties to existing objects by prompting the user.

/**
 * Prompts user for values of properties if obj doesn't already have them
 * @param {Object} obj - Object to add properties to
 * @param {Array} properties - List of properties to get values for
 * @param {Function} callback - Callback function (err, updatedObj)
 * @returns {Object} prompt object for chaining
 */
function addProperties(obj, properties, callback);

Usage Example:

const config = {
  host: 'localhost',
  port: 3000
};

// Only prompt for missing properties
prompt.addProperties(config, ['host', 'port', 'username', 'password'], function(err, result) {
  // Only prompts for 'username' and 'password' since host/port already exist
  console.log('Complete config:', result);
});

Confirmation Prompts

Prompt for yes/no confirmation with customizable validation.

/**
 * Confirms a single or series of messages by prompting for Y/N response
 * @param {string|ConfirmSchema|Array<string|ConfirmSchema>} msg - Set of messages to confirm
 * @param {Object} options - Optional additional options to merge with each confirm schema
 * @param {(err: Error|null, isConfirmed: boolean) => void} callback - Callback function
 * @returns {void} Calls callback with true if ALL messages confirmed, otherwise false
 */
function confirm(msg, options, callback);

/** Confirmation schema with customizable validation */
interface ConfirmSchema {
  /** Message to display for confirmation */
  description: string;
  /** Pattern for valid responses (default: /^[yntf]{1}/i) */
  pattern?: RegExp;
  /** Pattern for "yes" responses (default: /^[yt]{1}/i) */
  yes?: RegExp;
  /** Error message for invalid responses */
  message?: string;
}

Usage Examples:

// Simple confirmation
prompt.confirm('Are you sure?', function(err, result) {
  console.log('User confirmed:', result);
});

// Custom validation
const confirmOptions = {
  description: 'Delete all files?',
  pattern: /^[yntf]{1}/i,
  yes: /^[yt]{1}/i,
  message: 'Please enter yes, y, no, n, true, t, false, or f'
};

prompt.confirm(confirmOptions, function(err, result) {
  if (result) {
    console.log('Proceeding with deletion...');
  }
});

Low-Level Input

Get single input with validation (used internally by get()).

/**
 * Gets input from user via stdin for specified message with validation
 * @param {Object|string} prop - Property schema or name
 * @param {Function} callback - Callback function (err, input)
 */
function getInput(prop, callback);

State Management

Control the prompt system lifecycle and state.

/**
 * Pauses input coming in from stdin
 * @returns {Object} prompt object for chaining
 */
function pause();

/**
 * Resumes input coming in from stdin
 * @returns {Object} prompt object for chaining
 */
function resume();

/**
 * Stops input coming in from stdin and destroys it
 * @returns {Object} prompt object for chaining
 */
function stop();

Usage Example:

prompt.start();

// Pause during async operation
prompt.pause();
await someAsyncOperation();
prompt.resume();

// Later, stop completely
prompt.stop();

History Access

Access previous prompt/answer pairs from memory.

/**
 * Returns property:value pair from within the prompts history array
 * @param {number|string} search - Index or property name to find
 * @returns {Object|null} History entry object or null if not found
 */
function history(search);

Usage Example:

// Get by index
const lastPrompt = prompt.history(0);

// Get by property name
const usernameEntry = prompt.history('username');
console.log('Previous username:', usernameEntry?.value);

Configuration Properties

State Properties

/** Indicates if prompt has been started */
boolean started;

/** Indicates if prompt is currently paused */
boolean paused;

/** Indicates if prompt has been stopped */
boolean stopped;

Behavior Properties

/** Global setting to allow empty responses */
boolean allowEmpty;

/** Default message prefix for prompts */
string message;

/** Default delimiter between message and input */
string delimiter;

/** Enable/disable colored output */
boolean colors;

/** Number of previous prompt/answer pairs to remember */
number memory;

Storage Properties

/** Stored property schemas for reuse */
Object properties;

/** Property values to override during prompting */
Object override;

Utility Properties

/** Package version from package.json */
string version;

/** Winston logger instance for prompt output */
Object logger;

Schema Validation

Prompt uses JSON Schema-compatible validation with additional properties:

interface PropertySchema {
  // Display Properties
  /** Prompt text displayed to user */
  description?: string;
  /** Error message displayed on validation failure */
  message?: string;
  
  // Data Type Properties
  /** Data type: 'string', 'boolean', 'number', 'integer', 'array' */
  type?: 'string' | 'boolean' | 'number' | 'integer' | 'array';
  /** Default value if no input provided */
  default?: any;
  /** Whether input is required (non-empty) */
  required?: boolean;
  
  // Validation Properties
  /** Regular expression for validation */
  pattern?: RegExp;
  /** Custom validation function */
  conform?: (value: any) => boolean;
  /** Format validation (from revalidator) - 'email', 'url', 'date-time', etc. */
  format?: string;
  
  // Input Control Properties
  /** Hide input characters (for passwords) */
  hidden?: boolean;
  /** Replacement character for hidden input (default: '*') */
  replace?: string;
  /** Transform input before validation */
  before?: (value: any) => any;
  /** Dynamic condition to show/skip prompt */
  ask?: () => boolean;
  
  // Array Type Properties
  /** For array type - maximum number of items */
  maxItems?: number;
  /** For array type - minimum number of items */
  minItems?: number;
  
  // Numeric Type Properties (inherited from revalidator)
  /** For number/integer types - minimum value */
  minimum?: number;
  /** For number/integer types - maximum value */
  maximum?: number;
  
  // String Type Properties (inherited from revalidator)
  /** For string type - minimum length */
  minLength?: number;
  /** For string type - maximum length */
  maxLength?: number;
}

Type-Specific Behavior:

  • boolean: Accepts case-insensitive 'true', 't', 'false', 'f'
  • number/integer: Automatically converts string input to Number
  • array: Requires users to press Ctrl+C to end input, supports maxItems/minItems
  • string: Default type, no automatic conversion

Event System

Prompt inherits from EventEmitter and emits the following events:

/** 
 * Emitted when prompt.start() is called successfully
 * Fired after streams are configured and SIGINT handlers are set up
 */
event 'start'

/** 
 * Emitted when prompt.pause() is called
 * Fired after stdin.pause() is executed and prompt is in paused state
 */
event 'pause'

/** 
 * Emitted when prompt.resume() is called
 * Fired after stdin.resume() is executed and prompt is active again
 */
event 'resume'

/** 
 * Emitted when prompt.stop() is called
 * Fired after stdin is destroyed and prompt is fully stopped
 */
event 'stop'

/** 
 * Emitted when getInput begins prompting for a specific property
 * Fired before the actual input prompt is displayed to the user
 * @param {Object} prop - Property object being prompted for
 * @param {Array} prop.path - Property path array (e.g., ['username'])
 * @param {Object} prop.schema - Validation schema for this property
 */
event 'prompt'

/** 
 * Emitted when user input fails validation
 * Fired after validation fails but before re-prompting the user
 * @param {Object} prop - Property object that failed validation
 * @param {Array} prop.path - Property path array
 * @param {Object} prop.schema - Validation schema that failed
 * @param {any} input - The input value that failed validation
 */
event 'invalid'

Usage Example:

prompt.on('prompt', function(prop) {
  console.log('Prompting for:', prop.path);
});

prompt.on('invalid', function(prop, input) {
  console.log('Invalid input:', input, 'for property:', prop.path);
});

Error Handling

Validation Errors

Validation is handled through the revalidator package:

// Validation errors cause re-prompting
const schema = {
  properties: {
    email: {
      format: 'email',
      message: 'Please enter a valid email address'
    }
  }
};

try {
  const result = await prompt.get(schema);
} catch (err) {
  // Handle system errors (not validation errors)
  console.error('System error:', err);
}

Exception Handling

// Handle SIGINT (Ctrl+C)
process.on('SIGINT', function() {
  console.log('Received SIGINT, exiting...');
  process.exit(1);
});

// Handle stream errors
prompt.start({
  stdin: customInputStream,
  stdout: customOutputStream
});

Advanced Usage

Custom Validation

const schema = {
  properties: {
    username: {
      conform: function(value) {
        return value.length >= 3 && /^[a-zA-Z0-9_]+$/.test(value);
      },
      message: 'Username must be at least 3 characters and contain only letters, numbers, and underscores'
    }
  }
};

Dynamic Prompts

const schema = {
  properties: {
    hasEmail: {
      type: 'boolean',
      description: 'Do you have an email?'
    },
    email: {
      ask: function() {
        return prompt.history('hasEmail')?.value === true;
      },
      format: 'email',
      description: 'Enter your email'
    }
  }
};

Password Input

const schema = {
  properties: {
    password: {
      hidden: true,
      replace: '*',
      description: 'Enter password'
    },
    confirmPassword: {
      hidden: true,
      replace: '*',
      description: 'Confirm password',
      conform: function(value) {
        return value === prompt.history('password')?.value;
      },
      message: 'Passwords do not match'
    }
  }
};