readline.d.ts (25714B)
1 /** 2 * The `readline` module provides an interface for reading data from a `Readable` stream (such as `process.stdin`) one line at a time. It can be accessed 3 * using: 4 * 5 * ```js 6 * import readline from 'node:readline'; 7 * ``` 8 * 9 * The following simple example illustrates the basic use of the `readline` module. 10 * 11 * ```js 12 * import readline from 'node:readline'; 13 * 14 * const rl = readline.createInterface({ 15 * input: process.stdin, 16 * output: process.stdout 17 * }); 18 * 19 * rl.question('What do you think of Node.js? ', (answer) => { 20 * // TODO: Log the answer in a database 21 * console.log(`Thank you for your valuable feedback: ${answer}`); 22 * 23 * rl.close(); 24 * }); 25 * ``` 26 * 27 * Once this code is invoked, the Node.js application will not terminate until the`readline.Interface` is closed because the interface waits for data to be 28 * received on the `input` stream. 29 * @see [source](https://github.com/nodejs/node/blob/v16.9.0/lib/readline.js) 30 */ 31 declare module "readline" { 32 import { Abortable, EventEmitter } from "node:events"; 33 interface Key { 34 sequence?: string | undefined; 35 name?: string | undefined; 36 ctrl?: boolean | undefined; 37 meta?: boolean | undefined; 38 shift?: boolean | undefined; 39 } 40 /** 41 * Instances of the `readline.Interface` class are constructed using the`readline.createInterface()` method. Every instance is associated with a 42 * single `input` `Readable` stream and a single `output` `Writable` stream. 43 * The `output` stream is used to print prompts for user input that arrives on, 44 * and is read from, the `input` stream. 45 * @since v0.1.104 46 */ 47 class Interface extends EventEmitter { 48 readonly terminal: boolean; 49 /** 50 * The current input data being processed by node. 51 * 52 * This can be used when collecting input from a TTY stream to retrieve the 53 * current value that has been processed thus far, prior to the `line` event 54 * being emitted. Once the `line` event has been emitted, this property will 55 * be an empty string. 56 * 57 * Be aware that modifying the value during the instance runtime may have 58 * unintended consequences if `rl.cursor` is not also controlled. 59 * 60 * **If not using a TTY stream for input, use the `'line'` event.** 61 * 62 * One possible use case would be as follows: 63 * 64 * ```js 65 * const values = ['lorem ipsum', 'dolor sit amet']; 66 * const rl = readline.createInterface(process.stdin); 67 * const showResults = debounce(() => { 68 * console.log( 69 * '\n', 70 * values.filter((val) => val.startsWith(rl.line)).join(' ') 71 * ); 72 * }, 300); 73 * process.stdin.on('keypress', (c, k) => { 74 * showResults(); 75 * }); 76 * ``` 77 * @since v0.1.98 78 */ 79 readonly line: string; 80 /** 81 * The cursor position relative to `rl.line`. 82 * 83 * This will track where the current cursor lands in the input string, when 84 * reading input from a TTY stream. The position of cursor determines the 85 * portion of the input string that will be modified as input is processed, 86 * as well as the column where the terminal caret will be rendered. 87 * @since v0.1.98 88 */ 89 readonly cursor: number; 90 /** 91 * NOTE: According to the documentation: 92 * 93 * > Instances of the `readline.Interface` class are constructed using the 94 * > `readline.createInterface()` method. 95 * 96 * @see https://nodejs.org/dist/latest-v16.x/docs/api/readline.html#readline_class_interface 97 */ 98 protected constructor( 99 input: NodeJS.ReadableStream, 100 output?: NodeJS.WritableStream, 101 completer?: Completer | AsyncCompleter, 102 terminal?: boolean, 103 ); 104 /** 105 * NOTE: According to the documentation: 106 * 107 * > Instances of the `readline.Interface` class are constructed using the 108 * > `readline.createInterface()` method. 109 * 110 * @see https://nodejs.org/dist/latest-v16.x/docs/api/readline.html#readline_class_interface 111 */ 112 protected constructor(options: ReadLineOptions); 113 /** 114 * The `rl.getPrompt()` method returns the current prompt used by `rl.prompt()`. 115 * @since v15.3.0 116 * @return the current prompt string 117 */ 118 getPrompt(): string; 119 /** 120 * The `rl.setPrompt()` method sets the prompt that will be written to `output`whenever `rl.prompt()` is called. 121 * @since v0.1.98 122 */ 123 setPrompt(prompt: string): void; 124 /** 125 * The `rl.prompt()` method writes the `readline.Interface` instances configured`prompt` to a new line in `output` in order to provide a user with a new 126 * location at which to provide input. 127 * 128 * When called, `rl.prompt()` will resume the `input` stream if it has been 129 * paused. 130 * 131 * If the `readline.Interface` was created with `output` set to `null` or`undefined` the prompt is not written. 132 * @since v0.1.98 133 * @param preserveCursor If `true`, prevents the cursor placement from being reset to `0`. 134 */ 135 prompt(preserveCursor?: boolean): void; 136 /** 137 * The `rl.question()` method displays the `query` by writing it to the `output`, 138 * waits for user input to be provided on `input`, then invokes the `callback`function passing the provided input as the first argument. 139 * 140 * When called, `rl.question()` will resume the `input` stream if it has been 141 * paused. 142 * 143 * If the `readline.Interface` was created with `output` set to `null` or`undefined` the `query` is not written. 144 * 145 * The `callback` function passed to `rl.question()` does not follow the typical 146 * pattern of accepting an `Error` object or `null` as the first argument. 147 * The `callback` is called with the provided answer as the only argument. 148 * 149 * Example usage: 150 * 151 * ```js 152 * rl.question('What is your favorite food? ', (answer) => { 153 * console.log(`Oh, so your favorite food is ${answer}`); 154 * }); 155 * ``` 156 * 157 * Using an `AbortController` to cancel a question. 158 * 159 * ```js 160 * const ac = new AbortController(); 161 * const signal = ac.signal; 162 * 163 * rl.question('What is your favorite food? ', { signal }, (answer) => { 164 * console.log(`Oh, so your favorite food is ${answer}`); 165 * }); 166 * 167 * signal.addEventListener('abort', () => { 168 * console.log('The food question timed out'); 169 * }, { once: true }); 170 * 171 * setTimeout(() => ac.abort(), 10000); 172 * ``` 173 * 174 * If this method is invoked as it's util.promisify()ed version, it returns a 175 * Promise that fulfills with the answer. If the question is canceled using 176 * an `AbortController` it will reject with an `AbortError`. 177 * 178 * ```js 179 * import util from 'node:util'; 180 * const question = util.promisify(rl.question).bind(rl); 181 * 182 * async function questionExample() { 183 * try { 184 * const answer = await question('What is you favorite food? '); 185 * console.log(`Oh, so your favorite food is ${answer}`); 186 * } catch (err) { 187 * console.error('Question rejected', err); 188 * } 189 * } 190 * questionExample(); 191 * ``` 192 * @since v0.3.3 193 * @param query A statement or query to write to `output`, prepended to the prompt. 194 * @param callback A callback function that is invoked with the user's input in response to the `query`. 195 */ 196 question(query: string, callback: (answer: string) => void): void; 197 question(query: string, options: Abortable, callback: (answer: string) => void): void; 198 /** 199 * The `rl.pause()` method pauses the `input` stream, allowing it to be resumed 200 * later if necessary. 201 * 202 * Calling `rl.pause()` does not immediately pause other events (including`'line'`) from being emitted by the `readline.Interface` instance. 203 * @since v0.3.4 204 */ 205 pause(): this; 206 /** 207 * The `rl.resume()` method resumes the `input` stream if it has been paused. 208 * @since v0.3.4 209 */ 210 resume(): this; 211 /** 212 * The `rl.close()` method closes the `readline.Interface` instance and 213 * relinquishes control over the `input` and `output` streams. When called, 214 * the `'close'` event will be emitted. 215 * 216 * Calling `rl.close()` does not immediately stop other events (including `'line'`) 217 * from being emitted by the `readline.Interface` instance. 218 * @since v0.1.98 219 */ 220 close(): void; 221 /** 222 * The `rl.write()` method will write either `data` or a key sequence identified 223 * by `key` to the `output`. The `key` argument is supported only if `output` is 224 * a `TTY` text terminal. See `TTY keybindings` for a list of key 225 * combinations. 226 * 227 * If `key` is specified, `data` is ignored. 228 * 229 * When called, `rl.write()` will resume the `input` stream if it has been 230 * paused. 231 * 232 * If the `readline.Interface` was created with `output` set to `null` or`undefined` the `data` and `key` are not written. 233 * 234 * ```js 235 * rl.write('Delete this!'); 236 * // Simulate Ctrl+U to delete the line written previously 237 * rl.write(null, { ctrl: true, name: 'u' }); 238 * ``` 239 * 240 * The `rl.write()` method will write the data to the `readline` `Interface`'s`input`_as if it were provided by the user_. 241 * @since v0.1.98 242 */ 243 write(data: string | Buffer, key?: Key): void; 244 write(data: undefined | null | string | Buffer, key: Key): void; 245 /** 246 * Returns the real position of the cursor in relation to the input 247 * prompt + string. Long input (wrapping) strings, as well as multiple 248 * line prompts are included in the calculations. 249 * @since v13.5.0, v12.16.0 250 */ 251 getCursorPos(): CursorPos; 252 /** 253 * events.EventEmitter 254 * 1. close 255 * 2. line 256 * 3. pause 257 * 4. resume 258 * 5. SIGCONT 259 * 6. SIGINT 260 * 7. SIGTSTP 261 * 8. history 262 */ 263 addListener(event: string, listener: (...args: any[]) => void): this; 264 addListener(event: "close", listener: () => void): this; 265 addListener(event: "line", listener: (input: string) => void): this; 266 addListener(event: "pause", listener: () => void): this; 267 addListener(event: "resume", listener: () => void): this; 268 addListener(event: "SIGCONT", listener: () => void): this; 269 addListener(event: "SIGINT", listener: () => void): this; 270 addListener(event: "SIGTSTP", listener: () => void): this; 271 addListener(event: "history", listener: (history: string[]) => void): this; 272 emit(event: string | symbol, ...args: any[]): boolean; 273 emit(event: "close"): boolean; 274 emit(event: "line", input: string): boolean; 275 emit(event: "pause"): boolean; 276 emit(event: "resume"): boolean; 277 emit(event: "SIGCONT"): boolean; 278 emit(event: "SIGINT"): boolean; 279 emit(event: "SIGTSTP"): boolean; 280 emit(event: "history", history: string[]): boolean; 281 on(event: string, listener: (...args: any[]) => void): this; 282 on(event: "close", listener: () => void): this; 283 on(event: "line", listener: (input: string) => void): this; 284 on(event: "pause", listener: () => void): this; 285 on(event: "resume", listener: () => void): this; 286 on(event: "SIGCONT", listener: () => void): this; 287 on(event: "SIGINT", listener: () => void): this; 288 on(event: "SIGTSTP", listener: () => void): this; 289 on(event: "history", listener: (history: string[]) => void): this; 290 once(event: string, listener: (...args: any[]) => void): this; 291 once(event: "close", listener: () => void): this; 292 once(event: "line", listener: (input: string) => void): this; 293 once(event: "pause", listener: () => void): this; 294 once(event: "resume", listener: () => void): this; 295 once(event: "SIGCONT", listener: () => void): this; 296 once(event: "SIGINT", listener: () => void): this; 297 once(event: "SIGTSTP", listener: () => void): this; 298 once(event: "history", listener: (history: string[]) => void): this; 299 prependListener(event: string, listener: (...args: any[]) => void): this; 300 prependListener(event: "close", listener: () => void): this; 301 prependListener(event: "line", listener: (input: string) => void): this; 302 prependListener(event: "pause", listener: () => void): this; 303 prependListener(event: "resume", listener: () => void): this; 304 prependListener(event: "SIGCONT", listener: () => void): this; 305 prependListener(event: "SIGINT", listener: () => void): this; 306 prependListener(event: "SIGTSTP", listener: () => void): this; 307 prependListener(event: "history", listener: (history: string[]) => void): this; 308 prependOnceListener(event: string, listener: (...args: any[]) => void): this; 309 prependOnceListener(event: "close", listener: () => void): this; 310 prependOnceListener(event: "line", listener: (input: string) => void): this; 311 prependOnceListener(event: "pause", listener: () => void): this; 312 prependOnceListener(event: "resume", listener: () => void): this; 313 prependOnceListener(event: "SIGCONT", listener: () => void): this; 314 prependOnceListener(event: "SIGINT", listener: () => void): this; 315 prependOnceListener(event: "SIGTSTP", listener: () => void): this; 316 prependOnceListener(event: "history", listener: (history: string[]) => void): this; 317 [Symbol.asyncIterator](): NodeJS.AsyncIterator<string>; 318 } 319 type ReadLine = Interface; // type forwarded for backwards compatibility 320 type Completer = (line: string) => CompleterResult; 321 type AsyncCompleter = (line: string, callback: (err?: null | Error, result?: CompleterResult) => void) => void; 322 type CompleterResult = [string[], string]; 323 interface ReadLineOptions { 324 /** 325 * The [`Readable`](https://nodejs.org/docs/latest-v16.x/api/stream.html#readable-streams) stream to listen to 326 */ 327 input: NodeJS.ReadableStream; 328 /** 329 * The [`Writable`](https://nodejs.org/docs/latest-v16.x/api/stream.html#writable-streams) stream to write readline data to. 330 */ 331 output?: NodeJS.WritableStream | undefined; 332 /** 333 * An optional function used for Tab autocompletion. 334 */ 335 completer?: Completer | AsyncCompleter | undefined; 336 /** 337 * `true` if the `input` and `output` streams should be treated like a TTY, 338 * and have ANSI/VT100 escape codes written to it. 339 * Default: checking `isTTY` on the `output` stream upon instantiation. 340 */ 341 terminal?: boolean | undefined; 342 /** 343 * Initial list of history lines. 344 * This option makes sense only if `terminal` is set to `true` by the user or by an internal `output` check, 345 * otherwise the history caching mechanism is not initialized at all. 346 * @default [] 347 */ 348 history?: string[] | undefined; 349 /** 350 * Maximum number of history lines retained. 351 * To disable the history set this value to `0`. 352 * This option makes sense only if `terminal` is set to `true` by the user or by an internal `output` check, 353 * otherwise the history caching mechanism is not initialized at all. 354 * @default 30 355 */ 356 historySize?: number | undefined; 357 /** 358 * If `true`, when a new input line added to the history list duplicates an older one, 359 * this removes the older line from the list. 360 * @default false 361 */ 362 removeHistoryDuplicates?: boolean | undefined; 363 /** 364 * The prompt string to use. 365 * @default "> " 366 */ 367 prompt?: string | undefined; 368 /** 369 * If the delay between `\r` and `\n` exceeds `crlfDelay` milliseconds, 370 * both `\r` and `\n` will be treated as separate end-of-line input. 371 * `crlfDelay` will be coerced to a number no less than `100`. 372 * It can be set to `Infinity`, in which case 373 * `\r` followed by `\n` will always be considered a single newline 374 * (which may be reasonable for [reading files](https://nodejs.org/docs/latest-v16.x/api/readline.html#example-read-file-stream-line-by-line) with `\r\n` line delimiter). 375 * @default 100 376 */ 377 crlfDelay?: number | undefined; 378 /** 379 * The duration `readline` will wait for a character 380 * (when reading an ambiguous key sequence in milliseconds 381 * one that can both form a complete key sequence using the input read so far 382 * and can take additional input to complete a longer key sequence). 383 * @default 500 384 */ 385 escapeCodeTimeout?: number | undefined; 386 /** 387 * The number of spaces a tab is equal to (minimum 1). 388 * @default 8 389 */ 390 tabSize?: number | undefined; 391 /** 392 * Allows closing the interface using an AbortSignal. 393 * Aborting the signal will internally call `close` on the interface. 394 */ 395 signal?: AbortSignal | undefined; 396 } 397 /** 398 * The `readline.createInterface()` method creates a new `readline.Interface` instance. 399 * 400 * ```js 401 * import readline from 'node:readline'; 402 * const rl = readline.createInterface({ 403 * input: process.stdin, 404 * output: process.stdout 405 * }); 406 * ``` 407 * 408 * Once the `readline.Interface` instance is created, the most common case is to 409 * listen for the `'line'` event: 410 * 411 * ```js 412 * rl.on('line', (line) => { 413 * console.log(`Received: ${line}`); 414 * }); 415 * ``` 416 * 417 * If `terminal` is `true` for this instance then the `output` stream will get 418 * the best compatibility if it defines an `output.columns` property and emits 419 * a `'resize'` event on the `output` if or when the columns ever change 420 * (`process.stdout` does this automatically when it is a TTY). 421 * 422 * When creating a `readline.Interface` using `stdin` as input, the program 423 * will not terminate until it receives `EOF` (Ctrl+D on 424 * Linux/macOS, Ctrl+Z followed by Return on 425 * Windows). 426 * If you want your application to exit without waiting for user input, you can `unref()` the standard input stream: 427 * 428 * ```js 429 * process.stdin.unref(); 430 * ``` 431 * @since v0.1.98 432 */ 433 function createInterface( 434 input: NodeJS.ReadableStream, 435 output?: NodeJS.WritableStream, 436 completer?: Completer | AsyncCompleter, 437 terminal?: boolean, 438 ): Interface; 439 function createInterface(options: ReadLineOptions): Interface; 440 /** 441 * The `readline.emitKeypressEvents()` method causes the given `Readable` stream to begin emitting `'keypress'` events corresponding to received input. 442 * 443 * Optionally, `interface` specifies a `readline.Interface` instance for which 444 * autocompletion is disabled when copy-pasted input is detected. 445 * 446 * If the `stream` is a `TTY`, then it must be in raw mode. 447 * 448 * This is automatically called by any readline instance on its `input` if the`input` is a terminal. Closing the `readline` instance does not stop 449 * the `input` from emitting `'keypress'` events. 450 * 451 * ```js 452 * readline.emitKeypressEvents(process.stdin); 453 * if (process.stdin.isTTY) 454 * process.stdin.setRawMode(true); 455 * ``` 456 * @since v0.7.7 457 */ 458 function emitKeypressEvents(stream: NodeJS.ReadableStream, readlineInterface?: Interface): void; 459 type Direction = -1 | 0 | 1; 460 interface CursorPos { 461 rows: number; 462 cols: number; 463 } 464 /** 465 * The `readline.clearLine()` method clears current line of given `TTY` stream 466 * in a specified direction identified by `dir`. 467 * @since v0.7.7 468 * @param callback Invoked once the operation completes. 469 * @return `false` if `stream` wishes for the calling code to wait for the `'drain'` event to be emitted before continuing to write additional data; otherwise `true`. 470 */ 471 function clearLine(stream: NodeJS.WritableStream, dir: Direction, callback?: () => void): boolean; 472 /** 473 * The `readline.clearScreenDown()` method clears the given `TTY` stream from 474 * the current position of the cursor down. 475 * @since v0.7.7 476 * @param callback Invoked once the operation completes. 477 * @return `false` if `stream` wishes for the calling code to wait for the `'drain'` event to be emitted before continuing to write additional data; otherwise `true`. 478 */ 479 function clearScreenDown(stream: NodeJS.WritableStream, callback?: () => void): boolean; 480 /** 481 * The `readline.cursorTo()` method moves cursor to the specified position in a 482 * given `TTY` `stream`. 483 * @since v0.7.7 484 * @param callback Invoked once the operation completes. 485 * @return `false` if `stream` wishes for the calling code to wait for the `'drain'` event to be emitted before continuing to write additional data; otherwise `true`. 486 */ 487 function cursorTo(stream: NodeJS.WritableStream, x: number, y?: number, callback?: () => void): boolean; 488 /** 489 * The `readline.moveCursor()` method moves the cursor _relative_ to its current 490 * position in a given `TTY` `stream`. 491 * 492 * ## Example: Tiny CLI 493 * 494 * The following example illustrates the use of `readline.Interface` class to 495 * implement a small command-line interface: 496 * 497 * ```js 498 * import readline from 'node:readline'; 499 * const rl = readline.createInterface({ 500 * input: process.stdin, 501 * output: process.stdout, 502 * prompt: 'OHAI> ' 503 * }); 504 * 505 * rl.prompt(); 506 * 507 * rl.on('line', (line) => { 508 * switch (line.trim()) { 509 * case 'hello': 510 * console.log('world!'); 511 * break; 512 * default: 513 * console.log(`Say what? I might have heard '${line.trim()}'`); 514 * break; 515 * } 516 * rl.prompt(); 517 * }).on('close', () => { 518 * console.log('Have a great day!'); 519 * process.exit(0); 520 * }); 521 * ``` 522 * 523 * ## Example: Read file stream line-by-Line 524 * 525 * A common use case for `readline` is to consume an input file one line at a 526 * time. The easiest way to do so is leveraging the `fs.ReadStream` API as 527 * well as a `for await...of` loop: 528 * 529 * ```js 530 * import fs from 'node:fs'; 531 * import readline from 'node:readline'; 532 * 533 * async function processLineByLine() { 534 * const fileStream = fs.createReadStream('input.txt'); 535 * 536 * const rl = readline.createInterface({ 537 * input: fileStream, 538 * crlfDelay: Infinity 539 * }); 540 * // Note: we use the crlfDelay option to recognize all instances of CR LF 541 * // ('\r\n') in input.txt as a single line break. 542 * 543 * for await (const line of rl) { 544 * // Each line in input.txt will be successively available here as `line`. 545 * console.log(`Line from file: ${line}`); 546 * } 547 * } 548 * 549 * processLineByLine(); 550 * ``` 551 * 552 * Alternatively, one could use the `'line'` event: 553 * 554 * ```js 555 * import fs from 'node:fs'; 556 * import readline from 'node:readline'; 557 * 558 * const rl = readline.createInterface({ 559 * input: fs.createReadStream('sample.txt'), 560 * crlfDelay: Infinity 561 * }); 562 * 563 * rl.on('line', (line) => { 564 * console.log(`Line from file: ${line}`); 565 * }); 566 * ``` 567 * 568 * Currently, `for await...of` loop can be a bit slower. If `async` / `await`flow and speed are both essential, a mixed approach can be applied: 569 * 570 * ```js 571 * import { once } from 'node:events'; 572 * import { createReadStream } from 'node:fs'; 573 * import { createInterface } from 'node:readline'; 574 * 575 * (async function processLineByLine() { 576 * try { 577 * const rl = createInterface({ 578 * input: createReadStream('big-file.txt'), 579 * crlfDelay: Infinity 580 * }); 581 * 582 * rl.on('line', (line) => { 583 * // Process the line. 584 * }); 585 * 586 * await once(rl, 'close'); 587 * 588 * console.log('File processed.'); 589 * } catch (err) { 590 * console.error(err); 591 * } 592 * })(); 593 * ``` 594 * @since v0.7.7 595 * @param callback Invoked once the operation completes. 596 * @return `false` if `stream` wishes for the calling code to wait for the `'drain'` event to be emitted before continuing to write additional data; otherwise `true`. 597 */ 598 function moveCursor(stream: NodeJS.WritableStream, dx: number, dy: number, callback?: () => void): boolean; 599 } 600 declare module "node:readline" { 601 export * from "readline"; 602 }