11cb0ef41Sopenharmony_ciconst readline = require('readline')
21cb0ef41Sopenharmony_ciconst Mute = require('mute-stream')
31cb0ef41Sopenharmony_ci
41cb0ef41Sopenharmony_cimodule.exports = async function read ({
51cb0ef41Sopenharmony_ci  default: def = '',
61cb0ef41Sopenharmony_ci  input = process.stdin,
71cb0ef41Sopenharmony_ci  output = process.stdout,
81cb0ef41Sopenharmony_ci  completer,
91cb0ef41Sopenharmony_ci  prompt = '',
101cb0ef41Sopenharmony_ci  silent,
111cb0ef41Sopenharmony_ci  timeout,
121cb0ef41Sopenharmony_ci  edit,
131cb0ef41Sopenharmony_ci  terminal,
141cb0ef41Sopenharmony_ci  replace,
151cb0ef41Sopenharmony_ci}) {
161cb0ef41Sopenharmony_ci  if (typeof def !== 'undefined' && typeof def !== 'string' && typeof def !== 'number') {
171cb0ef41Sopenharmony_ci    throw new Error('default value must be string or number')
181cb0ef41Sopenharmony_ci  }
191cb0ef41Sopenharmony_ci
201cb0ef41Sopenharmony_ci  let editDef = false
211cb0ef41Sopenharmony_ci  prompt = prompt.trim() + ' '
221cb0ef41Sopenharmony_ci  terminal = !!(terminal || output.isTTY)
231cb0ef41Sopenharmony_ci
241cb0ef41Sopenharmony_ci  if (def) {
251cb0ef41Sopenharmony_ci    if (silent) {
261cb0ef41Sopenharmony_ci      prompt += '(<default hidden>) '
271cb0ef41Sopenharmony_ci    } else if (edit) {
281cb0ef41Sopenharmony_ci      editDef = true
291cb0ef41Sopenharmony_ci    } else {
301cb0ef41Sopenharmony_ci      prompt += '(' + def + ') '
311cb0ef41Sopenharmony_ci    }
321cb0ef41Sopenharmony_ci  }
331cb0ef41Sopenharmony_ci
341cb0ef41Sopenharmony_ci  const m = new Mute({ replace, prompt })
351cb0ef41Sopenharmony_ci  m.pipe(output, { end: false })
361cb0ef41Sopenharmony_ci  output = m
371cb0ef41Sopenharmony_ci
381cb0ef41Sopenharmony_ci  return new Promise((resolve, reject) => {
391cb0ef41Sopenharmony_ci    const rl = readline.createInterface({ input, output, terminal, silent: true, completer })
401cb0ef41Sopenharmony_ci    const timer = timeout && setTimeout(() => onError(new Error('timed out')), timeout)
411cb0ef41Sopenharmony_ci
421cb0ef41Sopenharmony_ci    output.unmute()
431cb0ef41Sopenharmony_ci    rl.setPrompt(prompt)
441cb0ef41Sopenharmony_ci    rl.prompt()
451cb0ef41Sopenharmony_ci
461cb0ef41Sopenharmony_ci    if (silent) {
471cb0ef41Sopenharmony_ci      output.mute()
481cb0ef41Sopenharmony_ci    } else if (editDef) {
491cb0ef41Sopenharmony_ci      rl.line = def
501cb0ef41Sopenharmony_ci      rl.cursor = def.length
511cb0ef41Sopenharmony_ci      rl._refreshLine()
521cb0ef41Sopenharmony_ci    }
531cb0ef41Sopenharmony_ci
541cb0ef41Sopenharmony_ci    const done = () => {
551cb0ef41Sopenharmony_ci      rl.close()
561cb0ef41Sopenharmony_ci      clearTimeout(timer)
571cb0ef41Sopenharmony_ci      output.mute()
581cb0ef41Sopenharmony_ci      output.end()
591cb0ef41Sopenharmony_ci    }
601cb0ef41Sopenharmony_ci
611cb0ef41Sopenharmony_ci    const onError = (er) => {
621cb0ef41Sopenharmony_ci      done()
631cb0ef41Sopenharmony_ci      reject(er)
641cb0ef41Sopenharmony_ci    }
651cb0ef41Sopenharmony_ci
661cb0ef41Sopenharmony_ci    rl.on('error', onError)
671cb0ef41Sopenharmony_ci    rl.on('line', (line) => {
681cb0ef41Sopenharmony_ci      if (silent && terminal) {
691cb0ef41Sopenharmony_ci        output.unmute()
701cb0ef41Sopenharmony_ci      }
711cb0ef41Sopenharmony_ci      done()
721cb0ef41Sopenharmony_ci      // truncate the \n at the end.
731cb0ef41Sopenharmony_ci      const res = line.replace(/\r?\n?$/, '') || def || ''
741cb0ef41Sopenharmony_ci      return resolve(res)
751cb0ef41Sopenharmony_ci    })
761cb0ef41Sopenharmony_ci
771cb0ef41Sopenharmony_ci    rl.on('SIGINT', () => {
781cb0ef41Sopenharmony_ci      rl.close()
791cb0ef41Sopenharmony_ci      onError(new Error('canceled'))
801cb0ef41Sopenharmony_ci    })
811cb0ef41Sopenharmony_ci  })
821cb0ef41Sopenharmony_ci}
83