• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict';
2
3const {
4  Promise,
5  SymbolDispose,
6} = primordials;
7
8const {
9  Readline,
10} = require('internal/readline/promises');
11
12const {
13  Interface: _Interface,
14  kQuestionCancel,
15} = require('internal/readline/interface');
16
17const {
18  AbortError,
19} = require('internal/errors');
20const { validateAbortSignal } = require('internal/validators');
21
22const {
23  kEmptyObject,
24} = require('internal/util');
25let addAbortListener;
26
27class Interface extends _Interface {
28  // eslint-disable-next-line no-useless-constructor
29  constructor(input, output, completer, terminal) {
30    super(input, output, completer, terminal);
31  }
32  question(query, options = kEmptyObject) {
33    return new Promise((resolve, reject) => {
34      let cb = resolve;
35
36      if (options?.signal) {
37        validateAbortSignal(options.signal, 'options.signal');
38        if (options.signal.aborted) {
39          return reject(
40            new AbortError(undefined, { cause: options.signal.reason }));
41        }
42
43        const onAbort = () => {
44          this[kQuestionCancel]();
45          reject(new AbortError(undefined, { cause: options.signal.reason }));
46        };
47        addAbortListener ??= require('events').addAbortListener;
48        const disposable = addAbortListener(options.signal, onAbort);
49
50        cb = (answer) => {
51          disposable[SymbolDispose]();
52          resolve(answer);
53        };
54      }
55
56      super.question(query, cb);
57    });
58  }
59}
60
61function createInterface(input, output, completer, terminal) {
62  return new Interface(input, output, completer, terminal);
63}
64
65module.exports = {
66  Interface,
67  Readline,
68  createInterface,
69};
70