From 85a6f1cfefa339bd285eea7690e422eed0c1ee01 Mon Sep 17 00:00:00 2001 From: mostafaroshdy1 <66712535+mostafaroshdy1@users.noreply.github.com> Date: Sun, 9 Nov 2025 23:42:19 +0200 Subject: [PATCH 1/2] module: read from stdin when input is a pipe Update the CommonJS module loader to detect when the input filename is /dev/stdin and stdin is a pipe (FIFO). In such cases, read directly from file descriptor 0 instead of attempting to open the /proc//fd/pipe:[...] path, which can result in ENOENT errors. This change ensures that running Node with piped input like: printf 'console.log(1)' | node /dev/stdin works reliably on Linux systems. Fixes: https://github.com/nodejs/node/issues/54200 --- lib/internal/modules/cjs/loader.js | 5 +++++ test/parallel/test-typescript-stdin-pipe.js | 21 +++++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 test/parallel/test-typescript-stdin-pipe.js diff --git a/lib/internal/modules/cjs/loader.js b/lib/internal/modules/cjs/loader.js index b8aac380da7974..74e1e8c5227bd3 100644 --- a/lib/internal/modules/cjs/loader.js +++ b/lib/internal/modules/cjs/loader.js @@ -1135,6 +1135,11 @@ function defaultLoadImpl(filename, format) { case 'module-typescript': case 'commonjs-typescript': case 'typescript': { + const isPipePath = ['/dev/stdin', '/dev/fd/0'].includes(filename) || + (filename.startsWith('/proc/') && filename.includes('/fd/pipe:')); + if (isPipePath) { + return fs.readFileSync(0, 'utf8'); + } return fs.readFileSync(filename, 'utf8'); } case 'builtin': diff --git a/test/parallel/test-typescript-stdin-pipe.js b/test/parallel/test-typescript-stdin-pipe.js new file mode 100644 index 00000000000000..e144a3c8d57251 --- /dev/null +++ b/test/parallel/test-typescript-stdin-pipe.js @@ -0,0 +1,21 @@ +'use strict'; +const common = require('../common'); + +if (common.isWindows || common.isAIX || common.isIBMi) + common.skip(`No /dev/stdin on ${process.platform}.`); + +const assert = require('assert'); +const { exec } = require('child_process'); + +const tsCode = ` +const message = "JavaScript from pipe"; +console.log(message); +`; + + +const [cmd, opts] = common.escapePOSIXShell`echo ${tsCode} | ${process.execPath} /dev/stdin`; + +exec(cmd, opts, common.mustSucceed((stdout, stderr) => { + assert.strictEqual(stdout.trim(), 'JavaScript from pipe'); + assert.strictEqual(stderr, ''); +})); From 78959f7fddbb53ac960333bb2b9c197a841ca55d Mon Sep 17 00:00:00 2001 From: mostafaroshdy1 <66712535+mostafaroshdy1@users.noreply.github.com> Date: Mon, 10 Nov 2025 01:31:49 +0200 Subject: [PATCH 2/2] test: replace echo with printf for reliable multi-line stdin piping --- test/parallel/test-typescript-stdin-pipe.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/parallel/test-typescript-stdin-pipe.js b/test/parallel/test-typescript-stdin-pipe.js index e144a3c8d57251..741fa8c7bbab42 100644 --- a/test/parallel/test-typescript-stdin-pipe.js +++ b/test/parallel/test-typescript-stdin-pipe.js @@ -13,7 +13,7 @@ console.log(message); `; -const [cmd, opts] = common.escapePOSIXShell`echo ${tsCode} | ${process.execPath} /dev/stdin`; +const [cmd, opts] = common.escapePOSIXShell`printf "${tsCode}" | ${process.execPath} /dev/stdin`; exec(cmd, opts, common.mustSucceed((stdout, stderr) => { assert.strictEqual(stdout.trim(), 'JavaScript from pipe');