Skip to content

Commit 1752160

Browse files
committed
fix(cli-repl): account for Node.js 24 multi-line REPL handling update MONGOSH-2233
1 parent 1b02f97 commit 1752160

File tree

2 files changed

+43
-11
lines changed

2 files changed

+43
-11
lines changed

packages/cli-repl/src/mongosh-repl.ts

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,10 @@ import type { FormatOptions } from './format-output';
4747
import { markTime } from './startup-timing';
4848
import type { Context } from 'vm';
4949
import { Script, createContext, runInContext } from 'vm';
50-
import { installPasteSupport } from './repl-paste-support';
50+
import {
51+
addReplEventForEvalReady,
52+
installPasteSupport,
53+
} from './repl-paste-support';
5154
import util from 'util';
5255

5356
declare const __non_webpack_require__: any;
@@ -260,7 +263,7 @@ class MongoshNodeRepl implements EvaluationListener {
260263
repl = asyncRepl.start({
261264
// 'repl' is not supported in startup snapshots yet.
262265
// eslint-disable-next-line @typescript-eslint/no-var-requires
263-
start: require('pretty-repl').start,
266+
//start: require('pretty-repl').start,
264267
input: this.lineByLineInput,
265268
output: this.output,
266269
prompt: '',
@@ -521,15 +524,11 @@ class MongoshNodeRepl implements EvaluationListener {
521524
// This is used below for multiline history manipulation.
522525
let originalHistory: string[] | null = null;
523526

524-
const originalDisplayPrompt = repl.displayPrompt.bind(repl);
525-
526-
repl.displayPrompt = (...args: any[]) => {
527-
if (!this.started) {
528-
return;
529-
}
530-
originalDisplayPrompt(...args);
531-
this.lineByLineInput.nextLine();
532-
};
527+
addReplEventForEvalReady(
528+
repl,
529+
() => !!this.started,
530+
() => this.lineByLineInput.nextLine()
531+
);
533532

534533
if (repl.commands.editor) {
535534
const originalEditorAction = repl.commands.editor.action.bind(repl);

packages/cli-repl/src/repl-paste-support.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,36 @@ export function installPasteSupport(repl: REPLServer): string {
6565
});
6666
return onEnd;
6767
}
68+
69+
// Not related to paste support, but rather for integrating with the MongoshNodeRepl's
70+
// line-by-line input handling.
71+
export function addReplEventForEvalReady(
72+
repl: REPLServer,
73+
before: () => boolean,
74+
after: () => void
75+
): void {
76+
const wrapMethodWithLineByLineInputNextLine = (
77+
repl: REPLServer,
78+
key: keyof REPLServer
79+
) => {
80+
const originalMethod = repl[key].bind(repl);
81+
if (!originalMethod) return;
82+
(repl as any)[key] = (...args: any[]) => {
83+
if (!before()) {
84+
return;
85+
}
86+
const result = originalMethod(...args);
87+
after();
88+
return result;
89+
};
90+
};
91+
// https://github.com/nodejs/node/blob/88f4cef8b96b2bb9d4a92f6848ce4d63a82879a8/lib/internal/readline/interface.js#L954
92+
// added in https://github.com/nodejs/node/commit/96be7836d794509dd455e66d91c2975419feed64
93+
// handles newlines inside multi-line input and replaces `.displayPrompt()` which was
94+
// previously used to print the prompt for multi-line input.
95+
const addNewLineOnTTYKey = [...prototypeChain(repl)]
96+
.flatMap((proto) => Object.getOwnPropertySymbols(proto))
97+
.find((s) => String(s).includes('(_addNewLineOnTTY)')) as keyof REPLServer;
98+
wrapMethodWithLineByLineInputNextLine(repl, 'displayPrompt');
99+
wrapMethodWithLineByLineInputNextLine(repl, addNewLineOnTTYKey);
100+
}

0 commit comments

Comments
 (0)