UNPKG

dop-stick

Version:

Source control tooling for versionable-upgradeable smart contracts

152 lines 6.28 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Prompt = void 0; const terminal_1 = require("./terminal"); const events_1 = require("events"); class Prompt extends events_1.EventEmitter { constructor() { super(); this.isReading = false; process.stdin.setEncoding('utf8'); } static getInstance() { if (!Prompt.instance) { Prompt.instance = new Prompt(); } return Prompt.instance; } async ask(question, options = {}) { var _a, _b; if (this.isReading) { throw new Error('Another prompt is already active'); } this.isReading = true; let input = ''; let cursorPos = 0; // Setup raw mode const wasRaw = process.stdin.isRaw; (_b = (_a = process.stdin).setRawMode) === null || _b === void 0 ? void 0 : _b.call(_a, true); return new Promise((resolve) => { const cleanup = () => { var _a, _b; (_b = (_a = process.stdin).setRawMode) === null || _b === void 0 ? void 0 : _b.call(_a, wasRaw); process.stdin.removeListener('data', onData); this.isReading = false; terminal_1.Terminal.write('\n'); }; const render = () => { terminal_1.Terminal.eraseLine(); terminal_1.Terminal.cursorTo(0); const displayText = options.mask ? '•'.repeat(input.length) : input; terminal_1.Terminal.write(`${question} ${displayText}`); }; const onData = (data) => { const key = data.toString(); // Handle special keys switch (key) { case '\u0003': // Ctrl+C cleanup(); process.exit(); break; case '\r': // Enter case '\n': const value = input || options.default || ''; if (options.validate) { const result = options.validate(value); if (result !== true) { terminal_1.Terminal.write('\n'); terminal_1.Terminal.write(terminal_1.Terminal.style(result.toString(), terminal_1.Terminal.colors.red)); terminal_1.Terminal.write('\n'); render(); return; } } cleanup(); resolve(options.transformer ? options.transformer(value) : value); break; case '\u007f': // Backspace if (cursorPos > 0) { input = input.slice(0, -1); cursorPos--; render(); } break; default: if (key.charCodeAt(0) < 32) return; // Ignore control characters input += key; cursorPos++; render(); } }; process.stdin.on('data', onData); render(); }); } async confirm(message, defaultValue = true) { const response = await this.ask(`${message} ${defaultValue ? '(Y/n)' : '(y/N)'}: `, { default: defaultValue ? 'y' : 'n', validate: (input) => { const normalized = input.toLowerCase(); return ['y', 'n', 'yes', 'no', ''].includes(normalized) || 'Please answer with y/n'; }, }); return !!response; } async select(message, choices, defaultChoice) { if (choices.length === 0) { throw new Error('No choices provided'); } terminal_1.Terminal.write(`${message}\n`); let selectedIndex = defaultChoice ? choices.indexOf(defaultChoice) : 0; const render = () => { choices.forEach((choice, index) => { terminal_1.Terminal.eraseLine(); terminal_1.Terminal.cursorTo(0); const prefix = index === selectedIndex ? '❯' : ' '; terminal_1.Terminal.write(`${prefix} ${index === selectedIndex ? terminal_1.Terminal.style(choice, terminal_1.Terminal.colors.cyan) : choice}\n`); }); terminal_1.Terminal.cursorTo(0); terminal_1.Terminal.cursorUp(choices.length - selectedIndex); }; return new Promise((resolve) => { var _a, _b; const onData = (data) => { const key = data.toString(); switch (key) { case '\u001b[A': // Up arrow selectedIndex = (selectedIndex - 1 + choices.length) % choices.length; render(); break; case '\u001b[B': // Down arrow selectedIndex = (selectedIndex + 1) % choices.length; render(); break; case '\r': // Enter cleanup(); resolve(choices[selectedIndex]); break; case '\u0003': // Ctrl+C cleanup(); process.exit(); break; } }; const cleanup = () => { var _a, _b; (_b = (_a = process.stdin).setRawMode) === null || _b === void 0 ? void 0 : _b.call(_a, false); process.stdin.removeListener('data', onData); terminal_1.Terminal.write('\n'); }; (_b = (_a = process.stdin).setRawMode) === null || _b === void 0 ? void 0 : _b.call(_a, true); process.stdin.on('data', onData); render(); }); } } exports.Prompt = Prompt; //# sourceMappingURL=prompt.js.map