CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-walk

A Node.js port of Python's os.walk for asynchronous and synchronous filesystem traversal with EventEmitter patterns

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

Walk

Walk is a Node.js port of Python's os.walk that provides both asynchronous and synchronous filesystem traversal capabilities. It uses EventEmitter patterns with built-in flow control to minimize file descriptor usage, making it well-suited for traditional hard disk operations.

Package Information

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

Core Imports

const walk = require('walk');

Basic Usage

const walk = require('walk');

// Create an asynchronous walker
const walker = walk.walk('/tmp');

walker.on('file', function (root, fileStats, next) {
  console.log(root + '/' + fileStats.name);
  next(); // Must call next() to continue walking
});

walker.on('end', function () {
  console.log('Walk completed');
});

Architecture

Walk is built around several key components:

  • Walker Class: Internal EventEmitter-based class that performs the actual filesystem traversal
  • Flow Control: All event handlers receive a next() callback that must be called to continue processing
  • Event System: Comprehensive event system supporting both individual node events and grouped events
  • Sync/Async Modes: Both asynchronous and synchronous walking with identical APIs
  • Built-in Filtering: Directory filtering and symbolic link following options

Capabilities

Asynchronous Walking

Creates an asynchronous directory walker that traverses the filesystem using EventEmitter patterns.

/**
 * Creates an asynchronous directory walker
 * @param {string} path - Starting directory path to walk
 * @param {WalkOptions} [options] - Configuration options
 * @returns {Walker} EventEmitter instance for handling walk events
 */
function walk(path, options);

Usage Example:

const walk = require('walk');

const walker = walk.walk('./my-directory', {
  followLinks: false,
  filters: ['node_modules', '.git']
});

walker.on('file', function (root, fileStats, next) {
  console.log('Found file:', root + '/' + fileStats.name);
  next();
});

walker.on('directory', function (root, dirStats, next) {
  console.log('Found directory:', root + '/' + dirStats.name);
  next();
});

walker.on('end', function () {
  console.log('Walk completed');
});

Synchronous Walking

Creates a synchronous directory walker with the same API as the asynchronous version.

/**
 * Creates a synchronous directory walker
 * @param {string} path - Starting directory path to walk
 * @param {WalkOptions} [options] - Configuration options
 * @returns {Walker} EventEmitter instance for handling walk events
 */
function walkSync(path, options);

Usage Example:

const walk = require('walk');

// For truly synchronous operation, use options.listeners
const walker = walk.walkSync('./my-directory', {
  listeners: {
    file: function (root, fileStats, next) {
      console.log('Found file:', root + '/' + fileStats.name);
      next();
    },
    directories: function (root, dirStatsArray, next) {
      console.log('Found directories:', dirStatsArray.map(s => s.name));
      next();
    },
    end: function () {
      console.log('Walk completed');
    }
  }
});

Walker Instance Control

Control methods available on walker instances for pausing and resuming operations.

/**
 * Pauses the walker, preventing further filesystem operations
 */
walker.pause();

/**
 * Resumes a paused walker, continuing filesystem operations
 */
walker.resume();

Events

Individual Node Events

All individual node event callbacks have the signature: function (root, stat, next) {}

/**
 * Emitted for any filesystem node
 * @param {string} root - Current directory path
 * @param {WalkStat} stat - File statistics with additional properties
 * @param {function} next - Callback to continue processing
 */
walker.on('node', function (root, stat, next) {});

/**
 * Emitted for each file (includes symbolic links when followLinks is true)
 * @param {string} root - Current directory path
 * @param {WalkStat} stat - File statistics with additional properties
 * @param {function} next - Callback to continue processing
 */
walker.on('file', function (root, stat, next) {});

/**
 * Emitted for each directory
 * @param {string} root - Current directory path
 * @param {WalkStat} stat - Directory statistics with additional properties
 * @param {function} next - Callback to continue processing
 */
walker.on('directory', function (root, stat, next) {});

/**
 * Emitted for symbolic links (empty when followLinks is true)
 * @param {string} root - Current directory path
 * @param {WalkStat} stat - Symbolic link statistics with additional properties
 * @param {function} next - Callback to continue processing
 */
