@@ -909,30 +909,204 @@ to connect to both Unix and TCP sockets.
909909By starting a REPL from a Unix socket-based server instead of stdin, it is
910910possible to connect to a long-running Node.js process without restarting it.
911911
912- For an example of running a "full-featured" (` terminal ` ) REPL over
913- a ` net.Server ` and ` net.Socket ` instance, see:
914- < https://gist.github.com/TooTallNate/2209310 > .
912+ ### Examples
915913
916- For an example of running a REPL instance over [ ` curl(1) ` ] [ ] , see:
917- < https://gist.github.com/TooTallNate/2053342 > .
914+ #### Full-featured "terminal" REPL over ` net.Server ` and ` net.Socket `
918915
919- This example is intended purely for educational purposes to demonstrate how
916+ This is an example on how to run a "full-featured" (terminal) REPL using
917+ [ ` net.Server ` ] [ ] and [ ` net.Socket ` ] [ ]
918+
919+ The following script starts an HTTP server on port ` 1337 ` that allows
920+ clients to establish socket connections to its REPL instance.
921+
922+ ``` mjs
923+ // repl-server.js
924+ import repl from ' node:repl' ;
925+ import net from ' node:net' ;
926+
927+ net
928+ .createServer ((socket ) => {
929+ const r = repl .start ({
930+ prompt: ` socket ${ socket .remoteAddress } :${ socket .remotePort } > ` ,
931+ input: socket,
932+ output: socket,
933+ terminal: true ,
934+ useGlobal: false ,
935+ });
936+ r .on (' exit' , () => {
937+ socket .end ();
938+ });
939+ r .context .socket = socket;
940+ })
941+ .listen (1337 );
942+ ```
943+
944+ ``` cjs
945+ // repl-server.js
946+ const repl = require (' node:repl' );
947+ const net = require (' node:net' );
948+
949+ net
950+ .createServer ((socket ) => {
951+ const r = repl .start ({
952+ prompt: ` socket ${ socket .remoteAddress } :${ socket .remotePort } > ` ,
953+ input: socket,
954+ output: socket,
955+ terminal: true ,
956+ useGlobal: false ,
957+ });
958+ r .on (' exit' , () => {
959+ socket .end ();
960+ });
961+ r .context .socket = socket;
962+ })
963+ .listen (1337 );
964+ ```
965+
966+ While the following implements a client that can create a socket connection
967+ with the above defined server over port ` 1337 ` .
968+
969+ ``` mjs
970+ // repl-client.js
971+ import net from ' node:net' ;
972+ import process from ' node:process' ;
973+
974+ const sock = net .connect (1337 );
975+
976+ process .stdin .pipe (sock);
977+ sock .pipe (process .stdout );
978+
979+ sock .on (' connect' , () => {
980+ process .stdin .resume ();
981+ process .stdin .setRawMode (true );
982+ });
983+
984+ sock .on (' close' , () => {
985+ process .stdin .setRawMode (false );
986+ process .stdin .pause ();
987+ sock .removeListener (' close' , done);
988+ });
989+
990+ process .stdin .on (' end' , () => {
991+ sock .destroy ();
992+ console .log ();
993+ });
994+
995+ process .stdin .on (' data' , (b ) => {
996+ if (b .length === 1 && b[0 ] === 4 ) {
997+ process .stdin .emit (' end' );
998+ }
999+ });
1000+ ```
1001+
1002+ ``` cjs
1003+ // repl-client.js
1004+ const net = require (' node:net' );
1005+
1006+ const sock = net .connect (1337 );
1007+
1008+ process .stdin .pipe (sock);
1009+ sock .pipe (process .stdout );
1010+
1011+ sock .on (' connect' , () => {
1012+ process .stdin .resume ();
1013+ process .stdin .setRawMode (true );
1014+ });
1015+
1016+ sock .on (' close' , () => {
1017+ process .stdin .setRawMode (false );
1018+ process .stdin .pause ();
1019+ sock .removeListener (' close' , done);
1020+ });
1021+
1022+ process .stdin .on (' end' , () => {
1023+ sock .destroy ();
1024+ console .log ();
1025+ });
1026+
1027+ process .stdin .on (' data' , (b ) => {
1028+ if (b .length === 1 && b[0 ] === 4 ) {
1029+ process .stdin .emit (' end' );
1030+ }
1031+ });
1032+ ```
1033+
1034+ To run the example open two different terminals on your machine, start the server
1035+ with ` node repl-server.js ` in one terminal and ` node repl-client.js ` on the other.
1036+
1037+ Original code from < https://gist.github.com/TooTallNate/2209310 > .
1038+
1039+ #### REPL over ` curl `
1040+
1041+ This is an example on how to run a REPL instance over [ ` curl() ` ] [ ]
1042+
1043+ The following script starts an HTTP server on port ` 8000 ` that can accept
1044+ a connection established via [ ` curl() ` ] [ ] .
1045+
1046+ ``` mjs
1047+ import http from ' node:http' ;
1048+ import repl from ' node:repl' ;
1049+
1050+ const server = http .createServer ((req , res ) => {
1051+ res .setHeader (' content-type' , ' multipart/octet-stream' );
1052+
1053+ repl .start ({
1054+ prompt: ' curl repl> ' ,
1055+ input: req,
1056+ output: res,
1057+ terminal: false ,
1058+ useColors: true ,
1059+ useGlobal: false ,
1060+ });
1061+ });
1062+
1063+ server .listen (8000 );
1064+ ```
1065+
1066+ ``` cjs
1067+ const http = require (' node:http' );
1068+ const repl = require (' node:repl' );
1069+
1070+ const server = http .createServer ((req , res ) => {
1071+ res .setHeader (' content-type' , ' multipart/octet-stream' );
1072+
1073+ repl .start ({
1074+ prompt: ' curl repl> ' ,
1075+ input: req,
1076+ output: res,
1077+ terminal: false ,
1078+ useColors: true ,
1079+ useGlobal: false ,
1080+ });
1081+ });
1082+
1083+ server .listen (8000 );
1084+ ```
1085+
1086+ When the above script is running you can then use [ ` curl() ` ] [ ] to connect to
1087+ the server and connect to its REPL instance by running ` curl --no-progress-meter -sSNT. localhost:8000 ` .
1088+
1089+ ** Warning** This example is intended purely for educational purposes to demonstrate how
9201090Node.js REPLs can be started using different I/O streams.
9211091It should ** not** be used in production environments or any context where security
9221092is a concern without additional protective measures.
9231093If you need to implement REPLs in a real-world application, consider alternative
9241094approaches that mitigate these risks, such as using secure input mechanisms and
9251095avoiding open network interfaces.
9261096
1097+ Original code from < https://gist.github.com/TooTallNate/2053342 > .
1098+
9271099[ TTY keybindings ] : readline.md#tty-keybindings
9281100[ ZSH ] : https://en.wikipedia.org/wiki/Z_shell
9291101[ `'uncaughtException'` ] : process.md#event-uncaughtexception
9301102[ `--no-experimental-repl-await` ] : cli.md#--no-experimental-repl-await
9311103[ `ERR_DOMAIN_CANNOT_SET_UNCAUGHT_EXCEPTION_CAPTURE` ] : errors.md#err_domain_cannot_set_uncaught_exception_capture
9321104[ `ERR_INVALID_REPL_INPUT` ] : errors.md#err_invalid_repl_input
933- [ `curl(1 )` ] : https://curl.haxx.se/docs/manpage.html
1105+ [ `curl()` ] : https://curl.haxx.se/docs/manpage.html
9341106[ `domain` ] : domain.md
9351107[ `module.builtinModules` ] : module.md#modulebuiltinmodules
1108+ [ `net.Server` ] : net.md#class-netserver
1109+ [ `net.Socket` ] : net.md#class-netsocket
9361110[ `process.setUncaughtExceptionCaptureCallback()` ] : process.md#processsetuncaughtexceptioncapturecallbackfn
9371111[ `readline.InterfaceCompleter` ] : readline.md#use-of-the-completer-function
9381112[ `repl.ReplServer` ] : #class-replserver
0 commit comments