@@ -9,10 +9,12 @@ import type {
99 EvaluationListener ,
1010 OnLoadResult ,
1111 ShellCliOptions ,
12+ TypeSignature ,
1213} from '@mongosh/shell-api' ;
1314import {
1415 ShellInstanceState ,
1516 getShellApiType ,
17+ signatures ,
1618 toShellResult ,
1719} from '@mongosh/shell-api' ;
1820import type { ShellResult } from '@mongosh/shell-evaluator' ;
@@ -47,6 +49,7 @@ import { markTime } from './startup-timing';
4749import type { Context } from 'vm' ;
4850import { Script , createContext , runInContext } from 'vm' ;
4951import { installPasteSupport } from './repl-paste-support' ;
52+ import util from 'util' ;
5053
5154declare const __non_webpack_require__ : any ;
5255
@@ -365,6 +368,8 @@ class MongoshNodeRepl implements EvaluationListener {
365368 await this . finishInitializingNodeRepl ( ) ;
366369 instanceState . setCtx ( context ) ;
367370
371+ this . setupHistoryCommand ( ) ;
372+
368373 if ( ! this . shellCliOptions . nodb && ! this . shellCliOptions . quiet ) {
369374 // cf. legacy shell:
370375 // https://github.com/mongodb/mongo/blob/a6df396047a77b90bf1ce9463eecffbee16fb864/src/mongo/shell/mongo_main.cpp#L1003-L1026
@@ -391,6 +396,44 @@ class MongoshNodeRepl implements EvaluationListener {
391396 return { __initialized : 'yes' } ;
392397 }
393398
399+ setupHistoryCommand ( ) : void {
400+ const getHistory = ( ) => {
401+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
402+ const replHistory : string [ ] = ( this . runtimeState ( ) . repl as any ) . history ;
403+ const formattedHistory =
404+ // Remove the history call from the formatted history
405+ replHistory . slice ( 1 , replHistory . length ) . reverse ( ) ;
406+
407+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
408+ formattedHistory [ util . inspect . custom as any ] = ( ( ) => {
409+ return formatOutput (
410+ {
411+ // The value of the format has to be a copy of the history to avoid circular references.
412+ value : formattedHistory . concat ( ) ,
413+ } ,
414+ { colors : true , maxArrayLength : Infinity }
415+ ) ;
416+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
417+ } ) as any ;
418+ return formattedHistory ;
419+ } ;
420+
421+ getHistory . isDirectShellCommand = true ;
422+ getHistory . returnsPromise = false ;
423+ getHistory . acceptsRawInput = true ;
424+
425+ this . runtimeState ( ) . context . history =
426+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
427+ ( this . runtimeState ( ) . instanceState . shellApi as any ) . history = getHistory ;
428+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
429+ ( signatures . ShellApi . attributes as any ) . history = {
430+ type : 'function' ,
431+ returnsPromise : true ,
432+ isDirectShellCommand : true ,
433+ acceptsRawInput : true ,
434+ } as TypeSignature ;
435+ }
436+
394437 private async finishInitializingNodeRepl ( ) : Promise < void > {
395438 const { repl, instanceState } = this . runtimeState ( ) ;
396439 if ( ! repl ) return ;
0 commit comments