walker.on('symbolicLink', function (root, stat, next) {});

/**
 * Emitted for block devices
 * @param {string} root - Current directory path
 * @param {WalkStat} stat - Block device statistics with additional properties
 * @param {function} next - Callback to continue processing
 */
walker.on('blockDevice', function (root, stat, next) {});

/**
 * Emitted for character devices
 * @param {string} root - Current directory path
 * @param {WalkStat} stat - Character device statistics with additional properties
 * @param {function} next - Callback to continue processing
 */
walker.on('characterDevice', function (root, stat, next) {});

/**
 * Emitted for FIFO files
 * @param {string} root - Current directory path
 * @param {WalkStat} stat - FIFO statistics with additional properties
 * @param {function} next - Callback to continue processing
 */
walker.on('FIFO', function (root, stat, next) {});

/**
 * Emitted for socket files
 * @param {string} root - Current directory path
 * @param {WalkStat} stat - Socket statistics with additional properties
 * @param {function} next - Callback to continue processing
 */
walker.on('socket', function (root, stat, next) {});

Grouped Events

All grouped event callbacks have the signature: function (root, statsArray, next) {}

/**
 * Emitted before stat operations, contains array of filenames
 * @param {string} root - Current directory path
 * @param {string[]} nodeNamesArray - Array of filenames in the directory
 * @param {function} next - Callback to continue processing (noop for names event)
 */
walker.on('names', function (root, nodeNamesArray, next) {});

/**
 * Emitted for each individual filename before stat operations
 * @param {string} root - Current directory path
 * @param {string} filename - Individual filename
 * @param {function} next - Callback to continue processing (noop for name event)
 */
walker.on('name', function (root, filename, next) {});

/**
 * Emitted for all nodes in a directory
 * @param {string} root - Current directory path
 * @param {WalkStat[]} statsArray - Array of all node statistics
 * @param {function} next - Callback to continue processing
 */
walker.on('nodes', function (root, statsArray, next) {});

/**
 * Emitted for all files in a directory
 * @param {string} root - Current directory path
 * @param {WalkStat[]} statsArray - Array of file statistics
 * @param {function} next - Callback to continue processing
 */
walker.on('files', function (root, statsArray, next) {});

/**
 * Emitted for all directories in a directory
 * @param {string} root - Current directory path
 * @param {WalkStat[]} statsArray - Array of directory statistics
 * @param {function} next - Callback to continue processing
 */
walker.on('directories', function (root, statsArray, next) {});

/**
 * Emitted for all symbolic links in a directory
 * @param {string} root - Current directory path
 * @param {WalkStat[]} statsArray - Array of symbolic link statistics
 * @param {function} next - Callback to continue processing
 */
walker.on('symbolicLinks', function (root, statsArray, next) {});

/**
 * Emitted for all block devices in a directory
 * @param {string} root - Current directory path
 * @param {WalkStat[]} statsArray - Array of block device statistics
 * @param {function} next - Callback to continue processing
 */
walker.on('blockDevices', function (root, statsArray, next) {});

/**
 * Emitted for all character devices in a directory
 * @param {string} root - Current directory path
 * @param {WalkStat[]} statsArray - Array of character device statistics
 * @param {function} next - Callback to continue processing
 */
walker.on('characterDevices', function (root, statsArray, next) {});

/**
 * Emitted for all FIFO files in a directory
 * @param {string} root - Current directory path
 * @param {WalkStat[]} statsArray - Array of FIFO statistics
 * @param {function} next - Callback to continue processing
 */
walker.on('FIFOs', function (root, statsArray, next) {});

/**
 * Emitted for all socket files in a directory
 * @param {string} root - Current directory path
 * @param {WalkStat[]} statsArray - Array of socket statistics
 * @param {function} next - Callback to continue processing
 */
walker.on('sockets', function (root, statsArray, next) {});

Error Events

/**
 * Collection of all errors encountered in a directory
 * @param {string} root - Current directory path
 * @param {WalkStat[]} errorStatsArray - Array of error statistics
 * @param {function} next - Callback to continue processing
 */
