diff --git a/lib/.eslintrc.yaml b/lib/.eslintrc.yaml index 05142865e12802..9a2e6f43ba410a 100644 --- a/lib/.eslintrc.yaml +++ b/lib/.eslintrc.yaml @@ -25,6 +25,60 @@ rules: message: "Please use `require('internal/errors').hideStackFrames()` instead." - selector: "AssignmentExpression:matches([left.name='prepareStackTrace'], [left.property.name='prepareStackTrace'])" message: "Use 'overrideStackTrace' from 'lib/internal/errors.js' instead of 'Error.prepareStackTrace'." + no-restricted-globals: + - error + - name: AbortController + message: "Use `const { AbortController } = require('internal/abort_controller');` instead of the global." + - name: AbortSignal + message: "Use `const { AbortSignal } = require('internal/abort_controller');` instead of the global." + # Atomics is not available in primordials because it can be + # disabled with --no-harmony-atomics CLI flag. + - name: Atomics + message: "Use `const { Atomics } = globalThis;` instead of the global." + - name: Buffer + message: "Use `const { Buffer } = require('buffer');` instead of the global." + - name: Event + message: "Use `const { Event } = require('internal/event_target');` instead of the global." + - name: EventTarget + message: "Use `const { EventTarget } = require('internal/event_target');` instead of the global." + # Intl is not available in primordials because it can be + # disabled with --without-intl build flag. + - name: Intl + message: "Use `const { Intl } = globalThis;` instead of the global." + - name: MessageChannel + message: "Use `const { MessageChannel } = require('internal/worker/io');` instead of the global." + - name: MessageEvent + message: "Use `const { MessageEvent } = require('internal/worker/io');` instead of the global." + - name: MessagePort + message: "Use `const { MessagePort } = require('internal/worker/io');` instead of the global." + # SharedArrayBuffer is not available in primordials because it can be + # disabled with --no-harmony-sharedarraybuffer CLI flag. + - name: SharedArrayBuffer + message: "Use `const { SharedArrayBuffer } = globalThis;` instead of the global." + - name: TextDecoder + message: "Use `const { TextDecoder } = require('internal/encoding');` instead of the global." + - name: TextEncoder + message: "Use `const { TextEncoder } = require('internal/encoding');` instead of the global." + - name: URL + message: "Use `const { URL } = require('internal/url');` instead of the global." + - name: URLSearchParams + message: "Use `const { URLSearchParams } = require('internal/url');` instead of the global." + # WebAssembly is not available in primordials because it can be + # disabled with --jitless CLI flag. + - name: WebAssembly + message: "Use `const { WebAssembly } = globalThis;` instead of the global." + - name: atob + message: "Use `const { atob } = require('buffer');` instead of the global." + - name: btoa + message: "Use `const { btoa } = require('buffer');` instead of the global." + - name: global + message: "Use `const { globalThis } = primordials;` instead of `global`." + - name: globalThis + message: "Use `const { globalThis } = primordials;` instead of the global." + - name: performance + message: "Use `const { performance } = require('perf_hooks');` instead of the global." + - name: queueMicrotask + message: "Use `const { queueMicrotask } = require('internal/process/task_queues');` instead of the global." # Custom rules in tools/eslint-rules node-core/lowercase-name-for-primitive: error node-core/non-ascii-character: error @@ -67,6 +121,7 @@ rules: into: Number - name: parseInt into: Number + - name: Proxy - name: Promise - name: RangeError - name: ReferenceError diff --git a/lib/child_process.js b/lib/child_process.js index 68fb8ddd3d254a..ceccbb499e3d8b 100644 --- a/lib/child_process.js +++ b/lib/child_process.js @@ -43,6 +43,7 @@ let debug = require('internal/util/debuglog').debuglog( debug = fn; } ); +const { AbortController } = require('internal/abort_controller'); const { Buffer } = require('buffer'); const { Pipe, constants: PipeConstants } = internalBinding('pipe_wrap'); diff --git a/lib/internal/bootstrap/node.js b/lib/internal/bootstrap/node.js index 2705f8b50a658d..718c9a6ac6491e 100644 --- a/lib/internal/bootstrap/node.js +++ b/lib/internal/bootstrap/node.js @@ -45,6 +45,7 @@ const { ObjectGetPrototypeOf, ObjectSetPrototypeOf, SymbolToStringTag, + globalThis, } = primordials; const config = internalBinding('config'); const { deprecate } = require('internal/util'); @@ -119,34 +120,35 @@ if (!config.noBrowserGlobals) { // Override global console from the one provided by the VM // to the one implemented by Node.js // https://console.spec.whatwg.org/#console-namespace - exposeNamespace(global, 'console', createGlobalConsole(global.console)); + exposeNamespace(globalThis, 'console', + createGlobalConsole(globalThis.console)); const { URL, URLSearchParams } = require('internal/url'); // https://url.spec.whatwg.org/#url - exposeInterface(global, 'URL', URL); + exposeInterface(globalThis, 'URL', URL); // https://url.spec.whatwg.org/#urlsearchparams - exposeInterface(global, 'URLSearchParams', URLSearchParams); + exposeInterface(globalThis, 'URLSearchParams', URLSearchParams); const { TextEncoder, TextDecoder } = require('internal/encoding'); // https://encoding.spec.whatwg.org/#textencoder - exposeInterface(global, 'TextEncoder', TextEncoder); + exposeInterface(globalThis, 'TextEncoder', TextEncoder); // https://encoding.spec.whatwg.org/#textdecoder - exposeInterface(global, 'TextDecoder', TextDecoder); + exposeInterface(globalThis, 'TextDecoder', TextDecoder); // https://html.spec.whatwg.org/multipage/webappapis.html#windoworworkerglobalscope const timers = require('timers'); - defineOperation(global, 'clearInterval', timers.clearInterval); - defineOperation(global, 'clearTimeout', timers.clearTimeout); - defineOperation(global, 'setInterval', timers.setInterval); - defineOperation(global, 'setTimeout', timers.setTimeout); + defineOperation(globalThis, 'clearInterval', timers.clearInterval); + defineOperation(globalThis, 'clearTimeout', timers.clearTimeout); + defineOperation(globalThis, 'setInterval', timers.setInterval); + defineOperation(globalThis, 'setTimeout', timers.setTimeout); - defineOperation(global, 'queueMicrotask', queueMicrotask); + defineOperation(globalThis, 'queueMicrotask', queueMicrotask); // Non-standard extensions: - defineOperation(global, 'clearImmediate', timers.clearImmediate); - defineOperation(global, 'setImmediate', timers.setImmediate); + defineOperation(globalThis, 'clearImmediate', timers.clearImmediate); + defineOperation(globalThis, 'setImmediate', timers.setImmediate); } // Set the per-Environment callback that will be called @@ -280,7 +282,7 @@ function setupProcessObject() { value: 'process' }); // Make process globally available to users by putting it on the global proxy - ObjectDefineProperty(global, 'process', { + ObjectDefineProperty(globalThis, 'process', { value: process, enumerable: false, writable: true, @@ -289,7 +291,7 @@ function setupProcessObject() { } function setupGlobalProxy() { - ObjectDefineProperty(global, SymbolToStringTag, { + ObjectDefineProperty(globalThis, SymbolToStringTag, { value: 'global', writable: false, enumerable: false, @@ -306,7 +308,7 @@ function setupBuffer() { delete bufferBinding.setBufferPrototype; delete bufferBinding.zeroFill; - ObjectDefineProperty(global, 'Buffer', { + ObjectDefineProperty(globalThis, 'Buffer', { value: Buffer, enumerable: false, writable: true, diff --git a/lib/internal/bootstrap/pre_execution.js b/lib/internal/bootstrap/pre_execution.js index dfd7249e907ebc..61f3aea190fd4c 100644 --- a/lib/internal/bootstrap/pre_execution.js +++ b/lib/internal/bootstrap/pre_execution.js @@ -7,6 +7,7 @@ const { SafeMap, SafeWeakMap, StringPrototypeStartsWith, + globalThis, } = primordials; const { @@ -290,7 +291,7 @@ function initializeDeprecations() { // deprecation path for these in ES Modules. // See https://github.com/nodejs/node/pull/26334. let _process = process; - ObjectDefineProperty(global, 'process', { + ObjectDefineProperty(globalThis, 'process', { get() { return _process; }, @@ -302,7 +303,7 @@ function initializeDeprecations() { }); let _Buffer = Buffer; - ObjectDefineProperty(global, 'Buffer', { + ObjectDefineProperty(globalThis, 'Buffer', { get() { return _Buffer; }, @@ -321,7 +322,7 @@ function initializeAbortController() { AbortController, AbortSignal } = require('internal/abort_controller'); - ObjectDefineProperties(global, { + ObjectDefineProperties(globalThis, { AbortController: { writable: true, enumerable: false, diff --git a/lib/internal/freeze_intrinsics.js b/lib/internal/freeze_intrinsics.js index 1e305cf6777b71..d4a72ccebabd55 100644 --- a/lib/internal/freeze_intrinsics.js +++ b/lib/internal/freeze_intrinsics.js @@ -19,7 +19,7 @@ // https://github.com/google/caja/blob/HEAD/src/com/google/caja/ses/repairES5.js // https://github.com/tc39/proposal-ses/blob/e5271cc42a257a05dcae2fd94713ed2f46c08620/shim/src/freeze.js -/* global WebAssembly, SharedArrayBuffer, console */ +/* global console */ 'use strict'; const { @@ -73,6 +73,7 @@ const { ObjectPrototypeHasOwnProperty, Promise, PromisePrototype, + Proxy, RangeError, RangeErrorPrototype, ReferenceError, @@ -111,8 +112,16 @@ const { decodeURIComponent, encodeURI, encodeURIComponent, + globalThis, } = primordials; +const { + Atomics, + Intl, + SharedArrayBuffer, + WebAssembly +} = globalThis; + module.exports = function() { const { clearImmediate, diff --git a/lib/internal/http2/compat.js b/lib/internal/http2/compat.js index 18e619b4746824..407b0ee30b79b8 100644 --- a/lib/internal/http2/compat.js +++ b/lib/internal/http2/compat.js @@ -7,6 +7,7 @@ const { ObjectCreate, ObjectKeys, ObjectPrototypeHasOwnProperty, + Proxy, ReflectGetPrototypeOf, Symbol, } = primordials; diff --git a/lib/internal/http2/core.js b/lib/internal/http2/core.js index 5e930ad216a1f5..91f4e143b4c77e 100644 --- a/lib/internal/http2/core.js +++ b/lib/internal/http2/core.js @@ -12,6 +12,7 @@ const { ObjectDefineProperty, ObjectPrototypeHasOwnProperty, Promise, + Proxy, ReflectApply, ReflectGet, ReflectGetPrototypeOf, diff --git a/lib/internal/main/eval_string.js b/lib/internal/main/eval_string.js index 124e4842308c55..ad068b935dfee0 100644 --- a/lib/internal/main/eval_string.js +++ b/lib/internal/main/eval_string.js @@ -3,6 +3,10 @@ // User passed `-e` or `--eval` arguments to Node without `-i` or // `--interactive`. +const { + globalThis, +} = primordials; + const { prepareMainThreadExecution } = require('internal/bootstrap/pre_execution'); @@ -12,7 +16,7 @@ const { addBuiltinLibsToObject } = require('internal/modules/cjs/helpers'); const { getOptionValue } = require('internal/options'); prepareMainThreadExecution(); -addBuiltinLibsToObject(global); +addBuiltinLibsToObject(globalThis); markBootstrapComplete(); const source = getOptionValue('--eval'); diff --git a/lib/internal/main/worker_thread.js b/lib/internal/main/worker_thread.js index 3528ebccfdba35..e6bc341c33e35d 100644 --- a/lib/internal/main/worker_thread.js +++ b/lib/internal/main/worker_thread.js @@ -9,6 +9,7 @@ const { ArrayPrototypeSplice, ObjectDefineProperty, PromisePrototypeCatch, + globalThis: { Atomics }, } = primordials; const { diff --git a/lib/internal/modules/cjs/loader.js b/lib/internal/modules/cjs/loader.js index 7c006042a0c04d..1a0eb587206401 100644 --- a/lib/internal/modules/cjs/loader.js +++ b/lib/internal/modules/cjs/loader.js @@ -44,6 +44,7 @@ const { ObjectPrototype, ObjectPrototypeHasOwnProperty, ObjectSetPrototypeOf, + Proxy, ReflectApply, ReflectSet, RegExpPrototypeTest, diff --git a/lib/internal/modules/esm/loader.js b/lib/internal/modules/esm/loader.js index 14e66dcb9fdf62..8b2c89ba130aa7 100644 --- a/lib/internal/modules/esm/loader.js +++ b/lib/internal/modules/esm/loader.js @@ -9,6 +9,7 @@ const { RegExpPrototypeExec, SafeWeakMap, StringPrototypeStartsWith, + globalThis, } = primordials; const { diff --git a/lib/internal/modules/esm/translators.js b/lib/internal/modules/esm/translators.js index 66636d9ce092b5..0a43113a065bdf 100644 --- a/lib/internal/modules/esm/translators.js +++ b/lib/internal/modules/esm/translators.js @@ -1,7 +1,5 @@ 'use strict'; -/* global WebAssembly */ - const { ArrayPrototypeMap, Boolean, @@ -19,6 +17,7 @@ const { StringPrototypeSplit, StringPrototypeStartsWith, SyntaxErrorPrototype, + globalThis: { WebAssembly }, } = primordials; let _TYPES = null; @@ -61,6 +60,7 @@ const experimentalImportMetaResolve = getOptionValue('--experimental-import-meta-resolve'); const asyncESM = require('internal/process/esm_loader'); const { emitWarningSync } = require('internal/process/warning'); +const { TextDecoder } = require('internal/encoding'); let cjsParse; async function initCJSParse() { diff --git a/lib/internal/per_context/primordials.js b/lib/internal/per_context/primordials.js index 6492da782a9edb..a4ea444ef7d832 100644 --- a/lib/internal/per_context/primordials.js +++ b/lib/internal/per_context/primordials.js @@ -171,6 +171,15 @@ primordials.SafeWeakSet = makeSafe( } ); +// Create copies of configurable value properties of the global object +[ + 'Proxy', + 'globalThis', +].forEach((name) => { + // eslint-disable-next-line no-restricted-globals + primordials[name] = globalThis[name]; +}); + // Create copies of URI handling functions [ decodeURI, @@ -185,8 +194,10 @@ primordials.SafeWeakSet = makeSafe( [ 'JSON', 'Math', - 'Reflect' + 'Proxy', + 'Reflect', ].forEach((name) => { + // eslint-disable-next-line no-restricted-globals copyPropsRenamed(global[name], primordials, name); }); @@ -227,6 +238,7 @@ primordials.SafeWeakSet = makeSafe( 'WeakMap', 'WeakSet', ].forEach((name) => { + // eslint-disable-next-line no-restricted-globals const original = global[name]; primordials[name] = original; copyPropsRenamed(original, primordials, name); @@ -239,6 +251,7 @@ primordials.SafeWeakSet = makeSafe( [ 'Promise', ].forEach((name) => { + // eslint-disable-next-line no-restricted-globals const original = global[name]; primordials[name] = original; copyPropsRenamedBound(original, primordials, name); diff --git a/lib/internal/process/execution.js b/lib/internal/process/execution.js index 314b8b0a03c161..e370770643ca6f 100644 --- a/lib/internal/process/execution.js +++ b/lib/internal/process/execution.js @@ -1,5 +1,9 @@ 'use strict'; +const { + globalThis, +} = primordials; + const path = require('path'); const { diff --git a/lib/internal/test/binding.js b/lib/internal/test/binding.js index 063b9b5c900aad..d00ef89a16111b 100644 --- a/lib/internal/test/binding.js +++ b/lib/internal/test/binding.js @@ -1,5 +1,9 @@ 'use strict'; +const { + globalThis, +} = primordials; + process.emitWarning( 'These APIs are for internal testing only. Do not use them.', 'internal/test/binding'); diff --git a/lib/internal/util/inspect.js b/lib/internal/util/inspect.js index 14b4e54e4f4157..e8728370cd1e6c 100644 --- a/lib/internal/util/inspect.js +++ b/lib/internal/util/inspect.js @@ -3,6 +3,7 @@ const { Array, ArrayIsArray, + ArrayPrototypeFilter, BigIntPrototypeValueOf, BooleanPrototypeValueOf, DatePrototypeGetTime, @@ -41,7 +42,9 @@ const { ObjectSetPrototypeOf, ReflectApply, RegExp, + RegExpPrototypeExec, RegExpPrototypeToString, + SafeSet, SafeStringIterator, Set, SetPrototypeGetSize, @@ -55,6 +58,7 @@ const { TypedArrayPrototypeGetLength, TypedArrayPrototypeGetSymbolToStringTag, Uint8Array, + globalThis, uncurryThis, } = primordials; @@ -120,8 +124,11 @@ const { NativeModule } = require('internal/bootstrap/loaders'); let hexSlice; -const builtInObjects = new Set( - ObjectGetOwnPropertyNames(global).filter((e) => /^[A-Z][a-zA-Z0-9]+$/.test(e)) +const builtInObjects = new SafeSet( + ArrayPrototypeFilter( + ObjectGetOwnPropertyNames(globalThis), + (e) => RegExpPrototypeExec(/^[A-Z][a-zA-Z0-9]+$/, e) !== null + ) ); // https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot diff --git a/lib/internal/util/iterable_weak_map.js b/lib/internal/util/iterable_weak_map.js index 464ba74281127b..06d0001970635f 100644 --- a/lib/internal/util/iterable_weak_map.js +++ b/lib/internal/util/iterable_weak_map.js @@ -6,6 +6,7 @@ const { SafeSet, SafeWeakMap, SymbolIterator, + globalThis, } = primordials; // TODO(aduh95): Add FinalizationRegistry to primordials diff --git a/lib/internal/v8_prof_polyfill.js b/lib/internal/v8_prof_polyfill.js index ae98a03ab206d8..369da5f9a34741 100644 --- a/lib/internal/v8_prof_polyfill.js +++ b/lib/internal/v8_prof_polyfill.js @@ -28,7 +28,7 @@ 'use strict'; /* eslint-disable node-core/prefer-primordials */ -/* global Buffer, console */ +/* global console */ module.exports = { versionCheck }; @@ -40,6 +40,7 @@ if (module.id === 'internal/v8_prof_polyfill') return; // Node polyfill const fs = require('fs'); const cp = require('child_process'); +const { Buffer } = require('buffer'); const os = { // eslint-disable-line no-unused-vars system: function(name, args) { if (process.platform === 'linux' && name === 'nm') { diff --git a/lib/internal/worker.js b/lib/internal/worker.js index 0965c5690fd06b..73aa910b0b77ce 100644 --- a/lib/internal/worker.js +++ b/lib/internal/worker.js @@ -1,7 +1,5 @@ 'use strict'; -/* global SharedArrayBuffer */ - const { ArrayIsArray, ArrayPrototypeMap, @@ -20,6 +18,7 @@ const { SymbolFor, TypedArrayPrototypeFill, Uint32Array, + globalThis: { Atomics, SharedArrayBuffer }, } = primordials; const EventEmitter = require('events'); diff --git a/lib/repl.js b/lib/repl.js index 1ec438e5210e49..cfcbf126ee8cf0 100644 --- a/lib/repl.js +++ b/lib/repl.js @@ -43,6 +43,7 @@ 'use strict'; const { + ArrayPrototypeForEach, Error, MathMax, NumberIsNaN, @@ -67,6 +68,7 @@ const { SyntaxError, SyntaxErrorPrototype, WeakSet, + globalThis, } = primordials; const { @@ -984,7 +986,7 @@ REPLServer.prototype.close = function close() { REPLServer.prototype.createContext = function() { let context; if (this.useGlobal) { - context = global; + context = globalThis; } else { sendInspectorCommand((session) => { session.post('Runtime.enable'); @@ -996,13 +998,13 @@ REPLServer.prototype.createContext = function() { }, () => { context = vm.createContext(); }); - for (const name of ObjectGetOwnPropertyNames(global)) { + ArrayPrototypeForEach(ObjectGetOwnPropertyNames(globalThis), (name) => { // Only set properties that do not already exist as a global builtin. if (!globalBuiltins.has(name)) { ObjectDefineProperty(context, name, - ObjectGetOwnPropertyDescriptor(global, name)); + ObjectGetOwnPropertyDescriptor(globalThis, name)); } - } + }); context.global = context; const _console = new Console(this.output); ObjectDefineProperty(context, 'console', {