@eftech93/nodesh
v0.0.2
Published
Interactive shell for Node.js applications (Express, NestJS, etc.) with autocompletion
Maintainers
Readme
NodeSH
An interactive shell for Node.js applications. Works with Express, NestJS, and any Node.js framework. Load your entire app context—models, services, configs, databases—and interact with them in a REPL with autocompletion.
Built with TypeScript for full type safety.
Features
- 🚀 Framework Agnostic - Works with Express, NestJS, or vanilla Node.js
- 🔄 Auto-Detection - Automatically detects Express vs NestJS projects
- 📦 Auto-Loading - Automatically loads models, services, config files
- 🎯 Intelligent Autocompletion - Deep tab completion for object properties, methods, and prototype chains
- Completes instance methods:
userService.findById,orderService.create - Completes static methods:
User.find,User.create - Completes nested properties:
config.database.url - Discovers inherited methods from prototype chains
- Completes instance methods:
- 🔍 Object Introspection - Built-in helper methods to explore objects
info(obj)- Get detailed metadata about any objectmethods(obj)- List all methods of an objectprops(obj)- List all properties of an objecttype(obj)- Get the type of an object
- 🔄 Hot Reload - Reload your app without restarting the shell
- 🎨 Syntax Highlighting - Colorized output for better readability
- 📜 Command History - Persistent history across sessions
- 🔷 Full TypeScript Support - Written in TypeScript, includes type definitions
- 🔧 Customizable - Configure via
.nodesh.jsorpackage.json - 🗄️ Multi-Database Support - 7+ databases supported:
- 🍃 MongoDB (Mongoose)
- 🐘 PostgreSQL (pg)
- 🐬 MySQL (mysql2)
- ⚡ Redis (ioredis)
- 📊 Prisma (Universal ORM)
- 🕸️ Neo4j (Graph Database)
- 📦 DynamoDB (AWS)
- 🌐 API Client - Built-in HTTP client for testing external and local APIs
- 📬 Queue Management - Full BullMQ/Bull queue control (pause, resume, retry, clean)
- 🧪 Testing Helpers - API testing, seeding, timing utilities built-in
Installation
Global Install (Recommended)
npm install -g @eftech93/nodeshThen use it with any project:
cd my-project
nodesh --yes
# Or use the shorter aliases:
nsh --yes # 3 characters
eft --yes # EFTECH93 brandLocal Install (Per Project)
npm install --save-dev @eftech93/nodeshQuick Start
1. Start Your Infrastructure
If using MongoDB/Redis (see examples):
docker-compose -f docker-compose.yml up -d2. Launch the Shell
# Auto-detects Express or NestJS
cd my-project
nodesh
# Auto-generate config on first run
nodesh --yes
# Shorter aliases (all do the same thing):
nsh --yes # 3 characters - shortest!
eft --yes # EFTECH93 brand3. Start Coding
// Query database
node> await User.find({ isActive: true })
// Use services
node> await userService.create({ email: '[email protected]' })
// Check cache
node> await cacheService.getStats()
// View queues
node> await queueService.getAllStatuses()
// Make HTTP requests
node> await apiService.get('https://api.example.com/users')
node> await apiService.local('GET', '/users')
// Reload after code changes
node> .reloadAuto-Configuration
On first run, nodesh automatically:
- Detects your framework (Express or NestJS)
- Detects TypeScript (checks for
tsconfig.json) - Generates appropriate config (
.nodesh.js)
| Detected | Prompt | Entry Point |
|----------|--------|-------------|
| Express | express> | src/app.js |
| NestJS | nest> | src/main.ts |
| TypeScript | Same | .ts extensions |
Configuration
Via .nodesh.js
module.exports = {
// Path to your app entry file
appEntry: 'src/app.js',
// Directories to auto-load
modelsDir: 'src/models',
servicesDir: 'src/services',
helpersDir: 'helpers',
configDir: 'config',
// REPL settings
prompt: 'myapp> ',
useColors: true,
historyFile: '~/.myapp_history',
// Custom context
context: {
db: require('./src/database'),
redis: require('./src/redis'),
}
};Via package.json
{
"nodesh": {
"appEntry": "src/server.js",
"prompt": "api> ",
"useColors": true
}
}Shell Commands
Type these in the shell (with the . prefix):
| Command | Description |
|---------|-------------|
| .reload | Reload all application files |
| .routes | List all Express routes |
| .models | Show loaded models |
| .services | List loaded services |
| .config | Display configuration |
| .env | Show environment variables |
| .clear | Clear screen |
| .help | Show help |
| .exit | Exit shell |
CLI Options
nodesh [path] [options]
Options:
-e, --entry <file> Path to app entry file
-r, --root <path> Project root directory
--no-color Disable colored output
-p, --prompt <string> REPL prompt string
--env <environment> Set NODE_ENV (default: development)
--nestjs Force NestJS mode detection
--express Force Express mode (skip NestJS detection)
--init Create config file (auto-detects type)
-y, --yes Auto-generate config if not found
-h, --help Display help
-V, --version Display versionLibrary Features
🗄️ Multi-Database Support
NodeSH includes a unified database connection manager supporting 7+ databases with automatic detection from environment variables:
| Database | Type | Adapter | Environment Variable |
|----------|------|---------|---------------------|
| 🍃 MongoDB | Document | mongoose | MONGODB_URI |
| 🐘 PostgreSQL | Relational | pg | DATABASE_URL or PGHOST |
| 🐬 MySQL | Relational | mysql2 | DATABASE_URL or MYSQL_HOST |
| ⚡ Redis | Key-Value | ioredis | REDIS_URL or REDIS_HOST |
| 📊 Prisma | Universal ORM | @prisma/client | DATABASE_URL |
| 🕸️ Neo4j | Graph | neo4j-driver | NEO4J_URI |
| 📦 DynamoDB | NoSQL | aws-sdk | AWS_REGION |
Quick Start:
const { initDatabases, getConnectionManager } = require('@eftech93/nodesh');
// Auto-detect and connect all configured databases
const { manager, helpers } = await initDatabases();
// Access any connection
const mongo = manager.get('mongodb');
const postgres = manager.get('postgresql');
const redis = manager.get('redis');
const neo4j = manager.get('neo4j');
const dynamo = manager.get('dynamodb');
const prisma = manager.get('prisma');
// Get stats for all databases
await helpers.getDBStats();DynamoDB Table Creation:
const dynamo = manager.get('dynamodb');
// Create table with GSI support
await dynamo.createTable({
tableName: 'Users',
keySchema: [
{ attributeName: 'pk', keyType: 'HASH' },
{ attributeName: 'sk', keyType: 'RANGE' }
],
attributeDefinitions: [
{ attributeName: 'pk', attributeType: 'S' },
{ attributeName: 'sk', attributeType: 'S' },
{ attributeName: 'email', attributeType: 'S' }
],
billingMode: 'PAY_PER_REQUEST',
globalSecondaryIndexes: [
{
indexName: 'EmailIndex',
keySchema: [{ attributeName: 'email', keyType: 'HASH' }],
projectionType: 'ALL'
}
]
});In the NodeSH Shell:
// MongoDB operations
node> await User.find({ isActive: true })
node> await User.countDocuments()
// Redis operations
node> await cacheService.get('user:123')
node> await cacheService.set('user:123', user, 3600)
// PostgreSQL queries
node> const result = await pg.query('SELECT * FROM users WHERE active = $1', [true])See Database Guide for detailed configuration.
Testing Helpers
Built-in utilities for testing and debugging:
// Timing operations
const { run, measure, batch } = require('@eftech93/nodesh');
await run(() => User.find(), 'Find all users');
const { result, duration } = await measure(() => heavyOperation());
// Run multiple operations
await batch([
() => User.findById('1'),
() => User.findById('2'),
() => User.findById('3'),
]);API Testing
Test API routes directly in the console:
const { http, ApiTester, debugApi } = require('@eftech93/nodesh');
// Simple HTTP calls
await http.get('/api/users');
await http.post('/api/users', { name: 'John', email: '[email protected]' });
// Using ApiTester class
const api = new ApiTester('http://localhost:3000/api');
await api.get('/users', { page: '1', limit: '10' });
// Debug API calls step-by-step
await debugApi('/api/users/123', 'GET');Database Seeding
Built-in seeding utilities:
const { seed, seedUsers, clear, showStats } = require('@eftech93/nodesh');
// Generic seeding
await seed({
count: 100,
create: (i) => User.create({ name: `User ${i}`, email: `user${i}@test.com` }),
batchSize: 10,
});
// User seeding with fake data
await seedUsers({
count: 50,
create: (data) => User.create(data),
roles: ['user', 'admin'],
});
// Show database stats
await showStats({
users: () => User.countDocuments(),
orders: () => Order.countDocuments(),
});
// Clear all data
await clear([
() => User.deleteMany({}),
() => Order.deleteMany({}),
]);Formatting Utilities
const { formatTable, formatBytes, formatDuration } = require('@eftech93/nodesh');
// Format as table
console.log(formatTable([
{ name: 'User', count: 100 },
{ name: 'Order', count: 500 },
]));
// Format bytes
formatBytes(1024); // "1 KB"
formatBytes(1048576); // "1 MB"
// Format duration
formatDuration(500); // "500ms"
formatDuration(5000); // "5.00s"
formatDuration(120000); // "2m 0.00s"🌐 API Client
Built-in HTTP client for testing APIs directly in the console:
// Configure base URL
apiService.setBaseURL('https://api.example.com')
// Make HTTP requests
const users = await apiService.get('/users')
const user = await apiService.get('/users/1')
const newUser = await apiService.post('/users', { name: 'John', email: '[email protected]' })
const updated = await apiService.put('/users/1', { name: 'Jane' })
const deleted = await apiService.delete('/users/1')
// Test connectivity
const ping = await apiService.ping('https://api.example.com/health')
// => { success: true, latency: 45, status: 200 }
// Call your own API (auto-uses localhost:3000)
const localUsers = await apiService.local('GET', '/users')
const newOrder = await apiService.local('POST', '/orders', { productId: '123', quantity: 2 })📬 Queue Management
Full queue control for BullMQ/Bull queues:
// Get all queue statuses
await queueDashboardController.getAllQueueStatuses()
// Pause/Resume queues
await queueDashboardController.pauseQueue('email')
await queueDashboardController.resumeQueue('email')
// Get jobs with status filtering
await queueDashboardController.getJobs('email', 'failed')
await queueDashboardController.getJobs('email', 'waiting', 0, 19)
// Retry failed jobs
await queueDashboardController.retryJob('email', 'job-id-123')
// Retry all failed jobs
const failed = await queueDashboardController.getJobs('email', 'failed')
for (const job of failed) {
await queueDashboardController.retryJob('email', job.id)
}
// Clean old jobs
await queueDashboardController.cleanQueue('email', 'completed', 100)
// Schedule job for future
await queueDashboardController.scheduleJob(
'email',
'send-welcome',
{ to: '[email protected]' },
new Date(Date.now() + 60000) // 1 minute from now
)
// Get queue metrics
await queueDashboardController.getQueueMetrics('email')Examples
Express + MongoDB + Redis + BullMQ
See example/ directory for a complete Express application with:
- MongoDB (Mongoose)
- Redis (caching)
- BullMQ (job queues)
- Full CRUD services
cd example
npm install
npm run docker:up
npm run consoleNestJS + MongoDB + Redis + BullMQ
See example-nestjs/ directory for a complete NestJS application with:
- MongoDB (Mongoose)
- Redis (caching)
- BullMQ (queues with processors)
- Full feature modules
cd example-nestjs
npm install
npm run docker:up
npm run build
npm run consoleIntelligent Autocomplete
The shell provides intelligent autocompletion for exploring your application's objects:
// Press TAB after the dot to see available methods
node> userService.<TAB>
// Shows: create, findById, findByEmail, findActive, update, delete, authenticate, getStats, clearCache
// Partial completion - type a few letters and press TAB
node> userService.find<TAB>
// Shows: findById, findByEmail, findActive
// Static/class methods on models
node> User.<TAB>
// Shows: find, findOne, findById, create, updateOne, deleteOne, countDocuments
// Deep nested property access
node> config.database.<TAB>
// Shows: url, host, port, name
// Array/Collection methods
node> users.map<TAB>
// Shows: map, filter, reduce, forEach, find, etc.Object Introspection Helpers
Special helper functions are available in the shell to explore objects:
// Get detailed information about any object
node> info(userService)
// Returns:
// {
// name: 'userService',
// type: 'UserService',
// constructor: 'UserService',
// properties: [...],
// methods: [...]
// }
// List all methods of an object
node> methods(userService)
// Returns: ['create', 'findById', 'findByEmail', 'findActive', 'update', 'delete', ...]
// List all properties (non-methods) of an object
node> props(config)
// Returns: ['env', 'port', 'database', 'redis', 'jwt']
// Get the type of any value
node> type(userService)
// Returns: 'UserService'
node> type(User)
// Returns: 'Object' or the class nameShell Session Examples
Express Example
express> await UserService.create({
email: '[email protected]',
password: 'password123',
name: { first: 'Alice', last: 'Smith' }
})
express> const user = await UserService.findByEmail('[email protected]')
express> await OrderService.create(user._id, items, shippingAddress)
express> await QueueService.getAllStatuses()
express> await CacheService.getStats()NestJS Example
nest> const user = await usersService.create({
email: '[email protected]',
password: 'password123',
name: { first: 'Bob', last: 'Jones' }
})
nest> await usersService.findById(user._id.toString())
nest> await ordersService.create(user._id.toString(), items, address)
nest> await queuesService.getAllStatuses()
nest> await cacheService.getStats()Global Installation Guide
When installed globally (npm install -g @eftech93/nodesh), you can use it with any project:
# Navigate to any project
cd ~/projects/my-api
# Run shell (auto-detects project type)
nodesh
# Auto-generate config on first run
nodesh --yesTypeScript Usage
The library is written in TypeScript and includes full type definitions.
import { ExpressConsole, AppLoader } from '@eftech93/nodesh';
async function startConsole(): Promise<void> {
const console = new ExpressConsole({
rootPath: __dirname,
appEntry: 'app.ts',
prompt: 'dev> '
});
await console.start();
}Programmatic API
Using the Intelligent Completer
You can use the autocomplete functionality in your own code:
import { IntelligentCompleter } from '@eftech93/nodesh';
const context = {
userService: new UserService(),
orderService: new OrderService()
};
const completer = new IntelligentCompleter(context);
// Get completions for a partial input
const [completions] = completer.complete('userService.find');
console.log(completions); // ['findById', 'findByEmail', 'findActive']
// Introspect an object
const metadata = completer.introspect('userService');
console.log(metadata.properties);
console.log(metadata.type);
console.log(metadata.constructor);
// Get type information
const type = completer.getTypeName(context.userService);
console.log(type); // 'UserService'Creating Custom REPL with Autocomplete
import { createCompleter, addIntrospectionMethods } from '@eftech93/nodesh';
import repl from 'repl';
const context = {
myService: new MyService()
};
const replServer = repl.start({
prompt: 'myapp> ',
completer: createCompleter(context)
});
// Add introspection helpers
addIntrospectionMethods(replServer.context);
Object.assign(replServer.context, context);Development
Running Tests
The library includes comprehensive unit tests and integration tests using Jest:
# Run all unit tests
npm test
# Run tests in watch mode
npm test -- --watch
# Run tests with coverage
npm test -- --coverageIntegration Tests
Integration tests verify the CLI works with real projects and databases:
# Start test databases (Docker required)
npm run test:docker:up
# Run all integration tests
npm run test:integration
# Run specific integration tests
npm run test:integration:nextjs
npm run test:integration:nestjs
npm run test:integration:express
# Stop test databases
npm run test:docker:downTest infrastructure includes 6 databases running on custom ports:
- MongoDB (port 9000)
- Redis (port 9001)
- PostgreSQL (port 9002)
- MySQL (port 9003)
- Neo4j (ports 9004/9005)
- DynamoDB Local (port 9006)
Test Structure
Tests are organized in the tests/ directory:
autocomplete.test.ts- Tests for intelligent autocomplete functionalityconfig.test.ts- Tests for configuration loadingloader.test.ts- Tests for application loadingconsole.test.ts- Tests for the main console classtypes.test.ts- Tests for TypeScript type definitionsintegration/- Integration tests with real projects and databases
Building
# Build TypeScript to JavaScript
npm run build
# Build in watch mode
npm run dev
# Clean build artifacts
npm run cleanTroubleshooting
MongoDB/Redis Connection Issues
Make sure your infrastructure is running:
docker-compose up -dModule Not Found
The shell will show warnings but continue. Fix paths in .nodesh.js:
module.exports = {
modelsDir: 'dist/models', // For compiled TS
servicesDir: 'dist/services'
};App Not Found
Specify the entry file explicitly:
nodesh --entry dist/main.jsDocker Compose (For Examples)
Included docker-compose.yml provides:
| Service | Port | Description | |---------|------|-------------| | MongoDB | 27017 | Database | | Redis | 6379 | Cache & Queue | | Redis Commander | 8081 | Redis UI |
docker-compose up -d
docker-compose downInspired By
License
MIT
