diff --git a/client/packages/cli/index.js b/client/packages/cli/index.js index 9ccc5c76c..52fd11106 100644 --- a/client/packages/cli/index.js +++ b/client/packages/cli/index.js @@ -23,6 +23,7 @@ import { } from "./src/util/packageManager.js"; import { pathExists, readJsonFile } from "./src/util/fs.js"; import prettier from "prettier"; +import toggle from "./src/toggle.js"; const execAsync = promisify(exec); @@ -460,7 +461,10 @@ async function handleEnvFile(pkgAndAuthInfo, appId) { console.log( `If we set ${chalk.green("`" + envName + "`")}, we can remember the app that you chose for all future commands.`, ); - const ok = await promptOk("Want us to create this env file for you?"); + const ok = await promptOk( + "Want us to create this env file for you?", + /*defaultAnswer=*/ true, + ); if (!ok) { console.log( `No .env file created. You can always set ${chalk.green("`" + envName + "`")} later. \n`, @@ -517,6 +521,7 @@ async function login(options) { const ok = await promptOk( `This will open instantdb.com in your browser, OK to proceed?`, + /*defaultAnswer=*/ true, ); if (!ok) return; @@ -632,6 +637,7 @@ async function promptImportAppOrCreateApp() { if (!apps.length) { const ok = await promptOk( "You don't have any apps. Want to create a new one?", + /*defaultAnswer=*/ true, ); if (!ok) return { ok: false }; return await promptCreateApp(); @@ -1288,14 +1294,13 @@ function prettyPrintJSONErr(data) { } } -async function promptOk(message) { +async function promptOk(message, defaultAnswer = false) { const options = program.opts(); if (options.yes) return true; - - return await confirm({ + return await toggle({ message, - default: false, + default: defaultAnswer, }).catch(() => false); } diff --git a/client/packages/cli/package.json b/client/packages/cli/package.json index a1fc32707..9119e1950 100644 --- a/client/packages/cli/package.json +++ b/client/packages/cli/package.json @@ -10,7 +10,9 @@ "instant-cli": "bin/index.js" }, "dependencies": { - "@inquirer/prompts": "^5.3.8", + "@inquirer/prompts": "5.3.8", + "@inquirer/core": "9.0.10", + "ansi-escapes": "4.3.2", "chalk": "^5.3.0", "commander": "^12.1.0", "dotenv": "^16.3.1", diff --git a/client/packages/cli/src/toggle.js b/client/packages/cli/src/toggle.js new file mode 100644 index 000000000..5b65ff94d --- /dev/null +++ b/client/packages/cli/src/toggle.js @@ -0,0 +1,53 @@ +// From: +// https://github.com/skarahoda/inquirer-toggle +import { + isDownKey, + isUpKey, + useKeypress, + useState, + isEnterKey, +} from "@inquirer/core"; +import { createPrompt, usePrefix, makeTheme } from "@inquirer/core"; +import ansiEscapes from "ansi-escapes"; + +function isLeftKey(key) { + return key.name === "left"; +} + +function isRightKey(key) { + return key.name === "right"; +} + +export default createPrompt((config, done) => { + const theme = makeTheme({ active: "yes", inactive: "no" }, config.theme); + const prefix = usePrefix({ theme }); + const [value, setValue] = useState(config.default ?? false); + const [isDone, setIsDone] = useState(false); + + useKeypress((key) => { + if (isEnterKey(key)) { + setIsDone(true); + done(value); + } else if ( + isLeftKey(key) || + isRightKey(key) || + isUpKey(key) || + isDownKey(key) + ) { + setValue(!value); + } + }); + const message = theme.style.message(config.message); + + if (isDone) { + return `${prefix} ${message} ${theme.style.answer(value ? theme.active : theme.inactive)}`; + } + + const activeMessage = value + ? theme.style.highlight(theme.active) + : theme.active; + const inactiveMessage = value + ? theme.inactive + : theme.style.highlight(theme.inactive); + return `${prefix} ${message} ${inactiveMessage} / ${activeMessage}${ansiEscapes.cursorHide}`; +}); diff --git a/client/pnpm-lock.yaml b/client/pnpm-lock.yaml index 12b658395..fbbdce8f0 100644 --- a/client/pnpm-lock.yaml +++ b/client/pnpm-lock.yaml @@ -42,9 +42,15 @@ importers: packages/cli: dependencies: + '@inquirer/core': + specifier: 9.0.10 + version: 9.0.10 '@inquirer/prompts': - specifier: ^5.3.8 + specifier: 5.3.8 version: 5.3.8 + ansi-escapes: + specifier: 4.3.2 + version: 4.3.2 chalk: specifier: ^5.3.0 version: 5.3.0