UNPKG

i18ntk

Version:

🚀 The fastest i18n toolkit with 97% performance boost! Zero-dependency, enterprise-grade internationalization for React, Vue, Angular, Python, Java, PHP & more. Features PIN protection, auto framework detection, 7+ UI languages, and comprehensive transla

211 lines (173 loc) • 5.96 kB
/** * Simple CLI argument parser to replace commander * Supports commands, options, and flags */ class Command { constructor(name, description = '') { this.name = name; this.description = description; this.options = []; this.flags = []; this.commands = []; this.actionHandler = null; this.requiredArgs = []; } description(desc) { this.description = desc; return this; } option(flags, description, defaultValue, required = false) { const option = { flags, description, required, defaultValue, long: flags.split(/\s*,\s*/).find(f => f.startsWith('--')).replace('--', ''), short: (flags.split(/\s*,\s*/).find(f => f.startsWith('-') && !f.startsWith('--')) || '').replace(/-/g, '') }; this.options.push(option); return this; } requiredOption(flags, description, defaultValue) { return this.option(flags, description, defaultValue, true); } argument(name, description, validator) { this.requiredArgs.push({ name, description, validator }); return this; } action(handler) { this.actionHandler = handler; return this; } command(name, description) { const cmd = new Command(name, description); this.commands.push(cmd); return cmd; } helpInformation() { let help = []; if (this.description) { help.push(` ${this.description}\n`); } help.push('Usage:'); help.push(` ${process.argv[1]} ${this.name} [options]`); if (this.requiredArgs.length > 0) { help.push('\nArguments:'); this.requiredArgs.forEach(arg => { help.push(` ${arg.name.padEnd(20)} ${arg.description}`); }); } if (this.options.length > 0) { help.push('\nOptions:'); this.options.forEach(opt => { const flags = [ opt.short ? `-${opt.short}` : null, `--${opt.long}${opt.defaultValue !== undefined ? ` <${opt.long}>` : ''}` ].filter(Boolean).join(', '); let desc = opt.description || ''; if (opt.defaultValue !== undefined) { desc += ` (default: ${opt.defaultValue})`; } help.push(` ${flags.padEnd(30)} ${desc}`); }); } if (this.commands.length > 0) { help.push('\nCommands:'); this.commands.forEach(cmd => { help.push(` ${cmd.name.padEnd(20)} ${cmd.description || ''}`); }); } return help.join('\n'); } parse(argv = process.argv.slice(2)) { const args = {}; const commandArgs = []; let currentCommand = null; // Set default values this.options.forEach(opt => { if (opt.defaultValue !== undefined) { args[opt.long] = opt.defaultValue; } }); // Parse arguments for (let i = 0; i < argv.length; i++) { const arg = argv[i]; // Check for commands if (!arg.startsWith('-')) { const cmd = this.commands.find(c => c.name === arg); if (cmd) { currentCommand = cmd; continue; } commandArgs.push(arg); continue; } // Handle --option=value if (arg.includes('=')) { const [key, value] = arg.split('='); const option = this.options.find(opt => `--${opt.long}` === key || (opt.short && `-${opt.short}` === key) ); if (option) { args[option.long] = value === 'true' ? true : (value === 'false' ? false : value); } continue; } // Handle --option value or -o value const option = this.options.find(opt => `--${opt.long}` === arg || (opt.short && `-${opt.short}` === arg) ); if (option) { if (i + 1 < argv.length && !argv[i + 1].startsWith('-')) { const value = argv[++i]; args[option.long] = value === 'true' ? true : (value === 'false' ? false : value); } else { args[option.long] = true; } continue; } // Handle --no-* flags if (arg.startsWith('--no-')) { const flagName = arg.substring(5); args[flagName] = false; continue; } } // Check required options const missingOptions = this.options .filter(opt => opt.required && args[opt.long] === undefined) .map(opt => `--${opt.long}`); if (missingOptions.length > 0) { throw new Error(`Missing required options: ${missingOptions.join(', ')}`); } // Check required arguments if (commandArgs.length < this.requiredArgs.length) { const missingArgs = this.requiredArgs .slice(commandArgs.length) .map(arg => `<${arg.name}>`); throw new Error(`Missing required arguments: ${missingArgs.join(' ')}`); } // Call action handler if (this.actionHandler) { const actionArgs = commandArgs.slice(0, this.requiredArgs.length); const remainingArgs = commandArgs.slice(this.requiredArgs.length); // Validate argument types if validators are provided for (let i = 0; i < this.requiredArgs.length; i++) { const arg = this.requiredArgs[i]; if (arg.validator && !arg.validator(actionArgs[i])) { throw new Error(`Invalid value for argument ${arg.name}: ${actionArgs[i]}`); } } return this.actionHandler(...actionArgs, { ...args, _args: remainingArgs }); } // If we have a command, parse with that if (currentCommand) { return currentCommand.parse(commandArgs); } return { ...args, _args: commandArgs }; } } function program(name = '') { return new Command(name); } module.exports = { program, Command };