# Examples
## 1 β Process execution with real-time monitoring
> Execute commands with live output streaming and error handling.
```ts
import { executeProcess, ProcessObserver } from '@push-based/utils';
// Create an observer to handle process events
const observer: ProcessObserver = {
onStdout: (data) => {
console.log(`π€ ${data.trim()}`);
},
onStderr: (data) => {
console.error(`β ${data.trim()}`);
},
onError: (error) => {
console.error(`Process failed with code ${error.code}`);
},
onComplete: () => {
console.log('β
Process completed successfully');
},
};
// Execute a Node.js command
const result = await executeProcess({
command: 'node',
args: ['--version'],
observer,
});
console.log(`Exit code: ${result.code}`);
console.log(`Duration: ${result.duration}ms`);
console.log(`Output: ${result.stdout.trim()}`);
// Output:
// β π€ v18.17.0
// β β
Process completed successfully
// β Exit code: 0
// β Duration: 45ms
// β Output: v18.17.0
```
---
## 2 β File pattern searching and processing
> Search for files containing specific patterns and process the results.
```ts
import {
findFilesWithPattern,
findInFile,
resolveFileCached,
} from '@push-based/utils';
// Find all TypeScript files containing 'Component'
const componentFiles = await findFilesWithPattern('./src', 'Component');
console.log(`Found ${componentFiles.length} files with 'Component':`);
componentFiles.forEach((file) => console.log(` - ${file}`));
// Get detailed information about matches in a specific file
if (componentFiles.length > 0) {
const firstFile = componentFiles[0];
const matches = await findInFile(firstFile, 'Component');
console.log(`\nDetailed matches in ${firstFile}:`);
matches.forEach((match) => {
console.log(
` Line ${match.position.startLine}, Column ${match.position.startColumn}`
);
});
// Load and cache the file content
const content = await resolveFileCached(firstFile);
console.log(`File size: ${content.length} characters`);
// Subsequent calls will use cached version
const cachedContent = await resolveFileCached(firstFile); // β‘ Fast cached access
}
// Output:
// β Found 3 files with 'Component':
// β - ./src/app/user.component.ts
// β - ./src/app/admin.component.ts
// β - ./src/shared/base.component.ts
// β
// β Detailed matches in ./src/app/user.component.ts:
// β Line 5, Column 14
// β Line 12, Column 25
// β File size: 1247 characters
```
---
## 3 β Command formatting and logging
> Format commands with colors and context for better development experience.
```ts
import { formatCommandLog, isVerbose, calcDuration } from '@push-based/utils';
// Set verbose mode for demonstration
process.env['NG_MCP_VERBOSE'] = 'true';
// Format commands with different contexts
const commands = [
{ cmd: 'npm', args: ['install'], cwd: undefined },
{ cmd: 'npx', args: ['eslint', '--fix', 'src/'], cwd: './packages/app' },
{ cmd: 'node', args: ['build.js', '--prod'], cwd: '../tools' },
{
cmd: 'git',
args: ['commit', '-m', 'feat: add new feature'],
cwd: process.cwd(),
},
];
console.log('Formatted commands:');
commands.forEach(({ cmd, args, cwd }) => {
const formatted = formatCommandLog(cmd, args, cwd);
console.log(formatted);
});
// Performance timing example
async function timedOperation() {
const start = performance.now();
// Simulate some work
await new Promise((resolve) => setTimeout(resolve, 150));
const duration = calcDuration(start);
console.log(`Operation completed in ${duration}ms`);
}
// Verbose logging check
if (isVerbose()) {
console.log('π Verbose logging is enabled');
await timedOperation();
} else {
console.log('π Verbose logging is disabled');
}
// Output (with ANSI colors in terminal):
// β Formatted commands:
// β $ npm install
// β packages/app $ npx eslint --fix src/
// β .. $ node build.js --prod
// β $ git commit -m feat: add new feature
// β π Verbose logging is enabled
// β Operation completed in 152ms
```
---
## 4 β CLI argument generation
> Convert objects to command-line arguments for process execution.
```ts
import { objectToCliArgs, executeProcess } from '@push-based/utils';
// Simple configuration object
const config = {
_: ['npx', 'eslint'], // Command and base args
fix: true, // Boolean flag
format: 'json', // String value
ext: ['.ts', '.js'], // Array values
'max-warnings': 0, // Numeric value
quiet: false, // Negative boolean
};
const args = objectToCliArgs(config);
console.log('Generated CLI args:');
args.forEach((arg) => console.log(` ${arg}`));
// Use the generated arguments in process execution
const result = await executeProcess({
command: args[0], // 'npx'
args: args.slice(1), // Everything after the command
});
// Output:
// β Generated CLI args:
// β npx
// β eslint
// β --fix
// β --format="json"
// β --ext=".ts"
// β --ext=".js"
// β --max-warnings=0
// β --no-quiet
// Complex nested configuration
const complexConfig = {
_: ['node', 'build.js'],
output: {
path: './dist',
format: 'esm',
},
optimization: {
minify: true,
'tree-shake': true,
},
};
const complexArgs = objectToCliArgs(complexConfig);
console.log('\nComplex nested args:');
complexArgs.forEach((arg) => console.log(` ${arg}`));
// Output:
// β Complex nested args:
// β node
// β build.js
// β --output.path="./dist"
// β --output.format="esm"
// β --optimization.minify
// β --optimization.tree-shake
```
---
## 5 β Error handling and process management
> Handle process errors gracefully with comprehensive error information.
```ts
import { executeProcess, ProcessError } from '@push-based/utils';
async function robustProcessExecution() {
const commands = [
{ command: 'node', args: ['--version'] }, // β
Should succeed
{ command: 'nonexistent-command', args: [] }, // β Should fail
{ command: 'node', args: ['-e', 'process.exit(1)'] }, // β Should fail with exit code 1
];
for (const config of commands) {
try {
console.log(
`\nπ Executing: ${config.command} ${config.args?.join(' ') || ''}`
);
const result = await executeProcess({
...config,
observer: {
onStdout: (data) => console.log(` π€ ${data.trim()}`),
onStderr: (data) => console.error(` β ${data.trim()}`),
onComplete: () => console.log(' β
Process completed'),
},
});
console.log(
` β
Success! Exit code: ${result.code}, Duration: ${result.duration}ms`
);
} catch (error) {
if (error instanceof ProcessError) {
console.error(` β Process failed:`);
console.error(` Exit code: ${error.code}`);
console.error(
` Error output: ${error.stderr.trim() || 'No stderr'}`
);
console.error(
` Standard output: ${error.stdout.trim() || 'No stdout'}`
);
} else {
console.error(` β Unexpected error: ${error}`);
}
}
}
// Example with ignoreExitCode option
console.log('\nπ Executing command with ignoreExitCode=true:');
try {
const result = await executeProcess({
command: 'node',
args: ['-e', 'console.log("Hello"); process.exit(1)'],
ignoreExitCode: true,
observer: {
onStdout: (data) => console.log(` π€ ${data.trim()}`),
onComplete: () =>
console.log(' β
Process completed (exit code ignored)'),
},
});
console.log(` β
Completed with exit code ${result.code} (ignored)`);
console.log(` π Output: ${result.stdout.trim()}`);
} catch (error) {
console.error(` β This shouldn't happen with ignoreExitCode=true`);
}
}
await robustProcessExecution();
// Output:
// β π Executing: node --version
// β π€ v18.17.0
// β β
Process completed
// β β
Success! Exit code: 0, Duration: 42ms
// β
// β π Executing: nonexistent-command
// β β Process failed:
// β Exit code: null
// β Error output: spawn nonexistent-command ENOENT
// β Standard output: No stdout
// β
// β π Executing: node -e process.exit(1)
// β β Process failed:
// β Exit code: 1
// β Error output: No stderr
// β Standard output: No stdout
// β
// β π Executing command with ignoreExitCode=true:
// β π€ Hello
// β β
Process completed (exit code ignored)
// β β
Completed with exit code 1 (ignored)
// β π Output: Hello
```
---
## 6 β Advanced file operations with generators
> Use async generators for efficient file processing.
```ts
import {
findAllFiles,
accessContent,
getLineHits,
isExcludedDirectory,
} from '@push-based/utils';
// Custom file finder with filtering
async function findLargeTypeScriptFiles(
baseDir: string,
minSize: number = 1000
) {
const largeFiles: string[] = [];
// Use async generator to process files one by one
for await (const file of findAllFiles(baseDir, (path) =>
path.endsWith('.ts')
)) {
try {
const stats = await fs.stat(file);
if (stats.size > minSize) {
largeFiles.push(file);
console.log(`π Large file: ${file} (${stats.size} bytes)`);
}
} catch (error) {
console.warn(`β οΈ Could not stat file: ${file}`);
}
}
return largeFiles;
}
// Process file content line by line
async function analyzeFileContent(filePath: string, searchTerm: string) {
const content = await fs.readFile(filePath, 'utf-8');
const results = {
totalLines: 0,
matchingLines: 0,
matches: [] as Array<{ line: number; hits: number; content: string }>,
};
// Use generator to process content efficiently
let lineNumber = 0;
for (const line of accessContent(content)) {
lineNumber++;
results.totalLines++;
const hits = getLineHits(line, searchTerm);
if (hits.length > 0) {
results.matchingLines++;
results.matches.push({
line: lineNumber,
hits: hits.length,
content: line.trim(),
});
}
}
return results;
}
// Directory filtering
const directories = [
'src',
'.git',
'node_modules',
'dist',
'coverage',
'.vscode',
];
directories.forEach((dir) => {
const excluded = isExcludedDirectory(dir);
console.log(`${dir}: ${excluded ? 'β excluded' : 'β
included'}`);
});
// Usage example
const largeFiles = await findLargeTypeScriptFiles('./src', 2000);
if (largeFiles.length > 0) {
const analysis = await analyzeFileContent(largeFiles[0], 'export');
console.log(`\nAnalysis of ${largeFiles[0]}:`);
console.log(`Total lines: ${analysis.totalLines}`);
console.log(`Lines with 'export': ${analysis.matchingLines}`);
console.log(`First few matches:`);
analysis.matches.slice(0, 3).forEach((match) => {
console.log(` Line ${match.line} (${match.hits} hits): ${match.content}`);
});
}
// Output:
// β src: β
included
// β .git: β excluded
// β node_modules: β excluded
// β dist: β excluded
// β coverage: β excluded
// β .vscode: β
included
// β π Large file: ./src/lib/utils.ts (2247 bytes)
// β π Large file: ./src/lib/execute-process.ts (5043 bytes)
// β
// β Analysis of ./src/lib/utils.ts:
// β Total lines: 88
// β Lines with 'export': 5
// β First few matches:
// β Line 2 (1 hits): export function calcDuration(start: number, stop?: number): number {
// β Line 6 (1 hits): export function isVerbose(): boolean {
// β Line 14 (1 hits): export function formatCommandLog(command: string, args?: string[], cwd?: string): string {
```
---
## 7 β ES Module loading and dynamic imports
> Load ES modules dynamically and extract default exports safely.
```ts
import { loadDefaultExport } from '@push-based/utils';
// Load configuration from ES module
const config = await loadDefaultExport('./config/app.config.mjs');
console.log(`API Port: ${config.port}`);
// Load with type safety
interface AppData {
version: string;
features: string[];
}
const appData = await loadDefaultExport<AppData>('./data/app.mjs');
console.log(`App version: ${appData.version}`);
console.log(`Features: ${appData.features.join(', ')}`);
// Handle loading errors gracefully
try {
const plugin = await loadDefaultExport('./plugins/optional.mjs');
console.log('β
Plugin loaded');
} catch (error) {
if (error.message.includes('No default export found')) {
console.warn('β οΈ Module missing default export');
} else {
console.warn('β οΈ Plugin not found, continuing without it');
}
}
// Output:
// β API Port: 3000
// β App version: 1.2.0
// β Features: auth, logging, metrics
// β β οΈ Plugin not found, continuing without it
```
---
These examples demonstrate the comprehensive capabilities of the `@push-based/utils` library for process execution, file operations, string manipulation, and development tooling in Node.js applications.