diff --git a/index.d.ts b/index.d.ts index dae5f58..f75b4c0 100644 --- a/index.d.ts +++ b/index.d.ts @@ -10,6 +10,7 @@ export interface PtyOptions { envs?: Record dir?: string size?: Size + interactive?: boolean onExit: (err: null | Error, exitCode: number) => void } /** A size struct to pass to resize. */ diff --git a/package-lock.json b/package-lock.json index 105749c..69ed1aa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@replit/ruspty", - "version": "3.1.2", + "version": "3.1.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@replit/ruspty", - "version": "3.1.2", + "version": "3.1.3", "license": "MIT", "devDependencies": { "@napi-rs/cli": "^2.18.2", diff --git a/package.json b/package.json index daae6b7..1886cbb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@replit/ruspty", - "version": "3.1.2", + "version": "3.1.3", "main": "dist/wrapper.js", "types": "dist/wrapper.d.ts", "author": "Szymon Kaliski ", diff --git a/src/lib.rs b/src/lib.rs index 97b8cc7..97a0a27 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -40,6 +40,7 @@ struct PtyOptions { pub envs: Option>, pub dir: Option, pub size: Option, + pub interactive: Option, #[napi(ts_type = "(err: null | Error, exitCode: number) => void")] pub on_exit: JsFunction, } @@ -128,7 +129,11 @@ impl Pty { set_nonblocking(controller_fd.as_raw_fd())?; // duplicate pty user_fd to be the child's stdin, stdout, and stderr - cmd.stdin(Stdio::from(user_fd.try_clone()?)); + if opts.interactive.unwrap_or(true) { + cmd.stdin(Stdio::from(user_fd.try_clone()?)); + } else { + cmd.stdin(Stdio::null()); + } cmd.stderr(Stdio::from(user_fd.try_clone()?)); cmd.stdout(Stdio::from(user_fd.try_clone()?)); diff --git a/tests/index.test.ts b/tests/index.test.ts index c627b9b..d0bf0c0 100644 --- a/tests/index.test.ts +++ b/tests/index.test.ts @@ -121,6 +121,34 @@ describe( writeStream.end(EOT); })); + test('can be started in non-interactive fashion', () => + new Promise((done) => { + const oldFds = getOpenFds(); + + let buffer = ''; + + const expectedResult = '\r\n'; + + const pty = new Pty({ + command: '/bin/cat', + interactive: false, + onExit: (err, exitCode) => { + expect(err).toBeNull(); + expect(exitCode).toBe(0); + let result = buffer.toString(); + expect(result.trim()).toStrictEqual(expectedResult.trim()); + expect(getOpenFds()).toStrictEqual(oldFds); + done(); + }, + }); + + const readStream = pty.read; + + readStream.on('data', (data) => { + buffer += data.toString(); + }); + })); + test('can be resized', () => new Promise((done) => { const oldFds = getOpenFds();