fexplr-js
v1.0.0
Published
fileexplorer is a web-based file explorer built using TypeScript. It provides a user-friendly interface for navigating and managing files and directories in a web environment.
Downloads
95
Readme
FileExplorer
A fast, efficient command-line file and folder explorer with advanced filtering capabilities, built as a monorepo with both a core library and CLI interface.
Overview
FileExplorer provides a powerful way to navigate and list files and directories from the command line. It features:
- 🚀 High-performance file system traversal
- 🎯 Advanced filtering with regex and glob patterns
- 📊 Multiple output formats (list, tree, JSON)
- ⚙️ Configuration file support
- 🔄 Parallel scanning for large directories
- 📈 Progress tracking and reporting
- 🛡️ Robust error handling
The project is structured as a monorepo with two main packages:
@fileexplorer/core: Core library for file system traversal and filtering@fileexplorer/cli: Command-line interface built on top of the core library
Prerequisites
- Node.js: >= 20.0.0
- pnpm: >= 8.0.0
Installation
Development Setup
- Clone the repository and navigate to the project directory:
cd filebrowser- Install dependencies using pnpm:
pnpm installUsage in Projects
To use the CLI as a global command:
pnpm -r build
pnpm -r add -g @fileexplorer/cliTo use the core library in your project:
pnpm add @fileexplorer/coreBuild Process
The project uses Vite for bundling and TypeScript for type checking. Build both packages:
# Build all packages
pnpm build
# Build specific package
pnpm -C packages/core build
pnpm -C packages/cli build
# Watch mode (for development)
pnpm -C packages/core dev
pnpm -C packages/cli dev
# Clean build artifacts
pnpm cleanRunning the Project
Using the CLI
After building, run the FileExplorer CLI:
# List files in current directory
pnpm -C packages/cli start .
# List files in a specific directory
pnpm -C packages/cli start /path/to/directory
# With various options
fileexplorer /path --output-format tree --verboseCLI Command Examples
Basic Usage
# List files in current directory in list format
fileexplorer .
# List files with JSON output
fileexplorer /home/user/projects --output-format json
# Display as tree structure
fileexplorer /home/user/projects --output-format treeFiltering and Exclusions
# Exclude node_modules and dist directories
fileexplorer . --exclude "node_modules" --exclude "dist"
# Exclude using regex patterns
fileexplorer . --exclude "^\\..*" --exclude ".*\\.tmp$"
# Use glob patterns
fileexplorer . --exclude "**/node_modules/**" --exclude "**/*.log"Output and Display Options
# Show detailed information (verbose mode)
fileexplorer . --verbose
# Display summary statistics
fileexplorer . --summary
# Pretty-printed JSON output
fileexplorer . --output-format json --pretty-json
# Limit depth of scan
fileexplorer . --max-depth 2Advanced Features
# Dry run (preview configuration without scanning)
fileexplorer . --dry-run
# Sort files (by name, size, or date)
fileexplorer . --sort name
# Follow symbolic links
fileexplorer . --follow-symlinks
# Use configuration file
fileexplorer . --config .filebrowserc
# Show progress during scan
fileexplorer . --progress minimalLibrary Usage
Basic Scanning
Import and use the core library in your TypeScript/JavaScript code:
import { Scanner } from '@fileexplorer/core';
const scanner = new Scanner();
const result = await scanner.scan({
path: '/path/to/directory',
includeHidden: false,
followSymlinks: false,
maxDepth: -1, // -1 means unlimited
});
console.log(`Found ${result.items.length} items`);
result.items.forEach((item) => {
console.log(`${item.type}: ${item.relativePath}`);
});Advanced Filtering
import { Scanner } from '@fileexplorer/core';
const scanner = new Scanner();
const result = await scanner.scan({
path: '/path/to/project',
excludePatterns: ['node_modules', 'dist', '.*'],
sortBy: 'name',
outputFormat: 'tree',
});
console.log(result);Using Convenience Function
import { scan } from '@fileexplorer/core';
const result = await scan({
path: '/path/to/directory',
excludePatterns: ['*.log', 'tmp/**'],
sortBy: 'size',
});
console.log(`Summary: ${result.summary.totalFiles} files, ${result.summary.totalDirectories} directories`);Streaming Results
import { scanStream } from '@fileexplorer/core';
const signal = AbortSignal.timeout(30000); // 30 second timeout
for await (const item of scanStream(
{ path: '/large/directory' },
signal
)) {
console.log(`Processing: ${item.relativePath}`);
}Testing
Run comprehensive test suites:
# Unit and integration tests
pnpm test
# Test coverage
pnpm test:coverage
# BDD tests with Cucumber
pnpm test:bdd
# E2E tests with Playwright
pnpm test:e2e
# View E2E test report
pnpm test:e2e:report
# Run all tests
pnpm test:allDevelopment
Code Quality
# Linting
pnpm lint
# Code formatting
pnpm formatProject Structure
filebrowser/
├── packages/
│ ├── core/ # Core library package
│ │ └── src/
│ │ ├── scanner/ # File system scanning logic
│ │ ├── filter/ # Filtering logic
│ │ ├── types/ # TypeScript type definitions
│ │ └── utils/ # Utility functions
│ └── cli/ # CLI package
│ └── src/
│ ├── cli.ts # Main CLI entry point
│ ├── parser/ # Command-line argument parsing
│ ├── formatter/ # Output formatting (list, tree, JSON)
│ └── config/ # Configuration management
├── tests/ # Test suites
│ ├── e2e/ # End-to-end tests
│ ├── features/ # BDD feature files
│ └── step-definitions/ # Cucumber step definitions
└── docs/ # DocumentationConfiguration
FileExplorer can be configured via multiple sources with clear precedence:
- CLI arguments (highest priority)
- Configuration file (INI format)
- Environment variables
- Built-in defaults (lowest priority)
Configuration File Format
The configuration file uses INI format and should typically be named .filebrowserc or .filebrowserrc. The file supports the following sections:
[defaults] Section
Main application settings:
[defaults]
# Output format: list, json, or tree
output=tree
# Include hidden files (true/false)
hidden=false
# Recursive scanning (true/false, default: true)
recursive=true
# Sort files by: name, size, or time
sort=name[exclude] Section
Patterns to exclude from results:
[exclude]
# Comma-separated list of patterns (supports glob and regex)
patterns=node_modules,dist,.git,*.log,.*[include] Section
Patterns to include in results:
[include]
# Comma-separated list of file extensions
extensions=.ts,.js,.md,.jsonComplete Configuration File Example
Create a .filebrowserc file in your project:
[defaults]
output=tree
hidden=false
recursive=true
sort=name
[exclude]
patterns=node_modules,dist,.git,*.log,coverage,build,.DS_Store
[include]
extensions=.ts,.js,.tsx,.jsx,.json,.mdUsing Configuration Files
# Use default .filebrowserc in current directory
fileexplorer .
# Specify a custom config file
fileexplorer . --config /path/to/custom-config.filebrowserc
# CLI arguments override config file values
fileexplorer . --config .filebrowserc --output-format jsonEnvironment Variables
Configuration can also be set via environment variables with the FILEEXPLORER_ prefix:
# Set default output format
export FILEEXPLORER_DEFAULT_OUTPUT=tree
# Set parallelism level
export FILEEXPLORER_PARALLELISM=4
# Specify config file location
export FILEEXPLORER_CONFIG=/path/to/config
# Run with environment variables
fileexplorer .Priority Example
Given this setup:
- Default:
output_format=list - Config file:
output=tree - Environment:
FILEEXPLORER_DEFAULT_OUTPUT=json - CLI:
--output-format list
The result will be list (CLI has highest priority).
Error Handling
The library provides specific error types for different scenarios:
import {
FileExplorerError,
PathNotFoundError,
PermissionDeniedError,
InvalidArgumentError,
} from '@fileexplorer/core';
try {
await scanner.scan({ path: '/invalid' });
} catch (error) {
if (error instanceof PathNotFoundError) {
console.error('Path does not exist');
} else if (error instanceof PermissionDeniedError) {
console.error('No permission to access path');
} else if (error instanceof FileExplorerError) {
console.error('General FileExplorer error:', error.message);
}
}License
MIT License - see LICENSE file for details
Contributing
- Create a feature branch
- Make your changes
- Run tests:
pnpm test:all - Submit a pull request
For detailed architectural information, see:
