Skip to content

Commit

Permalink
fix: allow long text in ux.prompt
Browse files Browse the repository at this point in the history
  • Loading branch information
mdonnalley committed Feb 12, 2024
1 parent e54ed76 commit 7d521b2
Showing 1 changed file with 23 additions and 15 deletions.
38 changes: 23 additions & 15 deletions src/cli-ux/prompt.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import chalk from 'chalk'
import readline from 'node:readline'

import * as Errors from '../errors'
import {config} from './config'
Expand Down Expand Up @@ -26,29 +27,36 @@ interface IPromptConfig {

function normal(options: IPromptConfig, retries = 100): Promise<string> {
if (retries < 0) throw new Error('no input')
const ac = new AbortController()
const {signal} = ac

return new Promise((resolve, reject) => {
let timer: NodeJS.Timeout
if (options.timeout) {
timer = setTimeout(() => {
process.stdin.pause()
reject(new Error('Prompt timeout'))
}, options.timeout)
timer.unref()
}
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
})

process.stdin.setEncoding('utf8')
process.stderr.write(options.prompt)
process.stdin.resume()
process.stdin.once('data', (b) => {
if (timer) clearTimeout(timer)
process.stdin.pause()
const data: string = (typeof b === 'string' ? b : b.toString()).trim()
rl.question(options.prompt, {signal}, (answer) => {
rl.close()
const data = answer.trim()
if (!options.default && options.required && data === '') {
resolve(normal(options, retries - 1))
} else {
resolve(data || (options.default as string))
}
})

if (options.timeout) {
signal.addEventListener(
'abort',
() => {
reject(new Error('Prompt timeout'))
},
{once: true},
)

setTimeout(() => ac.abort(), options.timeout)
}
})
}

Expand Down

0 comments on commit 7d521b2

Please sign in to comment.