maildev
Version:
SMTP Server and Web Interface for reading and testing emails during development
119 lines • 4.39 kB
JavaScript
/**
* MailDev CLI Entry Point
*
* Main command-line interface for MailDev
*/
import { Command } from 'commander';
import { configureOptions, ENV_VARS, CONFIG_FILES } from '../options.js';
import { resolveConfig, validateConfig, formatValidationErrors } from '../config/index.js';
import { createOrchestrator, setupShutdownHandlers } from '../server/index.js';
import { createLogger } from '../utils/logger.js';
import { VERSION } from '../index.js';
// Initialize commander
const program = new Command();
program
.name('maildev')
.description('SMTP Server and Web Interface for email testing during development')
.version(VERSION, '-V, --version', 'Output the version number')
.addHelpText('after', ENV_VARS + CONFIG_FILES);
// Configure all CLI options
configureOptions(program);
// Add init subcommand
program
.command('init')
.description('Create a MailDev configuration file')
.option('-f, --force', 'Overwrite existing configuration file')
.option('--json', 'Create .maildevrc.json instead of maildev.config.js')
.action(async (options) => {
// Dynamic import to avoid loading init dependencies unless needed
const { runInit } = await import('../commands/init.js');
await runInit(options);
});
// Main action (default when no subcommand)
program.action(async (options) => {
// Create logger (temporary, will reconfigure after config is resolved)
const logger = createLogger({
verbose: options.verbose ?? false,
silent: options.silent ?? false,
});
try {
// Resolve configuration from all sources
const { config, configFilePath } = await resolveConfig(options);
// Reconfigure logger with final settings
logger.configure({
verbose: config.verbose ?? false,
silent: config.silent ?? false,
});
// Log config file if found
if (configFilePath) {
logger.debug(`Using config file: ${configFilePath}`);
}
// Validate configuration
const validation = validateConfig(config);
// Show warnings
for (const warning of validation.warnings) {
logger.warn(warning);
}
// Exit on validation errors
if (!validation.valid) {
logger.error(formatValidationErrors(validation));
process.exit(1);
}
// Create orchestrator
const orchestrator = createOrchestrator({
config,
logger,
});
// Setup graceful shutdown handlers
setupShutdownHandlers({
orchestrator,
logger,
});
// Start servers
await orchestrator.start();
// Print startup banner
const protocol = config.https ? 'https' : 'http';
const webUrl = `${protocol}://${config.webIp === '0.0.0.0' ? 'localhost' : config.webIp}:${config.web}${config.basePathname}`;
logger.banner([
'MailDev',
` Version: ${VERSION}`,
'',
' SMTP Server',
` Address: ${config.ip}`,
` Port: ${config.smtp}`,
config.incomingUser ? ' Auth: Enabled' : '',
config.incomingSecure ? ' TLS: Enabled' : '',
'',
...(config.disableWeb
? [' Web Interface: Disabled']
: [
' Web Interface',
` URL: ${webUrl}`,
config.webUser ? ' Auth: Enabled' : '',
config.mcp ? ` MCP: ${webUrl}mcp` : '',
]),
'',
...(config.outgoingHost
? [
' Relay',
` Host: ${config.outgoingHost}:${config.outgoingPort || 25}`,
config.autoRelay ? ' Auto: Enabled' : '',
]
: []),
'',
' Press Ctrl+C to stop',
].filter(Boolean));
}
catch (error) {
const message = error instanceof Error ? error.message : String(error);
logger.error(message);
if (options.verbose && error instanceof Error && error.stack) {
logger.debug(error.stack);
}
process.exit(1);
}
});
// Parse command line arguments
program.parse();
//# sourceMappingURL=maildev.js.map