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