1+ 'use strict' ;
2+
3+ const {
4+ NumberIsInteger,
5+ ObjectSetPrototypeOf,
6+ } = primordials ;
7+
8+ const net = require ( 'net' ) ;
9+ const { TTY , isTTY } = internalBinding ( 'tty_wrap' ) ;
10+ const {
11+ ErrnoException,
12+ codes : {
13+ ERR_INVALID_FD ,
14+ ERR_TTY_INIT_FAILED ,
15+ } ,
16+ } = require ( 'internal/errors' ) ;
17+ const {
18+ getColorDepth,
19+ hasColors,
20+ } = require ( 'internal/tty' ) ;
21+
22+ // Lazy loaded for startup performance.
23+ let readline ;
24+
25+ function isatty ( fd ) {
26+ return NumberIsInteger ( fd ) && fd >= 0 && fd <= 2147483647 &&
27+ isTTY ( fd ) ;
28+ }
29+
30+ function ReadStream ( fd , options ) {
31+ if ( ! ( this instanceof ReadStream ) )
32+ return new ReadStream ( fd , options ) ;
33+ if ( fd >> 0 !== fd || fd < 0 )
34+ throw new ERR_INVALID_FD ( fd ) ;
35+
36+ const ctx = { } ;
37+ const tty = new TTY ( fd , ctx ) ;
38+ if ( ctx . code !== undefined ) {
39+ throw new ERR_TTY_INIT_FAILED ( ctx ) ;
40+ }
41+
42+ net . Socket . call ( this , {
43+ readableHighWaterMark : 0 ,
44+ handle : tty ,
45+ manualStart : true ,
46+ ...options ,
47+ } ) ;
48+
49+ this . isRaw = false ;
50+ this . isTTY = true ;
51+ }
52+
53+ ObjectSetPrototypeOf ( ReadStream . prototype , net . Socket . prototype ) ;
54+ ObjectSetPrototypeOf ( ReadStream , net . Socket ) ;
55+
56+ ReadStream . prototype . setRawMode = function ( flag ) {
57+ flag = ! ! flag ;
58+ const err = this . _handle ?. setRawMode ( flag ) ;
59+ if ( err ) {
60+ this . emit ( 'error' , new ErrnoException ( err , 'setRawMode' ) ) ;
61+ return this ;
62+ }
63+ this . isRaw = flag ;
64+ return this ;
65+ } ;
66+
67+ function WriteStream ( fd ) {
68+ if ( ! ( this instanceof WriteStream ) )
69+ return new WriteStream ( fd ) ;
70+ if ( fd >> 0 !== fd || fd < 0 )
71+ throw new ERR_INVALID_FD ( fd ) ;
72+
73+ const ctx = { } ;
74+ const tty = new TTY ( fd , ctx ) ;
75+ if ( ctx . code !== undefined ) {
76+ throw new ERR_TTY_INIT_FAILED ( ctx ) ;
77+ }
78+
79+ net . Socket . call ( this , {
80+ readableHighWaterMark : 0 ,
81+ handle : tty ,
82+ manualStart : true ,
83+ } ) ;
84+
85+ // Prevents interleaved or dropped stdout/stderr output for terminals.
86+ // As noted in the following reference, local TTYs tend to be quite fast and
87+ // this behavior has become expected due historical functionality on OS X,
88+ // even though it was originally intended to change in v1.0.2 (Libuv 1.2.1).
89+ // Ref: https://github.com/nodejs/node/pull/1771#issuecomment-119351671
90+ this . _handle . setBlocking ( true ) ;
91+
92+ const winSize = [ 0 , 0 ] ;
93+ const err = this . _handle . getWindowSize ( winSize ) ;
94+ if ( ! err ) {
95+ this . columns = winSize [ 0 ] ;
96+ this . rows = winSize [ 1 ] ;
97+ }
98+ }
99+
100+ ObjectSetPrototypeOf ( WriteStream . prototype , net . Socket . prototype ) ;
101+ ObjectSetPrototypeOf ( WriteStream , net . Socket ) ;
102+
103+ WriteStream . prototype . isTTY = true ;
104+
105+ WriteStream . prototype . getColorDepth = getColorDepth ;
106+
107+ WriteStream . prototype . hasColors = hasColors ;
108+
109+ WriteStream . prototype . _refreshSize = function ( ) {
110+ const oldCols = this . columns ;
111+ const oldRows = this . rows ;
112+ const winSize = [ 0 , 0 ] ;
113+ const err = this . _handle . getWindowSize ( winSize ) ;
114+ if ( err ) {
115+ this . emit ( 'error' , new ErrnoException ( err , 'getWindowSize' ) ) ;
116+ return ;
117+ }
118+ const { 0 : newCols , 1 : newRows } = winSize ;
119+ if ( oldCols !== newCols || oldRows !== newRows ) {
120+ this . columns = newCols ;
121+ this . rows = newRows ;
122+ this . emit ( 'resize' ) ;
123+ }
124+ } ;
125+
126+ // Backwards-compat
127+ WriteStream . prototype . cursorTo = function ( x , y , callback ) {
128+ if ( readline === undefined ) readline = require ( 'readline' ) ;
129+ return readline . cursorTo ( this , x , y , callback ) ;
130+ } ;
131+ WriteStream . prototype . moveCursor = function ( dx , dy , callback ) {
132+ if ( readline === undefined ) readline = require ( 'readline' ) ;
133+ return readline . moveCursor ( this , dx , dy , callback ) ;
134+ } ;
135+ WriteStream . prototype . clearLine = function ( dir , callback ) {
136+ if ( readline === undefined ) readline = require ( 'readline' ) ;
137+ return readline . clearLine ( this , dir , callback ) ;
138+ } ;
139+ WriteStream . prototype . clearScreenDown = function ( callback ) {
140+ if ( readline === undefined ) readline = require ( 'readline' ) ;
141+ return readline . clearScreenDown ( this , callback ) ;
142+ } ;
143+ WriteStream . prototype . getWindowSize = function ( ) {
144+ return [ this . columns , this . rows ] ;
145+ } ;
146+
147+ module . exports = { isatty, ReadStream, WriteStream } ;
0 commit comments