UNPKG

@teqed/interact-ibmi

Version:

Menus for interacting with IBMi AS400 using node-odbc.

184 lines (183 loc) 6.84 kB
import { createPrompt, useState, useKeypress, isEnterKey, isSpaceKey } from '@inquirer/core'; import chalk from 'chalk'; import confirm from './inquirer-confirm.js'; import input from './inquirer-input.js'; import rawlist from './inquirer-rawlist.js'; import select from './inquirer-select.js'; // The genericGetCommand function is used to get a command from the user. // It can be used to run queries or system commands, or to get input from the user. // The function takes a prompt object as an argument, which asks the user for input. // It might say something like "Please enter a command:". export const genericGetCommand = async (prompt) => { let command = await input({ default: prompt.default, message: prompt.message }, { clearPromptOnDone: prompt.clearPromptOnDone ?? true }); while ((command === `` || command === undefined || command === null) && prompt.allowEmpty === false) { // Print a message in red, 'Cannot be empty'. console.log(chalk.red(`Cannot be empty`)); // Play a sound. process.stdout.write(`\u0007`); process.stdout.moveCursor(0, -2); // eslint-disable-next-line no-await-in-loop command = await input({ default: prompt.default, message: prompt.message }, { clearPromptOnDone: prompt.clearPromptOnDone ?? true }); process.stdout.clearLine(0); } return command; }; export const genericListMenu = async (prompt) => { console.clear(); // genericListMenu is used to display a list of options to the user. const menu = await rawlist({ // Add a choice for every option in the array prompt.choices. choices: prompt.choices.map(choice => { return { name: choice, value: choice, }; }), message: prompt.message, }, { clearPromptOnDone: prompt.clearPromptOnDone ?? true }); return menu; }; export const genericSelectMenu = async (prompt) => { console.clear(); // genericSelectMenu is used to display a list of options to the user. // It takes a prompt object as an argument, which contains the menu name, // the list of options and a message. // The message might say something like "Please select an option:". // The menu name might be colored with chalk. // Accepts a menu name, message, and array of choices. // Returns the choice the user made as a number index of the array (1-indexed). // 1-index is used to match the keybindings of inquirer on the command line. // The user can press 1 to select the first option, 2 for the second, etc. const menu = await select({ // Add a choice for every option in the array prompt.choices. choices: prompt.choices.map(choice => { return { name: choice, value: choice, }; }), message: prompt.message, }, { clearPromptOnDone: prompt.clearPromptOnDone ?? true }); return menu; }; export const generatedListMenu = async (prompt) => { console.clear(); const menu = await rawlist({ choices: prompt.choices.map(choice => { return { name: choice, value: choice, }; }), message: prompt.message, }, { clearPromptOnDone: prompt.clearPromptOnDone ?? true }); return menu; }; export const generatedSelectMenu = async (prompt) => { console.clear(); const menu = await select({ choices: prompt.choices.map(choice => { return { name: choice, value: choice, }; }), message: prompt.message, }, { clearPromptOnDone: prompt.clearPromptOnDone ?? true }); return menu; }; export const genericPasswordMenu = async (config) => { return input({ default: undefined, message: config.message, // eslint-disable-next-line @typescript-eslint/no-shadow transformer(input, { isFinal }) { if (config.mask) { return String(config.mask).repeat(input.length); } if (!isFinal) { return chalk.dim(`[input is masked]`); } return ``; }, }, { clearPromptOnDone: config.clearPromptOnDone ?? true }); }; const customConfirm = createPrompt((config, done) => { const [status, setStatus] = useState(`pending`); const [value, setValue] = useState(``); switch (config.continueKey) { case `enter`: { useKeypress((key, rl) => { if (isEnterKey(key)) { const answer = value ? /^y(es)?/iu.test(value) : config.default !== false; setValue(answer ? `yes` : `no`); setStatus(`done`); rl.close(); done(answer); } else { // Ignore other keys. } }); break; } case `space`: { useKeypress((key, rl) => { if (isSpaceKey(key)) { const answer = value ? /^y(es)?/iu.test(value) : config.default !== false; setValue(answer ? `yes` : `no`); setStatus(`done`); rl.close(); done(answer); } else { // Ignore other keys. } }); break; } default: { useKeypress((key, rl) => { rl.close(); setValue(key.name); setStatus(`done`); done(true); }); break; } } let formattedValue = value; let defaultValue = ``; if (status === `done`) { formattedValue = chalk.cyan(value); } else { defaultValue = chalk.dim(``); } const message = chalk.bold(config.message); return `${message}${defaultValue} ${formattedValue}`; }); export const genericPressKeyPrompt = async () => { return await customConfirm({ message: `Press any key to continue...`, }, { clearPromptOnDone: true }); }; export const genericPressEnterPrompt = async () => { return await customConfirm({ continueKey: `enter`, message: `Press the Enter key to continue...`, }, { clearPromptOnDone: true }); }; export const genericPressSpacePrompt = async () => { return await customConfirm({ continueKey: `space`, message: `Press the Space key to continue...`, }, { clearPromptOnDone: true }); }; export const genericConfirmPrompt = async (config) => { return await confirm({ default: config._default ?? false, message: config.message, }, { clearPromptOnDone: config.clearPromptOnDone ?? true }); };