Websocket
[VSoRC/.git] / node_modules / wscat / node_modules / read / lib / read.js
1
2 module.exports = read
3
4 var readline = require('readline')
5 var Mute = require('mute-stream')
6
7 function read (opts, cb) {
8   if (opts.num) {
9     throw new Error('read() no longer accepts a char number limit')
10   }
11
12   if (typeof opts.default !== 'undefined' &&
13       typeof opts.default !== 'string' &&
14       typeof opts.default !== 'number') {
15     throw new Error('default value must be string or number')
16   }
17
18   var input = opts.input || process.stdin
19   var output = opts.output || process.stdout
20   var prompt = (opts.prompt || '').trim() + ' '
21   var silent = opts.silent
22   var editDef = false
23   var timeout = opts.timeout
24
25   var def = opts.default || ''
26   if (def) {
27     if (silent) {
28       prompt += '(<default hidden>) '
29     } else if (opts.edit) {
30       editDef = true
31     } else {
32       prompt += '(' + def + ') '
33     }
34   }
35   var terminal = !!(opts.terminal || output.isTTY)
36
37   var m = new Mute({ replace: opts.replace, prompt: prompt })
38   m.pipe(output, {end: false})
39   output = m
40   var rlOpts = { input: input, output: output, terminal: terminal }
41
42   if (process.version.match(/^v0\.6/)) {
43     var rl = readline.createInterface(rlOpts.input, rlOpts.output)
44   } else {
45     var rl = readline.createInterface(rlOpts)
46   }
47
48
49   output.unmute()
50   rl.setPrompt(prompt)
51   rl.prompt()
52   if (silent) {
53     output.mute()
54   } else if (editDef) {
55     rl.line = def
56     rl.cursor = def.length
57     rl._refreshLine()
58   }
59
60   var called = false
61   rl.on('line', onLine)
62   rl.on('error', onError)
63
64   rl.on('SIGINT', function () {
65     rl.close()
66     onError(new Error('canceled'))
67   })
68
69   var timer
70   if (timeout) {
71     timer = setTimeout(function () {
72       onError(new Error('timed out'))
73     }, timeout)
74   }
75
76   function done () {
77     called = true
78     rl.close()
79
80     if (process.version.match(/^v0\.6/)) {
81       rl.input.removeAllListeners('data')
82       rl.input.removeAllListeners('keypress')
83       rl.input.pause()
84     }
85
86     clearTimeout(timer)
87     output.mute()
88     output.end()
89   }
90
91   function onError (er) {
92     if (called) return
93     done()
94     return cb(er)
95   }
96
97   function onLine (line) {
98     if (called) return
99     if (silent && terminal) {
100       output.unmute()
101       output.write('\r\n')
102     }
103     done()
104     // truncate the \n at the end.
105     line = line.replace(/\r?\n$/, '')
106     var isDefault = !!(editDef && line === def)
107     if (def && !line) {
108       isDefault = true
109       line = def
110     }
111     cb(null, line, isDefault)
112   }
113 }