@projectlibertylabs/p2p-peer-test
Version:
CLI tool to test libp2p connections and discover peer protocols
160 lines (143 loc) • 4.26 kB
JavaScript
import chalk from 'chalk';
import { createInterface } from 'readline';
import { EXAMPLE_MULTIADDRS } from './libp2p-connection.js';
import { parseMultiaddrs } from './utils.js';
/**
* Runs interactive mode to get multiaddr input from user
* @returns {Promise<Object>} Result object with shouldExit flag and multiaddr or exit info
*/
export async function runInteractiveMode() {
const rl = createInterface({
input: process.stdin,
output: process.stdout
});
console.log(chalk.blue('🔗 libp2p Peer Connection Tester'));
console.log('Examples:');
EXAMPLE_MULTIADDRS.slice(0, 3).forEach((addr, index) => {
console.log(`${index + 1}. ${chalk.cyan(addr)}`);
});
console.log(chalk.gray('(Run "examples" command to see all examples)'));
console.log(
chalk.yellow(
'💡 Tip: Enter multiple multiaddrs (one per line), then press Enter twice when done!'
)
);
// Handle both interactive and piped input
let input = '';
if (process.stdin.isTTY) {
// Interactive mode - collect multiple lines until blank line
console.log('Enter multiaddr(s) to test:');
console.log(
chalk.gray(
'(Enter each address on a new line, then press Enter on an empty line to start testing)'
)
);
const lines = [];
rl.on('line', (line) => {
if (line.trim() === '') {
// Empty line signals end of input
rl.close();
} else {
lines.push(line);
}
});
await new Promise((resolve) => {
rl.on('close', () => {
// Check if there's remaining input in the buffer (for last line without newline)
const remaining = rl.line;
if (remaining && remaining.trim() !== '') {
lines.push(remaining.trim());
}
// Show completion message
if (lines.length > 0) {
console.log(
chalk.green(
`✓ Collected ${lines.length} address${lines.length === 1 ? '' : 'es'}, starting tests...\n`
)
);
}
input = lines.join('\n');
resolve();
});
});
} else {
// Piped input - read all lines
rl.close();
const chunks = [];
for await (const chunk of process.stdin) {
chunks.push(chunk);
}
input = Buffer.concat(chunks).toString();
}
try {
if (!input.trim()) {
return {
shouldExit: true,
exitCode: 0,
message: 'No multiaddr provided. Exiting.'
};
}
// Parse multiple multiaddrs from input
const multiaddrs = parseMultiaddrs(input);
if (multiaddrs.length === 0) {
return {
shouldExit: true,
exitCode: 1,
error: 'No valid multiaddrs found in input'
};
}
return {
shouldExit: false,
multiaddrs,
isMultiple: multiaddrs.length > 1
};
} catch (error) {
rl.close();
return {
shouldExit: true,
exitCode: 1,
error: error.message
};
}
}
/**
* Shows example multiaddrs to the user
* @returns {Object} Exit result with shouldExit true and exitCode 0
*/
export function showExamples() {
console.log('Example multiaddrs:');
EXAMPLE_MULTIADDRS.forEach((addr, index) => {
console.log(`${index + 1}. ${chalk.cyan(addr)}`);
});
return { shouldExit: true, exitCode: 0 };
}
/**
* Determines if progress should be shown for retry attempts
* @param {Object} options - CLI options
* @param {number} attempt - Current attempt number
* @param {number} totalAttempts - Total number of attempts
* @returns {boolean} True if progress should be shown
*/
export function shouldShowProgress(options, attempt, totalAttempts) {
return !options.json && attempt > 1 && totalAttempts > 1;
}
/**
* Formats a progress message for retry attempts
* @param {number} attempt - Current attempt number
* @param {number} totalRetries - Total number of retries
* @returns {string|null} Formatted progress message or null for first attempt
*/
export function formatProgressMessage(attempt, totalRetries) {
if (attempt === 1) return null;
return `Retry attempt ${attempt - 1}/${totalRetries}...`;
}
/**
* Formats a retry message for failed attempts
* @param {number} attempt - Current attempt number
* @param {number} totalAttempts - Total number of attempts
* @returns {string|null} Formatted retry message or null for final attempt
*/
export function formatRetryMessage(attempt, totalAttempts) {
if (attempt >= totalAttempts) return null;
return `Attempt ${attempt} failed, retrying...`;
}