1declare module "repl" {
2    import { Interface, Completer, AsyncCompleter } from "readline";
3    import { Context } from "vm";
4    import { InspectOptions } from "util";
5
6    interface ReplOptions {
7        /**
8         * The input prompt to display.
9         * Default: `"> "`
10         */
11        prompt?: string;
12        /**
13         * The `Readable` stream from which REPL input will be read.
14         * Default: `process.stdin`
15         */
16        input?: NodeJS.ReadableStream;
17        /**
18         * The `Writable` stream to which REPL output will be written.
19         * Default: `process.stdout`
20         */
21        output?: NodeJS.WritableStream;
22        /**
23         * If `true`, specifies that the output should be treated as a TTY terminal, and have
24         * ANSI/VT100 escape codes written to it.
25         * Default: checking the value of the `isTTY` property on the output stream upon
26         * instantiation.
27         */
28        terminal?: boolean;
29        /**
30         * The function to be used when evaluating each given line of input.
31         * Default: an async wrapper for the JavaScript `eval()` function. An `eval` function can
32         * error with `repl.Recoverable` to indicate the input was incomplete and prompt for
33         * additional lines.
34         *
35         * @see https://nodejs.org/dist/latest-v10.x/docs/api/repl.html#repl_default_evaluation
36         * @see https://nodejs.org/dist/latest-v10.x/docs/api/repl.html#repl_custom_evaluation_functions
37         */
38        eval?: REPLEval;
39        /**
40         * If `true`, specifies that the default `writer` function should include ANSI color
41         * styling to REPL output. If a custom `writer` function is provided then this has no
42         * effect.
43         * Default: the REPL instance's `terminal` value.
44         */
45        useColors?: boolean;
46        /**
47         * If `true`, specifies that the default evaluation function will use the JavaScript
48         * `global` as the context as opposed to creating a new separate context for the REPL
49         * instance. The node CLI REPL sets this value to `true`.
50         * Default: `false`.
51         */
52        useGlobal?: boolean;
53        /**
54         * If `true`, specifies that the default writer will not output the return value of a
55         * command if it evaluates to `undefined`.
56         * Default: `false`.
57         */
58        ignoreUndefined?: boolean;
59        /**
60         * The function to invoke to format the output of each command before writing to `output`.
61         * Default: a wrapper for `util.inspect`.
62         *
63         * @see https://nodejs.org/dist/latest-v10.x/docs/api/repl.html#repl_customizing_repl_output
64         */
65        writer?: REPLWriter;
66        /**
67         * An optional function used for custom Tab auto completion.
68         *
69         * @see https://nodejs.org/dist/latest-v11.x/docs/api/readline.html#readline_use_of_the_completer_function
70         */
71        completer?: Completer | AsyncCompleter;
72        /**
73         * A flag that specifies whether the default evaluator executes all JavaScript commands in
74         * strict mode or default (sloppy) mode.
75         * Accepted values are:
76         * - `repl.REPL_MODE_SLOPPY` - evaluates expressions in sloppy mode.
77         * - `repl.REPL_MODE_STRICT` - evaluates expressions in strict mode. This is equivalent to
78         *   prefacing every repl statement with `'use strict'`.
79         */
80        replMode?: typeof REPL_MODE_SLOPPY | typeof REPL_MODE_STRICT;
81        /**
82         * Stop evaluating the current piece of code when `SIGINT` is received, i.e. `Ctrl+C` is
83         * pressed. This cannot be used together with a custom `eval` function.
84         * Default: `false`.
85         */
86        breakEvalOnSigint?: boolean;
87    }
88
89    type REPLEval = (this: REPLServer, evalCmd: string, context: Context, file: string, cb: (err: Error | null, result: any) => void) => void;
90    type REPLWriter = (this: REPLServer, obj: any) => string;
91
92    /**
93     * This is the default "writer" value, if none is passed in the REPL options,
94     * and it can be overridden by custom print functions.
95     */
96    const writer: REPLWriter & { options: InspectOptions };
97
98    type REPLCommandAction = (this: REPLServer, text: string) => void;
99
100    interface REPLCommand {
101        /**
102         * Help text to be displayed when `.help` is entered.
103         */
104        help?: string;
105        /**
106         * The function to execute, optionally accepting a single string argument.
107         */
108        action: REPLCommandAction;
109    }
110
111    /**
112     * Provides a customizable Read-Eval-Print-Loop (REPL).
113     *
114     * Instances of `repl.REPLServer` will accept individual lines of user input, evaluate those
115     * according to a user-defined evaluation function, then output the result. Input and output
116     * may be from `stdin` and `stdout`, respectively, or may be connected to any Node.js `stream`.
117     *
118     * Instances of `repl.REPLServer` support automatic completion of inputs, simplistic Emacs-style
119     * line editing, multi-line inputs, ANSI-styled output, saving and restoring current REPL session
120     * state, error recovery, and customizable evaluation functions.
121     *
122     * Instances of `repl.REPLServer` are created using the `repl.start()` method and _should not_
123     * be created directly using the JavaScript `new` keyword.
124     *
125     * @see https://nodejs.org/dist/latest-v10.x/docs/api/repl.html#repl_repl
126     */
127    class REPLServer extends Interface {
128        /**
129         * The `vm.Context` provided to the `eval` function to be used for JavaScript
130         * evaluation.
131         */
132        readonly context: Context;
133        /**
134         * The `Readable` stream from which REPL input will be read.
135         */
136        readonly inputStream: NodeJS.ReadableStream;
137        /**
138         * The `Writable` stream to which REPL output will be written.
139         */
140        readonly outputStream: NodeJS.WritableStream;
141        /**
142         * The commands registered via `replServer.defineCommand()`.
143         */
144        readonly commands: { readonly [name: string]: REPLCommand | undefined };
145        /**
146         * A value indicating whether the REPL is currently in "editor mode".
147         *
148         * @see https://nodejs.org/dist/latest-v10.x/docs/api/repl.html#repl_commands_and_special_keys
149         */
150        readonly editorMode: boolean;
151        /**
152         * A value indicating whether the `_` variable has been assigned.
153         *
154         * @see https://nodejs.org/dist/latest-v10.x/docs/api/repl.html#repl_assignment_of_the_underscore_variable
155         */
156        readonly underscoreAssigned: boolean;
157        /**
158         * The last evaluation result from the REPL (assigned to the `_` variable inside of the REPL).
159         *
160         * @see https://nodejs.org/dist/latest-v10.x/docs/api/repl.html#repl_assignment_of_the_underscore_variable
161         */
162        readonly last: any;
163        /**
164         * A value indicating whether the `_error` variable has been assigned.
165         *
166         * @since v9.8.0
167         * @see https://nodejs.org/dist/latest-v10.x/docs/api/repl.html#repl_assignment_of_the_underscore_variable
168         */
169        readonly underscoreErrAssigned: boolean;
170        /**
171         * The last error raised inside the REPL (assigned to the `_error` variable inside of the REPL).
172         *
173         * @since v9.8.0
174         * @see https://nodejs.org/dist/latest-v10.x/docs/api/repl.html#repl_assignment_of_the_underscore_variable
175         */
176        readonly lastError: any;
177        /**
178         * Specified in the REPL options, this is the function to be used when evaluating each
179         * given line of input. If not specified in the REPL options, this is an async wrapper
180         * for the JavaScript `eval()` function.
181         */
182        readonly eval: REPLEval;
183        /**
184         * Specified in the REPL options, this is a value indicating whether the default
185         * `writer` function should include ANSI color styling to REPL output.
186         */
187        readonly useColors: boolean;
188        /**
189         * Specified in the REPL options, this is a value indicating whether the default `eval`
190         * function will use the JavaScript `global` as the context as opposed to creating a new
191         * separate context for the REPL instance.
192         */
193        readonly useGlobal: boolean;
194        /**
195         * Specified in the REPL options, this is a value indicating whether the default `writer`
196         * function should output the result of a command if it evaluates to `undefined`.
197         */
198        readonly ignoreUndefined: boolean;
199        /**
200         * Specified in the REPL options, this is the function to invoke to format the output of
201         * each command before writing to `outputStream`. If not specified in the REPL options,
202         * this will be a wrapper for `util.inspect`.
203         */
204        readonly writer: REPLWriter;
205        /**
206         * Specified in the REPL options, this is the function to use for custom Tab auto-completion.
207         */
208        readonly completer: Completer | AsyncCompleter;
209        /**
210         * Specified in the REPL options, this is a flag that specifies whether the default `eval`
211         * function should execute all JavaScript commands in strict mode or default (sloppy) mode.
212         * Possible values are:
213         * - `repl.REPL_MODE_SLOPPY` - evaluates expressions in sloppy mode.
214         * - `repl.REPL_MODE_STRICT` - evaluates expressions in strict mode. This is equivalent to
215         *    prefacing every repl statement with `'use strict'`.
216         */
217        readonly replMode: typeof REPL_MODE_SLOPPY | typeof REPL_MODE_STRICT;
218
219        /**
220         * NOTE: According to the documentation:
221         *
222         * > Instances of `repl.REPLServer` are created using the `repl.start()` method and
223         * > _should not_ be created directly using the JavaScript `new` keyword.
224         *
225         * `REPLServer` cannot be subclassed due to implementation specifics in NodeJS.
226         *
227         * @see https://nodejs.org/dist/latest-v10.x/docs/api/repl.html#repl_class_replserver
228         */
229        private constructor();
230
231        /**
232         * Used to add new `.`-prefixed commands to the REPL instance. Such commands are invoked
233         * by typing a `.` followed by the `keyword`.
234         *
235         * @param keyword The command keyword (_without_ a leading `.` character).
236         * @param cmd The function to invoke when the command is processed.
237         *
238         * @see https://nodejs.org/dist/latest-v10.x/docs/api/repl.html#repl_replserver_definecommand_keyword_cmd
239         */
240        defineCommand(keyword: string, cmd: REPLCommandAction | REPLCommand): void;
241        /**
242         * Readies the REPL instance for input from the user, printing the configured `prompt` to a
243         * new line in the `output` and resuming the `input` to accept new input.
244         *
245         * When multi-line input is being entered, an ellipsis is printed rather than the 'prompt'.
246         *
247         * This method is primarily intended to be called from within the action function for
248         * commands registered using the `replServer.defineCommand()` method.
249         *
250         * @param preserveCursor When `true`, the cursor placement will not be reset to `0`.
251         */
252        displayPrompt(preserveCursor?: boolean): void;
253        /**
254         * Clears any command that has been buffered but not yet executed.
255         *
256         * This method is primarily intended to be called from within the action function for
257         * commands registered using the `replServer.defineCommand()` method.
258         *
259         * @since v9.0.0
260         */
261        clearBufferedCommand(): void;
262
263        /**
264         * Initializes a history log file for the REPL instance. When executing the
265         * Node.js binary and using the command line REPL, a history file is initialized
266         * by default. However, this is not the case when creating a REPL
267         * programmatically. Use this method to initialize a history log file when working
268         * with REPL instances programmatically.
269         * @param path The path to the history file
270         */
271        setupHistory(path: string, cb: (err: Error | null, repl: this) => void): void;
272
273        /**
274         * events.EventEmitter
275         * 1. close - inherited from `readline.Interface`
276         * 2. line - inherited from `readline.Interface`
277         * 3. pause - inherited from `readline.Interface`
278         * 4. resume - inherited from `readline.Interface`
279         * 5. SIGCONT - inherited from `readline.Interface`
280         * 6. SIGINT - inherited from `readline.Interface`
281         * 7. SIGTSTP - inherited from `readline.Interface`
282         * 8. exit
283         * 9. reset
284         */
285
286        addListener(event: string, listener: (...args: any[]) => void): this;
287        addListener(event: "close", listener: () => void): this;
288        addListener(event: "line", listener: (input: string) => void): this;
289        addListener(event: "pause", listener: () => void): this;
290        addListener(event: "resume", listener: () => void): this;
291        addListener(event: "SIGCONT", listener: () => void): this;
292        addListener(event: "SIGINT", listener: () => void): this;
293        addListener(event: "SIGTSTP", listener: () => void): this;
294        addListener(event: "exit", listener: () => void): this;
295        addListener(event: "reset", listener: (context: Context) => void): this;
296
297        emit(event: string | symbol, ...args: any[]): boolean;
298        emit(event: "close"): boolean;
299        emit(event: "line", input: string): boolean;
300        emit(event: "pause"): boolean;
301        emit(event: "resume"): boolean;
302        emit(event: "SIGCONT"): boolean;
303        emit(event: "SIGINT"): boolean;
304        emit(event: "SIGTSTP"): boolean;
305        emit(event: "exit"): boolean;
306        emit(event: "reset", context: Context): boolean;
307
308        on(event: string, listener: (...args: any[]) => void): this;
309        on(event: "close", listener: () => void): this;
310        on(event: "line", listener: (input: string) => void): this;
311        on(event: "pause", listener: () => void): this;
312        on(event: "resume", listener: () => void): this;
313        on(event: "SIGCONT", listener: () => void): this;
314        on(event: "SIGINT", listener: () => void): this;
315        on(event: "SIGTSTP", listener: () => void): this;
316        on(event: "exit", listener: () => void): this;
317        on(event: "reset", listener: (context: Context) => void): this;
318
319        once(event: string, listener: (...args: any[]) => void): this;
320        once(event: "close", listener: () => void): this;
321        once(event: "line", listener: (input: string) => void): this;
322        once(event: "pause", listener: () => void): this;
323        once(event: "resume", listener: () => void): this;
324        once(event: "SIGCONT", listener: () => void): this;
325        once(event: "SIGINT", listener: () => void): this;
326        once(event: "SIGTSTP", listener: () => void): this;
327        once(event: "exit", listener: () => void): this;
328        once(event: "reset", listener: (context: Context) => void): this;
329
330        prependListener(event: string, listener: (...args: any[]) => void): this;
331        prependListener(event: "close", listener: () => void): this;
332        prependListener(event: "line", listener: (input: string) => void): this;
333        prependListener(event: "pause", listener: () => void): this;
334        prependListener(event: "resume", listener: () => void): this;
335        prependListener(event: "SIGCONT", listener: () => void): this;
336        prependListener(event: "SIGINT", listener: () => void): this;
337        prependListener(event: "SIGTSTP", listener: () => void): this;
338        prependListener(event: "exit", listener: () => void): this;
339        prependListener(event: "reset", listener: (context: Context) => void): this;
340
341        prependOnceListener(event: string, listener: (...args: any[]) => void): this;
342        prependOnceListener(event: "close", listener: () => void): this;
343        prependOnceListener(event: "line", listener: (input: string) => void): this;
344        prependOnceListener(event: "pause", listener: () => void): this;
345        prependOnceListener(event: "resume", listener: () => void): this;
346        prependOnceListener(event: "SIGCONT", listener: () => void): this;
347        prependOnceListener(event: "SIGINT", listener: () => void): this;
348        prependOnceListener(event: "SIGTSTP", listener: () => void): this;
349        prependOnceListener(event: "exit", listener: () => void): this;
350        prependOnceListener(event: "reset", listener: (context: Context) => void): this;
351    }
352
353    /**
354     * A flag passed in the REPL options. Evaluates expressions in sloppy mode.
355     */
356    const REPL_MODE_SLOPPY: symbol; // TODO: unique symbol
357
358    /**
359     * A flag passed in the REPL options. Evaluates expressions in strict mode.
360     * This is equivalent to prefacing every repl statement with `'use strict'`.
361     */
362    const REPL_MODE_STRICT: symbol; // TODO: unique symbol
363
364    /**
365     * Creates and starts a `repl.REPLServer` instance.
366     *
367     * @param options The options for the `REPLServer`. If `options` is a string, then it specifies
368     * the input prompt.
369     */
370    function start(options?: string | ReplOptions): REPLServer;
371
372    /**
373     * Indicates a recoverable error that a `REPLServer` can use to support multi-line input.
374     *
375     * @see https://nodejs.org/dist/latest-v10.x/docs/api/repl.html#repl_recoverable_errors
376     */
377    class Recoverable extends SyntaxError {
378        err: Error;
379
380        constructor(err: Error);
381    }
382}
383