From 27777932a8b6167e2b557bf3868c785d94e109ee Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Thu, 24 Feb 2022 14:12:18 +0100 Subject: [PATCH 1/2] lib: expose a global `node` proxy in eval script and REPL This global is meant to be a convenient shortcut to access core modules. --- doc/api/inspector.md | 6 +- doc/api/tls.md | 2 +- lib/internal/process/execution.js | 3 + lib/repl.js | 6 +- ...t-buffer-constructor-node-modules-paths.js | 2 +- test/parallel/test-cli-eval.js | 2 +- test/parallel/test-cli-options-precedence.js | 4 +- test/parallel/test-dummy-stdio.js | 2 +- test/parallel/test-http-max-header-size.js | 2 +- .../test-os-userinfo-handles-getter-errors.js | 2 +- test/parallel/test-tls-cipher-list.js | 8 +- test/parallel/test-trace-events-fs-sync.js | 184 +++++++++--------- .../test-vm-api-handles-getter-errors.js | 4 +- 13 files changed, 117 insertions(+), 110 deletions(-) diff --git a/doc/api/inspector.md b/doc/api/inspector.md index ea31db782d0b0f..00fd70edd54aa9 100644 --- a/doc/api/inspector.md +++ b/doc/api/inspector.md @@ -55,17 +55,17 @@ parameter usage. Return the URL of the active inspector, or `undefined` if there is none. ```console -$ node --inspect -p 'inspector.url()' +$ node --inspect -p 'node.inspector.url()' Debugger listening on ws://127.0.0.1:9229/166e272e-7a30-4d09-97ce-f1c012b43c34 For help, see: https://nodejs.org/en/docs/inspector ws://127.0.0.1:9229/166e272e-7a30-4d09-97ce-f1c012b43c34 -$ node --inspect=localhost:3000 -p 'inspector.url()' +$ node --inspect=localhost:3000 -p 'node.inspector.url()' Debugger listening on ws://localhost:3000/51cf8d0e-3c36-4c59-8efd-54519839e56a For help, see: https://nodejs.org/en/docs/inspector ws://localhost:3000/51cf8d0e-3c36-4c59-8efd-54519839e56a -$ node -p 'inspector.url()' +$ node -p 'node.inspector.url()' undefined ``` diff --git a/doc/api/tls.md b/doc/api/tls.md index 0402bdcd97ebcc..a8e40366579dcb 100644 --- a/doc/api/tls.md +++ b/doc/api/tls.md @@ -280,7 +280,7 @@ distributions to provide their own default list. The following command can be used to show the default cipher suite: ```console -node -p crypto.constants.defaultCoreCipherList | tr ':' '\n' +node -p node.crypto.constants.defaultCoreCipherList | tr ':' '\n' TLS_AES_256_GCM_SHA384 TLS_CHACHA20_POLY1305_SHA256 TLS_AES_128_GCM_SHA256 diff --git a/lib/internal/process/execution.js b/lib/internal/process/execution.js index 4a8e51f694f7e6..91b8ee406ea5cb 100644 --- a/lib/internal/process/execution.js +++ b/lib/internal/process/execution.js @@ -65,6 +65,9 @@ function evalScript(name, body, breakFirstLine, print) { // Create wrapper for cache entry const script = ` + globalThis.node = new Proxy(Object.freeze(Object.create(null)), { + get: (_, prop) => require("node:"+prop), + }); globalThis.module = module; globalThis.exports = exports; globalThis.__dirname = __dirname; diff --git a/lib/repl.js b/lib/repl.js index eb9152d9ce0266..49dd441491429f 100644 --- a/lib/repl.js +++ b/lib/repl.js @@ -1098,13 +1098,17 @@ REPLServer.prototype.createContext = function() { writable: true, value: replModule }); + const requireFunction = makeRequireFunction(replModule) ObjectDefineProperty(context, 'require', { configurable: true, writable: true, - value: makeRequireFunction(replModule) + value: requireFunction, }); addBuiltinLibsToObject(context, ''); + context.node = new Proxy(Object.freeze(Object.create(null)), { + get: (_, prop) => requireFunction("node:"+prop), + }) return context; }; diff --git a/test/parallel/test-buffer-constructor-node-modules-paths.js b/test/parallel/test-buffer-constructor-node-modules-paths.js index 40d314aec08435..1103afa4cd5a6b 100644 --- a/test/parallel/test-buffer-constructor-node-modules-paths.js +++ b/test/parallel/test-buffer-constructor-node-modules-paths.js @@ -11,7 +11,7 @@ function test(main, callSite, expected) { const { stderr } = child_process.spawnSync(process.execPath, ['-p', ` process.mainModule = { filename: ${JSON.stringify(main)} }; - vm.runInNewContext('new Buffer(10)', { Buffer }, { + node.vm.runInNewContext('new Buffer(10)', { Buffer }, { filename: ${JSON.stringify(callSite)} });`], { encoding: 'utf8' }); if (expected) diff --git a/test/parallel/test-cli-eval.js b/test/parallel/test-cli-eval.js index e95fee008d6e3a..3e057be96bec4c 100644 --- a/test/parallel/test-cli-eval.js +++ b/test/parallel/test-cli-eval.js @@ -83,7 +83,7 @@ child.exec(`${nodejs} --eval "console.error(42)"`, } // Check that builtin modules are pre-defined. -child.exec(`${nodejs} --print "os.platform()"`, +child.exec(`${nodejs} --print "node.os.platform()"`, common.mustSucceed((stdout, stderr) => { assert.strictEqual(stderr, ''); assert.strictEqual(stdout.trim(), require('os').platform()); diff --git a/test/parallel/test-cli-options-precedence.js b/test/parallel/test-cli-options-precedence.js index 32804d187fccc3..884eec2ad14fa5 100644 --- a/test/parallel/test-cli-options-precedence.js +++ b/test/parallel/test-cli-options-precedence.js @@ -7,7 +7,7 @@ const { spawnSync } = require('child_process'); assert.strictEqual(spawnSync(process.execPath, [ '--max-http-header-size=1234', '--max-http-header-size=5678', - '-p', 'http.maxHeaderSize', + '-p', 'node.http.maxHeaderSize', ], { encoding: 'utf8' }).stdout.trim(), '5678'); @@ -15,7 +15,7 @@ assert.strictEqual(spawnSync(process.execPath, [ // The command line takes precedence over NODE_OPTIONS: assert.strictEqual(spawnSync(process.execPath, [ '--max-http-header-size=5678', - '-p', 'http.maxHeaderSize', + '-p', 'node.http.maxHeaderSize', ], { encoding: 'utf8', env: { ...process.env, NODE_OPTIONS: '--max-http-header-size=1234' } diff --git a/test/parallel/test-dummy-stdio.js b/test/parallel/test-dummy-stdio.js index 4866f85c7def4b..864b372d3e0950 100644 --- a/test/parallel/test-dummy-stdio.js +++ b/test/parallel/test-dummy-stdio.js @@ -13,7 +13,7 @@ function runTest(fd, streamName, testOutputStream, expectedName) { '-e', `const { internalBinding } = require('internal/test/binding'); internalBinding('process_methods').resetStdioForTesting(); - fs.closeSync(${fd}); + node.fs.closeSync(${fd}); const ctorName = process.${streamName}.constructor.name; process.${testOutputStream}.write(ctorName); `]); diff --git a/test/parallel/test-http-max-header-size.js b/test/parallel/test-http-max-header-size.js index 53bd58c4f179b6..8e35594cd4ba30 100644 --- a/test/parallel/test-http-max-header-size.js +++ b/test/parallel/test-http-max-header-size.js @@ -7,5 +7,5 @@ const http = require('http'); assert.strictEqual(http.maxHeaderSize, 16 * 1024); const child = spawnSync(process.execPath, ['--max-http-header-size=10', '-p', - 'http.maxHeaderSize']); + 'node.http.maxHeaderSize']); assert.strictEqual(+child.stdout.toString().trim(), 10); diff --git a/test/parallel/test-os-userinfo-handles-getter-errors.js b/test/parallel/test-os-userinfo-handles-getter-errors.js index 146ab6c812379f..f0831929fe6992 100644 --- a/test/parallel/test-os-userinfo-handles-getter-errors.js +++ b/test/parallel/test-os-userinfo-handles-getter-errors.js @@ -6,7 +6,7 @@ const common = require('../common'); const assert = require('assert'); const execFile = require('child_process').execFile; -const script = `os.userInfo({ +const script = `node.os.userInfo({ get encoding() { throw new Error('xyz'); } diff --git a/test/parallel/test-tls-cipher-list.js b/test/parallel/test-tls-cipher-list.js index b1a61405898a9a..63938c23b114b5 100644 --- a/test/parallel/test-tls-cipher-list.js +++ b/test/parallel/test-tls-cipher-list.js @@ -24,9 +24,9 @@ function doCheck(arg, expression, check) { } // Test the default unmodified version -doCheck([], 'crypto.constants.defaultCipherList', defaultCoreList); -doCheck([], 'tls.DEFAULT_CIPHERS', defaultCoreList); +doCheck([], 'node.crypto.constants.defaultCipherList', defaultCoreList); +doCheck([], 'node.tls.DEFAULT_CIPHERS', defaultCoreList); // Test the command line switch by itself -doCheck(['--tls-cipher-list=ABC'], 'crypto.constants.defaultCipherList', 'ABC'); -doCheck(['--tls-cipher-list=ABC'], 'tls.DEFAULT_CIPHERS', 'ABC'); +doCheck(['--tls-cipher-list=ABC'], 'node.crypto.constants.defaultCipherList', 'ABC'); +doCheck(['--tls-cipher-list=ABC'], 'node.tls.DEFAULT_CIPHERS', 'ABC'); diff --git a/test/parallel/test-trace-events-fs-sync.js b/test/parallel/test-trace-events-fs-sync.js index 78a5059bc91f5f..4105b69c1839e0 100644 --- a/test/parallel/test-trace-events-fs-sync.js +++ b/test/parallel/test-trace-events-fs-sync.js @@ -16,102 +16,102 @@ if (!common.isWindows) { uid = process.getuid(); } -tests['fs.sync.access'] = 'fs.writeFileSync("fs.txt", "123", "utf8");' + - 'fs.accessSync("fs.txt");' + - 'fs.unlinkSync("fs.txt")'; -tests['fs.sync.chmod'] = 'fs.writeFileSync("fs.txt", "123", "utf8");' + - 'fs.chmodSync("fs.txt",100);' + - 'fs.unlinkSync("fs.txt")'; -tests['fs.sync.chown'] = 'fs.writeFileSync("fs.txt", "123", "utf8");' + - `fs.chownSync("fs.txt", ${uid}, ${gid});` + - 'fs.unlinkSync("fs.txt")'; -tests['fs.sync.close'] = 'fs.writeFileSync("fs.txt", "123", "utf8");' + - 'fs.unlinkSync("fs.txt")'; -tests['fs.sync.copyfile'] = 'fs.writeFileSync("fs.txt", "123", "utf8");' + - 'fs.copyFileSync("fs.txt","a.txt");' + - 'fs.unlinkSync("fs.txt")'; -tests['fs.sync.fchmod'] = 'fs.writeFileSync("fs.txt", "123", "utf8");' + - 'const fd = fs.openSync("fs.txt", "r+");' + - 'fs.fchmodSync(fd,100);' + - 'fs.unlinkSync("fs.txt")'; -tests['fs.sync.fchown'] = 'fs.writeFileSync("fs.txt", "123", "utf8");' + - 'const fd = fs.openSync("fs.txt", "r+");' + - `fs.fchownSync(fd, ${uid}, ${gid});` + - 'fs.unlinkSync("fs.txt")'; -tests['fs.sync.fdatasync'] = 'fs.writeFileSync("fs.txt", "123", "utf8");' + - 'const fd = fs.openSync("fs.txt", "r+");' + - 'fs.fdatasyncSync(fd);' + - 'fs.unlinkSync("fs.txt")'; -tests['fs.sync.fstat'] = 'fs.writeFileSync("fs.txt", "123", "utf8");' + - 'fs.readFileSync("fs.txt");' + - 'fs.unlinkSync("fs.txt")'; -tests['fs.sync.fsync'] = 'fs.writeFileSync("fs.txt", "123", "utf8");' + - 'const fd = fs.openSync("fs.txt", "r+");' + - 'fs.fsyncSync(fd);' + - 'fs.unlinkSync("fs.txt")'; -tests['fs.sync.ftruncate'] = 'fs.writeFileSync("fs.txt", "123", "utf8");' + - 'const fd = fs.openSync("fs.txt", "r+");' + - 'fs.ftruncateSync(fd, 1);' + - 'fs.unlinkSync("fs.txt")'; -tests['fs.sync.futimes'] = 'fs.writeFileSync("fs.txt", "123", "utf8");' + - 'const fd = fs.openSync("fs.txt", "r+");' + - 'fs.futimesSync(fd,1,1);' + - 'fs.unlinkSync("fs.txt")'; -tests['fs.sync.lchown'] = 'fs.writeFileSync("fs.txt", "123", "utf8");' + - `fs.lchownSync("fs.txt", ${uid}, ${gid});` + - 'fs.unlinkSync("fs.txt")'; -tests['fs.sync.link'] = 'fs.writeFileSync("fs.txt", "123", "utf8");' + - 'fs.linkSync("fs.txt", "linkx");' + - 'fs.unlinkSync("linkx");' + - 'fs.unlinkSync("fs.txt")'; -tests['fs.sync.lstat'] = 'fs.writeFileSync("fs.txt", "123", "utf8");' + - 'fs.lstatSync("fs.txt");' + - 'fs.unlinkSync("fs.txt")'; -tests['fs.sync.mkdir'] = 'fs.mkdirSync("fstemp");' + - 'fs.rmdirSync("fstemp")'; -tests['fs.sync.mkdtemp'] = 'const fp = fs.mkdtempSync("fstest");' + - 'fs.rmdirSync(fp)'; -tests['fs.sync.open'] = 'fs.writeFileSync("fs.txt", "123", "utf8");' + - 'fs.unlinkSync("fs.txt")'; -tests['fs.sync.read'] = 'fs.writeFileSync("fs.txt", "123", "utf8");' + - 'fs.readFileSync("fs.txt");' + - 'fs.unlinkSync("fs.txt")'; -tests['fs.sync.readdir'] = 'fs.readdirSync("./")'; -tests['fs.sync.realpath'] = 'fs.writeFileSync("fs.txt", "123", "utf8");' + - 'fs.linkSync("fs.txt", "linkx");' + - 'fs.realpathSync.native("linkx");' + - 'fs.unlinkSync("linkx");' + - 'fs.unlinkSync("fs.txt")'; -tests['fs.sync.rename'] = 'fs.writeFileSync("fs.txt", "123", "utf8");' + - 'fs.renameSync("fs.txt","xyz.txt"); ' + - 'fs.unlinkSync("xyz.txt")'; -tests['fs.sync.rmdir'] = 'fs.mkdirSync("fstemp");' + - 'fs.rmdirSync("fstemp")'; -tests['fs.sync.stat'] = 'fs.writeFileSync("fs.txt", "123", "utf8");' + - 'fs.statSync("fs.txt");' + - 'fs.unlinkSync("fs.txt")'; -tests['fs.sync.unlink'] = 'fs.writeFileSync("fs.txt", "123", "utf8");' + - 'fs.linkSync("fs.txt", "linkx");' + - 'fs.unlinkSync("linkx");' + - 'fs.unlinkSync("fs.txt")'; -tests['fs.sync.utimes'] = 'fs.writeFileSync("fs.txt", "123", "utf8");' + - 'fs.utimesSync("fs.txt",1,1);' + - 'fs.unlinkSync("fs.txt")'; -tests['fs.sync.write'] = 'fs.writeFileSync("fs.txt", "123", "utf8");' + - 'fs.unlinkSync("fs.txt")'; +tests['fs.sync.access'] = 'node.fs.writeFileSync("fs.txt", "123", "utf8");' + + 'node.fs.accessSync("fs.txt");' + + 'node.fs.unlinkSync("fs.txt")'; +tests['fs.sync.chmod'] = 'node.fs.writeFileSync("fs.txt", "123", "utf8");' + + 'node.fs.chmodSync("fs.txt",100);' + + 'node.fs.unlinkSync("fs.txt")'; +tests['fs.sync.chown'] = 'node.fs.writeFileSync("fs.txt", "123", "utf8");' + + `node.fs.chownSync("fs.txt", ${uid}, ${gid});` + + 'node.fs.unlinkSync("fs.txt")'; +tests['fs.sync.close'] = 'node.fs.writeFileSync("fs.txt", "123", "utf8");' + + 'node.fs.unlinkSync("fs.txt")'; +tests['fs.sync.copyfile'] = 'node.fs.writeFileSync("fs.txt", "123", "utf8");' + + 'node.fs.copyFileSync("fs.txt","a.txt");' + + 'node.fs.unlinkSync("fs.txt")'; +tests['fs.sync.fchmod'] = 'node.fs.writeFileSync("fs.txt", "123", "utf8");' + + 'const fd = node.fs.openSync("fs.txt", "r+");' + + 'node.fs.fchmodSync(fd,100);' + + 'node.fs.unlinkSync("fs.txt")'; +tests['fs.sync.fchown'] = 'node.fs.writeFileSync("fs.txt", "123", "utf8");' + + 'const fd = node.fs.openSync("fs.txt", "r+");' + + `node.fs.fchownSync(fd, ${uid}, ${gid});` + + 'node.fs.unlinkSync("fs.txt")'; +tests['fs.sync.fdatasync'] = 'node.fs.writeFileSync("fs.txt", "123", "utf8");' + + 'const fd = node.fs.openSync("fs.txt", "r+");' + + 'node.fs.fdatasyncSync(fd);' + + 'node.fs.unlinkSync("fs.txt")'; +tests['fs.sync.fstat'] = 'node.fs.writeFileSync("fs.txt", "123", "utf8");' + + 'node.fs.readFileSync("fs.txt");' + + 'node.fs.unlinkSync("fs.txt")'; +tests['fs.sync.fsync'] = 'node.fs.writeFileSync("fs.txt", "123", "utf8");' + + 'const fd = node.fs.openSync("fs.txt", "r+");' + + 'node.fs.fsyncSync(fd);' + + 'node.fs.unlinkSync("fs.txt")'; +tests['fs.sync.ftruncate'] = 'node.fs.writeFileSync("fs.txt", "123", "utf8");' + + 'const fd = node.fs.openSync("fs.txt", "r+");' + + 'node.fs.ftruncateSync(fd, 1);' + + 'node.fs.unlinkSync("fs.txt")'; +tests['fs.sync.futimes'] = 'node.fs.writeFileSync("fs.txt", "123", "utf8");' + + 'const fd = node.fs.openSync("fs.txt", "r+");' + + 'node.fs.futimesSync(fd,1,1);' + + 'node.fs.unlinkSync("fs.txt")'; +tests['fs.sync.lchown'] = 'node.fs.writeFileSync("fs.txt", "123", "utf8");' + + `node.fs.lchownSync("fs.txt", ${uid}, ${gid});` + + 'node.fs.unlinkSync("fs.txt")'; +tests['fs.sync.link'] = 'node.fs.writeFileSync("fs.txt", "123", "utf8");' + + 'node.fs.linkSync("fs.txt", "linkx");' + + 'node.fs.unlinkSync("linkx");' + + 'node.fs.unlinkSync("fs.txt")'; +tests['fs.sync.lstat'] = 'node.fs.writeFileSync("fs.txt", "123", "utf8");' + + 'node.fs.lstatSync("fs.txt");' + + 'node.fs.unlinkSync("fs.txt")'; +tests['fs.sync.mkdir'] = 'node.fs.mkdirSync("fstemp");' + + 'node.fs.rmdirSync("fstemp")'; +tests['fs.sync.mkdtemp'] = 'const fp = node.fs.mkdtempSync("fstest");' + + 'node.fs.rmdirSync(fp)'; +tests['fs.sync.open'] = 'node.fs.writeFileSync("fs.txt", "123", "utf8");' + + 'node.fs.unlinkSync("fs.txt")'; +tests['fs.sync.read'] = 'node.fs.writeFileSync("fs.txt", "123", "utf8");' + + 'node.fs.readFileSync("fs.txt");' + + 'node.fs.unlinkSync("fs.txt")'; +tests['fs.sync.readdir'] = 'node.fs.readdirSync("./")'; +tests['fs.sync.realpath'] = 'node.fs.writeFileSync("fs.txt", "123", "utf8");' + + 'node.fs.linkSync("fs.txt", "linkx");' + + 'node.fs.realpathSync.native("linkx");' + + 'node.fs.unlinkSync("linkx");' + + 'node.fs.unlinkSync("fs.txt")'; +tests['fs.sync.rename'] = 'node.fs.writeFileSync("fs.txt", "123", "utf8");' + + 'node.fs.renameSync("fs.txt","xyz.txt"); ' + + 'node.fs.unlinkSync("xyz.txt")'; +tests['fs.sync.rmdir'] = 'node.fs.mkdirSync("fstemp");' + + 'node.fs.rmdirSync("fstemp")'; +tests['fs.sync.stat'] = 'node.fs.writeFileSync("fs.txt", "123", "utf8");' + + 'node.fs.statSync("fs.txt");' + + 'node.fs.unlinkSync("fs.txt")'; +tests['fs.sync.unlink'] = 'node.fs.writeFileSync("fs.txt", "123", "utf8");' + + 'node.fs.linkSync("fs.txt", "linkx");' + + 'node.fs.unlinkSync("linkx");' + + 'node.fs.unlinkSync("fs.txt")'; +tests['fs.sync.utimes'] = 'node.fs.writeFileSync("fs.txt", "123", "utf8");' + + 'node.fs.utimesSync("fs.txt",1,1);' + + 'node.fs.unlinkSync("fs.txt")'; +tests['fs.sync.write'] = 'node.fs.writeFileSync("fs.txt", "123", "utf8");' + + 'node.fs.unlinkSync("fs.txt")'; // On windows, we need permissions to test symlink and readlink. // We'll only try to run these tests if we have enough privileges. if (common.canCreateSymLink()) { - tests['fs.sync.symlink'] = 'fs.writeFileSync("fs.txt", "123", "utf8");' + - 'fs.symlinkSync("fs.txt", "linkx");' + - 'fs.unlinkSync("linkx");' + - 'fs.unlinkSync("fs.txt")'; - tests['fs.sync.readlink'] = 'fs.writeFileSync("fs.txt", "123", "utf8");' + - 'fs.symlinkSync("fs.txt", "linkx");' + - 'fs.readlinkSync("linkx");' + - 'fs.unlinkSync("linkx");' + - 'fs.unlinkSync("fs.txt")'; + tests['fs.sync.symlink'] = 'node.fs.writeFileSync("fs.txt", "123", "utf8");' + + 'node.fs.symlinkSync("fs.txt", "linkx");' + + 'node.fs.unlinkSync("linkx");' + + 'node.fs.unlinkSync("fs.txt")'; + tests['fs.sync.readlink'] = 'node.fs.writeFileSync("fs.txt", "123", "utf8");' + + 'node.fs.symlinkSync("fs.txt", "linkx");' + + 'node.fs.readlinkSync("linkx");' + + 'node.fs.unlinkSync("linkx");' + + 'node.fs.unlinkSync("fs.txt")'; } const tmpdir = require('../common/tmpdir'); diff --git a/test/parallel/test-vm-api-handles-getter-errors.js b/test/parallel/test-vm-api-handles-getter-errors.js index 6a74fb29c17c81..3c333a1557fc20 100644 --- a/test/parallel/test-vm-api-handles-getter-errors.js +++ b/test/parallel/test-vm-api-handles-getter-errors.js @@ -11,7 +11,7 @@ const scripts = []; ['filename', 'cachedData', 'produceCachedData', 'lineOffset', 'columnOffset'] .forEach((prop) => { - scripts.push(`vm.createScript('', { + scripts.push(`node.vm.createScript('', { get ${prop} () { throw new Error('xyz'); } @@ -20,7 +20,7 @@ const scripts = []; ['breakOnSigint', 'timeout', 'displayErrors'] .forEach((prop) => { - scripts.push(`vm.createScript('').runInThisContext({ + scripts.push(`node.vm.createScript('').runInThisContext({ get ${prop} () { throw new Error('xyz'); } From d231a4784640dab7f0789ccdba92357a81a45a18 Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Sat, 26 Feb 2022 11:50:22 +0100 Subject: [PATCH 2/2] fixup! lib: expose a global `node` proxy in eval script and REPL --- lib/internal/process/execution.js | 9 ++++++--- lib/repl.js | 28 ++++++++++++++++++++++++---- 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/lib/internal/process/execution.js b/lib/internal/process/execution.js index 91b8ee406ea5cb..adf803e5722ec6 100644 --- a/lib/internal/process/execution.js +++ b/lib/internal/process/execution.js @@ -65,9 +65,12 @@ function evalScript(name, body, breakFirstLine, print) { // Create wrapper for cache entry const script = ` - globalThis.node = new Proxy(Object.freeze(Object.create(null)), { - get: (_, prop) => require("node:"+prop), - }); + { + class CoreModulesAggregator {} + globalThis.node = new Proxy(Object.freeze(new CoreModulesAggregator()), { + get: (_, prop) => require('node:' + prop), + }); + } globalThis.module = module; globalThis.exports = exports; globalThis.__dirname = __dirname; diff --git a/lib/repl.js b/lib/repl.js index 49dd441491429f..7274ec1b5d2c67 100644 --- a/lib/repl.js +++ b/lib/repl.js @@ -61,6 +61,7 @@ const { ArrayPrototypeUnshift, Boolean, Error, + FunctionPrototype, FunctionPrototypeBind, MathMaxApply, NumberIsNaN, @@ -72,9 +73,11 @@ const { ObjectGetOwnPropertyNames, ObjectGetPrototypeOf, ObjectKeys, + ObjectPreventExtensions, ObjectSetPrototypeOf, Promise, PromiseRace, + Proxy, ReflectApply, RegExp, RegExpPrototypeExec, @@ -109,6 +112,7 @@ const { isIdentifierChar } = require('internal/deps/acorn/acorn/dist/acorn'); const { + customInspectSymbol, decorateErrorStack, isError, deprecate @@ -1098,17 +1102,33 @@ REPLServer.prototype.createContext = function() { writable: true, value: replModule }); - const requireFunction = makeRequireFunction(replModule) + const requireFunction = makeRequireFunction(replModule); ObjectDefineProperty(context, 'require', { configurable: true, writable: true, value: requireFunction, }); + // TODO(aduh95): deprecate and remove access to core modules from global. addBuiltinLibsToObject(context, ''); - context.node = new Proxy(Object.freeze(Object.create(null)), { - get: (_, prop) => requireFunction("node:"+prop), - }) + + const builtinProxy = ObjectCreate(null); + // Adding "fake" getters to help with the autocomplete. + const { builtinModules } = require('internal/modules/cjs/loader').Module; + const propertyDefinition = { + enumerable: true, + configurable: false, + get: FunctionPrototype, + set: undefined, + }; + for (let i = 0; i < builtinModules.length; i++) { + ObjectDefineProperty(builtinProxy, builtinModules[i], propertyDefinition); + } + builtinProxy[customInspectSymbol] = () => 'CoreModulesAggregator {}'; + context.node = new Proxy(ObjectPreventExtensions(builtinProxy), { + // eslint-disable-next-line func-name-matching + get: function require(_, prop) { return requireFunction('node:' + prop); }, + }); return context; };