UNPKG

structure-validation

Version:

A Node.js CLI tool for validating codebase folder and file structure using a clean declarative configuration. Part of the guardz ecosystem for comprehensive TypeScript development.

132 lines 4.56 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SmartInputService = void 0; class SmartInputService { constructor(rl) { this.rl = rl; } /** * Get user input with smart Enter key handling */ async getSmartInput(options) { const { validChoices, choiceRange, timeoutMs = 3000 } = options; const totalOptions = validChoices.length; return new Promise((resolve) => { const timeout = setTimeout(() => { resolve({ choice: '', requiresEnter: true, isValid: false, errorMessage: 'Input timeout. Please press Enter to continue.' }); }, timeoutMs); this.rl.question(`\nEnter your choice (${choiceRange}): `, (answer) => { clearTimeout(timeout); const choice = answer.trim(); const result = this.processInput(choice, validChoices, totalOptions); resolve(result); }); }); } /** * Process input and determine if Enter is required */ processInput(input, validChoices, totalOptions) { // Handle empty input if (input === '') { return { choice: '', requiresEnter: true, isValid: false, errorMessage: 'Empty input. Please enter a valid choice.' }; } // Handle invalid input if (!validChoices.includes(input)) { return { choice: input, requiresEnter: true, isValid: false, errorMessage: `Invalid choice. Please enter ${validChoices[0]}-${validChoices[validChoices.length - 1]}.` }; } // Smart input logic const requiresEnter = this.shouldRequireEnter(input, totalOptions); return { choice: input, requiresEnter, isValid: true }; } /** * Determine if Enter key is required based on input and total options */ shouldRequireEnter(input, totalOptions) { // Single digit input (1-9) if (input.length === 1) { const inputNum = parseInt(input); // If there are 10+ options and input is 1-9, require Enter (ambiguous) if (totalOptions >= 10 && inputNum >= 1 && inputNum <= 9) { return true; } // If there are < 10 options, don't require Enter (unambiguous) if (totalOptions < 10) { return false; } } // Double digit input (10+) if (input.length > 1) { const inputNum = parseInt(input); // If input matches an option exactly, don't require Enter if (inputNum >= 1 && inputNum <= totalOptions) { return false; } } // Default: require Enter for safety return true; } /** * Display confirmation prompt and wait for Enter */ async waitForConfirmation(message = 'Press Enter to confirm') { return new Promise((resolve) => { this.rl.question(`\n${message}: `, () => { resolve(); }); }); } /** * Display error message and wait for Enter */ async displayErrorAndWait(errorMessage) { console.log(`❌ ${errorMessage}`); return this.waitForConfirmation('Press Enter to continue'); } /** * Get additional input (like new filename or pattern) */ async getAdditionalInput(prompt) { return new Promise((resolve) => { this.rl.question(`\n${prompt}: `, (answer) => { resolve(answer.trim()); }); }); } /** * Process input with smart handling and confirmation if needed */ async processInputWithConfirmation(options, onValidInput) { const result = await this.getSmartInput(options); if (!result.isValid) { await this.displayErrorAndWait(result.errorMessage || 'Invalid input'); return this.processInputWithConfirmation(options, onValidInput); } if (result.requiresEnter) { console.log(`\nSelected: ${result.choice}`); await this.waitForConfirmation(); } await onValidInput(result.choice); } } exports.SmartInputService = SmartInputService; //# sourceMappingURL=SmartInputService.js.map