walker.on('errors', function (root, errorStatsArray, next) {});

/**
 * Error when fs.stat/lstat fails
 * @param {string} root - Current directory path
 * @param {WalkStat} stat - Statistics object with error property
 * @param {function} next - Callback to continue processing
 */
walker.on('nodeError', function (root, stat, next) {});

/**
 * Error when fs.readdir fails but stat succeeded
 * @param {string} root - Current directory path
 * @param {WalkStat} stat - Statistics object with error property
 * @param {function} next - Callback to continue processing
 */
walker.on('directoryError', function (root, stat, next) {});

Completion Event

/**
 * Emitted when walking is complete
 */
walker.on('end', function () {});

Types

/**
 * Configuration options for walk operations
 */
interface WalkOptions {
  /** Whether to follow symbolic links (default: false) */
  followLinks?: boolean;
  /** Array of directory names or regex patterns to filter out */
  filters?: (string | RegExp)[];
  /** Event listeners for synchronous walker operations */
  listeners?: WalkListeners;
}

/**
 * Event listeners for synchronous walker operations
 */
interface WalkListeners {
  names?: (root: string, nodeNamesArray: string[], next: () => void) => void;
  name?: (root: string, filename: string, next: () => void) => void;
  node?: (root: string, stat: WalkStat, next: () => void) => void;
  file?: (root: string, stat: WalkStat, next: () => void) => void;
  directory?: (root: string, stat: WalkStat, next: () => void) => void;
  symbolicLink?: (root: string, stat: WalkStat, next: () => void) => void;
  blockDevice?: (root: string, stat: WalkStat, next: () => void) => void;
  characterDevice?: (root: string, stat: WalkStat, next: () => void) => void;
  FIFO?: (root: string, stat: WalkStat, next: () => void) => void;
  socket?: (root: string, stat: WalkStat, next: () => void) => void;
  nodes?: (root: string, statsArray: WalkStat[], next: () => void) => void;
  files?: (root: string, statsArray: WalkStat[], next: () => void) => void;
  directories?: (root: string, statsArray: WalkStat[], next: () => void) => void;
  symbolicLinks?: (root: string, statsArray: WalkStat[], next: () => void) => void;
  blockDevices?: (root: string, statsArray: WalkStat[], next: () => void) => void;
  characterDevices?: (root: string, statsArray: WalkStat[], next: () => void) => void;
  FIFOs?: (root: string, statsArray: WalkStat[], next: () => void) => void;
  sockets?: (root: string, statsArray: WalkStat[], next: () => void) => void;
  errors?: (root: string, errorStatsArray: WalkStat[], next: () => void) => void;
  nodeError?: (root: string, stat: WalkStat, next: () => void) => void;
  directoryError?: (root: string, stat: WalkStat, next: () => void) => void;
  end?: () => void;
}

/**
 * Enhanced file statistics object extending Node.js fs.Stats
 */
interface WalkStat {
  /** The filename */
  name: string;
  /** File type ('file', 'directory', 'symbolicLink', etc.) */
  type: string;
  /** Error object if stat operation failed */
  error?: Error;
  
  // Standard fs.Stats properties
  /** Device ID */
  dev: number;
  /** File mode (permissions and file type) */
  mode: number;
  /** Number of hard links */
  nlink: number;
  /** User ID */
  uid: number;
  /** Group ID */
  gid: number;
  /** Device ID (if special file) */
  rdev: number;
  /** Block size for filesystem I/O */
  blksize: number;
  /** Inode number */
  ino: number;
  /** Total size in bytes */
  size: number;
  /** Number of 512-byte blocks allocated */
  blocks: number;
  /** Access time */
  atime: Date;
  /** Modification time */
  mtime: Date;
  /** Change time */
  ctime: Date;
  /** Birth time (creation time) */
  birthtime: Date;
}

/**
 * Walker instance extending EventEmitter
 */
interface Walker extends EventEmitter {
  /** Pauses the walker */
  pause(): void;
  /** Resumes a paused walker */
  resume(): void;
}
Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/walk@2.3.x
Publish Source
CLI
Badge
tessl/npm-walk badge