node/lib/internal/util.js
Antoine du Hamel 94be10ac32
util: do not mark experimental feature as deprecated
PR-URL: https://github.com/nodejs/node/pull/55740
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
Reviewed-By: Chemi Atlow <chemi@atlow.co.il>
Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com>
2024-11-08 16:16:15 +00:00

946 lines
26 KiB
JavaScript

'use strict';
const {
ArrayFrom,
ArrayPrototypePush,
ArrayPrototypeSlice,
ArrayPrototypeSort,
Error,
ErrorCaptureStackTrace,
FunctionPrototypeCall,
ObjectDefineProperties,
ObjectDefineProperty,
ObjectFreeze,
ObjectGetOwnPropertyDescriptor,
ObjectGetOwnPropertyDescriptors,
ObjectGetPrototypeOf,
ObjectPrototypeHasOwnProperty,
ObjectSetPrototypeOf,
ObjectValues,
Promise,
ReflectApply,
ReflectConstruct,
RegExpPrototypeExec,
RegExpPrototypeGetDotAll,
RegExpPrototypeGetGlobal,
RegExpPrototypeGetHasIndices,
RegExpPrototypeGetIgnoreCase,
RegExpPrototypeGetMultiline,
RegExpPrototypeGetSource,
RegExpPrototypeGetSticky,
RegExpPrototypeGetUnicode,
SafeMap,
SafeSet,
SafeWeakMap,
SafeWeakRef,
StringPrototypeReplace,
StringPrototypeToLowerCase,
StringPrototypeToUpperCase,
Symbol,
SymbolFor,
SymbolReplace,
SymbolSplit,
} = primordials;
const {
codes: {
ERR_NO_CRYPTO,
ERR_NO_TYPESCRIPT,
ERR_UNKNOWN_SIGNAL,
},
isErrorStackTraceLimitWritable,
overrideStackTrace,
uvErrmapGet,
} = require('internal/errors');
const { signals } = internalBinding('constants').os;
const {
guessHandleType: _guessHandleType,
privateSymbols: {
arrow_message_private_symbol,
decorated_private_symbol,
},
sleep: _sleep,
} = internalBinding('util');
const { isNativeError, isPromise } = internalBinding('types');
const { getOptionValue } = require('internal/options');
const assert = require('internal/assert');
const { encodings } = internalBinding('string_decoder');
const noCrypto = !process.versions.openssl;
const noTypeScript = !process.versions.amaro;
const isWindows = process.platform === 'win32';
const isMacOS = process.platform === 'darwin';
const experimentalWarnings = new SafeSet();
const colorRegExp = /\u001b\[\d\d?m/g; // eslint-disable-line no-control-regex
let uvBinding;
function lazyUv() {
uvBinding ??= internalBinding('uv');
return uvBinding;
}
function removeColors(str) {
return StringPrototypeReplace(str, colorRegExp, '');
}
function isError(e) {
// An error could be an instance of Error while not being a native error
// or could be from a different realm and not be instance of Error but still
// be a native error.
return isNativeError(e) || e instanceof Error;
}
// Keep a list of deprecation codes that have been warned on so we only warn on
// each one once.
const codesWarned = new SafeSet();
let validateString;
function getDeprecationWarningEmitter(
code, msg, deprecated, useEmitSync,
shouldEmitWarning = () => true,
) {
let warned = false;
return function() {
if (!warned && shouldEmitWarning()) {
warned = true;
if (code === 'ExperimentalWarning') {
process.emitWarning(msg, code, deprecated);
} else if (code !== undefined) {
if (!codesWarned.has(code)) {
const emitWarning = useEmitSync ?
require('internal/process/warning').emitWarningSync :
process.emitWarning;
emitWarning(msg, 'DeprecationWarning', code, deprecated);
codesWarned.add(code);
}
} else {
process.emitWarning(msg, 'DeprecationWarning', deprecated);
}
}
};
}
function isPendingDeprecation() {
return getOptionValue('--pending-deprecation') &&
!getOptionValue('--no-deprecation');
}
// Internal deprecator for pending --pending-deprecation. This can be invoked
// at snapshot building time as the warning permission is only queried at
// run time.
function pendingDeprecate(fn, msg, code) {
const emitDeprecationWarning = getDeprecationWarningEmitter(
code, msg, deprecated, false, isPendingDeprecation,
);
function deprecated(...args) {
emitDeprecationWarning();
return ReflectApply(fn, this, args);
}
return deprecated;
}
// Mark that a method should not be used.
// Returns a modified function which warns once by default.
// If --no-deprecation is set, then it is a no-op.
function deprecate(fn, msg, code, useEmitSync) {
// Lazy-load to avoid a circular dependency.
if (validateString === undefined)
({ validateString } = require('internal/validators'));
if (code !== undefined)
validateString(code, 'code');
const emitDeprecationWarning = getDeprecationWarningEmitter(
code, msg, deprecated, useEmitSync,
);
function deprecated(...args) {
// TODO(joyeecheung): use getOptionValue('--no-deprecation') instead.
if (!process.noDeprecation) {
emitDeprecationWarning();
}
if (new.target) {
return ReflectConstruct(fn, args, new.target);
}
return ReflectApply(fn, this, args);
}
// The wrapper will keep the same prototype as fn to maintain prototype chain
ObjectSetPrototypeOf(deprecated, fn);
if (fn.prototype) {
// Setting this (rather than using Object.setPrototype, as above) ensures
// that calling the unwrapped constructor gives an instanceof the wrapped
// constructor.
deprecated.prototype = fn.prototype;
}
return deprecated;
}
function deprecateInstantiation(target, code, ...args) {
assert(typeof code === 'string');
getDeprecationWarningEmitter(code, `Instantiating ${target.name} without the 'new' keyword has been deprecated.`, target)();
return ReflectConstruct(target, args);
}
function decorateErrorStack(err) {
if (!(isError(err) && err.stack) || err[decorated_private_symbol])
return;
const arrow = err[arrow_message_private_symbol];
if (arrow) {
err.stack = arrow + err.stack;
err[decorated_private_symbol] = true;
}
}
function assertCrypto() {
if (noCrypto)
throw new ERR_NO_CRYPTO();
}
function assertTypeScript() {
if (noTypeScript)
throw new ERR_NO_TYPESCRIPT();
}
/**
* Move the "slow cases" to a separate function to make sure this function gets
* inlined properly. That prioritizes the common case.
* @param {unknown} enc
* @returns {string | undefined} Returns undefined if there is no match.
*/
function normalizeEncoding(enc) {
if (enc == null || enc === 'utf8' || enc === 'utf-8') return 'utf8';
return slowCases(enc);
}
function slowCases(enc) {
switch (enc.length) {
case 4:
if (enc === 'UTF8') return 'utf8';
if (enc === 'ucs2' || enc === 'UCS2') return 'utf16le';
enc = StringPrototypeToLowerCase(enc);
if (enc === 'utf8') return 'utf8';
if (enc === 'ucs2') return 'utf16le';
break;
case 3:
if (enc === 'hex' || enc === 'HEX' ||
StringPrototypeToLowerCase(enc) === 'hex')
return 'hex';
break;
case 5:
if (enc === 'ascii') return 'ascii';
if (enc === 'ucs-2') return 'utf16le';
if (enc === 'UTF-8') return 'utf8';
if (enc === 'ASCII') return 'ascii';
if (enc === 'UCS-2') return 'utf16le';
enc = StringPrototypeToLowerCase(enc);
if (enc === 'utf-8') return 'utf8';
if (enc === 'ascii') return 'ascii';
if (enc === 'ucs-2') return 'utf16le';
break;
case 6:
if (enc === 'base64') return 'base64';
if (enc === 'latin1' || enc === 'binary') return 'latin1';
if (enc === 'BASE64') return 'base64';
if (enc === 'LATIN1' || enc === 'BINARY') return 'latin1';
enc = StringPrototypeToLowerCase(enc);
if (enc === 'base64') return 'base64';
if (enc === 'latin1' || enc === 'binary') return 'latin1';
break;
case 7:
if (enc === 'utf16le' || enc === 'UTF16LE' ||
StringPrototypeToLowerCase(enc) === 'utf16le')
return 'utf16le';
break;
case 8:
if (enc === 'utf-16le' || enc === 'UTF-16LE' ||
StringPrototypeToLowerCase(enc) === 'utf-16le')
return 'utf16le';
break;
case 9:
if (enc === 'base64url' || enc === 'BASE64URL' ||
StringPrototypeToLowerCase(enc) === 'base64url')
return 'base64url';
break;
default:
if (enc === '') return 'utf8';
}
}
/**
* @param {string} feature Feature name used in the warning message
* @param {string} messagePrefix Prefix of the warning message
* @param {string} code See documentation of process.emitWarning
* @param {string} ctor See documentation of process.emitWarning
*/
function emitExperimentalWarning(feature, messagePrefix, code, ctor) {
if (experimentalWarnings.has(feature)) return;
experimentalWarnings.add(feature);
let msg = `${feature} is an experimental feature and might change at any time`;
if (messagePrefix) {
msg = messagePrefix + msg;
}
process.emitWarning(msg, 'ExperimentalWarning', code, ctor);
}
function filterDuplicateStrings(items, low) {
const map = new SafeMap();
for (let i = 0; i < items.length; i++) {
const item = items[i];
const key = StringPrototypeToLowerCase(item);
if (low) {
map.set(key, key);
} else {
map.set(key, item);
}
}
return ArrayPrototypeSort(ArrayFrom(map.values()));
}
function cachedResult(fn) {
let result;
return () => {
if (result === undefined)
result = fn();
return ArrayPrototypeSlice(result);
};
}
// Useful for Wrapping an ES6 Class with a constructor Function that
// does not require the new keyword. For instance:
// class A { constructor(x) {this.x = x;}}
// const B = createClassWrapper(A);
// B() instanceof A // true
// B() instanceof B // true
function createClassWrapper(type) {
function fn(...args) {
return ReflectConstruct(type, args, new.target || type);
}
// Mask the wrapper function name and length values
ObjectDefineProperties(fn, {
name: { __proto__: null, value: type.name },
length: { __proto__: null, value: type.length },
});
ObjectSetPrototypeOf(fn, type);
fn.prototype = type.prototype;
return fn;
}
let signalsToNamesMapping;
function getSignalsToNamesMapping() {
if (signalsToNamesMapping !== undefined)
return signalsToNamesMapping;
signalsToNamesMapping = { __proto__: null };
for (const key in signals) {
signalsToNamesMapping[signals[key]] = key;
}
return signalsToNamesMapping;
}
function convertToValidSignal(signal) {
if (typeof signal === 'number' && getSignalsToNamesMapping()[signal])
return signal;
if (typeof signal === 'string') {
const signalName = signals[StringPrototypeToUpperCase(signal)];
if (signalName) return signalName;
}
throw new ERR_UNKNOWN_SIGNAL(signal);
}
function getConstructorOf(obj) {
while (obj) {
const descriptor = ObjectGetOwnPropertyDescriptor(obj, 'constructor');
if (descriptor !== undefined &&
typeof descriptor.value === 'function' &&
descriptor.value.name !== '') {
return descriptor.value;
}
obj = ObjectGetPrototypeOf(obj);
}
return null;
}
let cachedURL;
let cachedCWD;
/**
* Get the current working directory while accounting for the possibility that it has been deleted.
* `process.cwd()` can fail if the parent directory is deleted while the process runs.
* @returns {URL} The current working directory or the volume root if it cannot be determined.
*/
function getCWDURL() {
const { sep } = require('path');
const { pathToFileURL } = require('internal/url');
let cwd;
try {
// The implementation of `process.cwd()` already uses proper cache when it can.
// It's a relatively cheap call performance-wise for the most common use case.
cwd = process.cwd();
} catch {
cachedURL ??= pathToFileURL(sep);
}
if (cwd != null && cwd !== cachedCWD) {
cachedURL = pathToFileURL(cwd + sep);
cachedCWD = cwd;
}
return cachedURL;
}
function getSystemErrorMessage(err) {
return lazyUv().getErrorMessage(err);
}
function getSystemErrorName(err) {
const entry = uvErrmapGet(err);
return entry ? entry[0] : `Unknown system error ${err}`;
}
function getSystemErrorMap() {
return lazyUv().getErrorMap();
}
const kCustomPromisifiedSymbol = SymbolFor('nodejs.util.promisify.custom');
const kCustomPromisifyArgsSymbol = Symbol('customPromisifyArgs');
let validateFunction;
function promisify(original) {
// Lazy-load to avoid a circular dependency.
if (validateFunction === undefined)
({ validateFunction } = require('internal/validators'));
validateFunction(original, 'original');
if (original[kCustomPromisifiedSymbol]) {
const fn = original[kCustomPromisifiedSymbol];
validateFunction(fn, 'util.promisify.custom');
return ObjectDefineProperty(fn, kCustomPromisifiedSymbol, {
__proto__: null,
value: fn, enumerable: false, writable: false, configurable: true,
});
}
// Names to create an object from in case the callback receives multiple
// arguments, e.g. ['bytesRead', 'buffer'] for fs.read.
const argumentNames = original[kCustomPromisifyArgsSymbol];
function fn(...args) {
return new Promise((resolve, reject) => {
ArrayPrototypePush(args, (err, ...values) => {
if (err) {
return reject(err);
}
if (argumentNames !== undefined && values.length > 1) {
const obj = {};
for (let i = 0; i < argumentNames.length; i++)
obj[argumentNames[i]] = values[i];
resolve(obj);
} else {
resolve(values[0]);
}
});
if (isPromise(ReflectApply(original, this, args))) {
process.emitWarning('Calling promisify on a function that returns a Promise is likely a mistake.',
'DeprecationWarning', 'DEP0174');
}
});
}
ObjectSetPrototypeOf(fn, ObjectGetPrototypeOf(original));
ObjectDefineProperty(fn, kCustomPromisifiedSymbol, {
__proto__: null,
value: fn, enumerable: false, writable: false, configurable: true,
});
const descriptors = ObjectGetOwnPropertyDescriptors(original);
const propertiesValues = ObjectValues(descriptors);
for (let i = 0; i < propertiesValues.length; i++) {
// We want to use null-prototype objects to not rely on globally mutable
// %Object.prototype%.
ObjectSetPrototypeOf(propertiesValues[i], null);
}
return ObjectDefineProperties(fn, descriptors);
}
promisify.custom = kCustomPromisifiedSymbol;
// The built-in Array#join is slower in v8 6.0
function join(output, separator) {
let str = '';
if (output.length !== 0) {
const lastIndex = output.length - 1;
for (let i = 0; i < lastIndex; i++) {
// It is faster not to use a template string here
str += output[i];
str += separator;
}
str += output[lastIndex];
}
return str;
}
// As of V8 6.6, depending on the size of the array, this is anywhere
// between 1.5-10x faster than the two-arg version of Array#splice()
function spliceOne(list, index) {
for (; index + 1 < list.length; index++)
list[index] = list[index + 1];
list.pop();
}
const kNodeModulesRE = /^(?:.*)[\\/]node_modules[\\/]/;
function isUnderNodeModules(filename) {
return filename && (RegExpPrototypeExec(kNodeModulesRE, filename) !== null);
}
let getStructuredStackImpl;
function lazyGetStructuredStack() {
if (getStructuredStackImpl === undefined) {
// Lazy-load to avoid a circular dependency.
const { runInNewContext } = require('vm');
// Use `runInNewContext()` to get something tamper-proof and
// side-effect-free. Since this is currently only used for a deprecated API
// and module mocking, the perf implications should be okay.
getStructuredStackImpl = runInNewContext(`(function() {
try { Error.stackTraceLimit = Infinity; } catch {}
return function structuredStack() {
const e = new Error();
overrideStackTrace.set(e, (err, trace) => trace);
return e.stack;
};
})()`, { overrideStackTrace }, { filename: 'structured-stack' });
}
return getStructuredStackImpl;
}
function getStructuredStack() {
const getStructuredStackImpl = lazyGetStructuredStack();
return getStructuredStackImpl();
}
function once(callback, { preserveReturnValue = false } = kEmptyObject) {
let called = false;
let returnValue;
return function(...args) {
if (called) return returnValue;
called = true;
const result = ReflectApply(callback, this, args);
returnValue = preserveReturnValue ? result : undefined;
return result;
};
}
let validateUint32;
function sleep(msec) {
// Lazy-load to avoid a circular dependency.
if (validateUint32 === undefined)
({ validateUint32 } = require('internal/validators'));
validateUint32(msec, 'msec');
_sleep(msec);
}
// https://heycam.github.io/webidl/#define-the-operations
function defineOperation(target, name, method) {
ObjectDefineProperty(target, name, {
__proto__: null,
writable: true,
enumerable: true,
configurable: true,
value: method,
});
}
// https://heycam.github.io/webidl/#es-interfaces
function exposeInterface(target, name, interfaceObject) {
ObjectDefineProperty(target, name, {
__proto__: null,
writable: true,
enumerable: false,
configurable: true,
value: interfaceObject,
});
}
// https://heycam.github.io/webidl/#es-namespaces
function exposeNamespace(target, name, namespaceObject) {
ObjectDefineProperty(target, name, {
__proto__: null,
writable: true,
enumerable: false,
configurable: true,
value: namespaceObject,
});
}
function exposeGetterAndSetter(target, name, getter, setter = undefined) {
ObjectDefineProperty(target, name, {
__proto__: null,
enumerable: false,
configurable: true,
get: getter,
set: setter,
});
}
function defineLazyProperties(target, id, keys, enumerable = true) {
const descriptors = { __proto__: null };
let mod;
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
let lazyLoadedValue;
function set(value) {
ObjectDefineProperty(target, key, {
__proto__: null,
writable: true,
value,
});
}
ObjectDefineProperty(set, 'name', {
__proto__: null,
value: `set ${key}`,
});
function get() {
mod ??= require(id);
if (lazyLoadedValue === undefined) {
lazyLoadedValue = mod[key];
set(lazyLoadedValue);
}
return lazyLoadedValue;
}
ObjectDefineProperty(get, 'name', {
__proto__: null,
value: `get ${key}`,
});
descriptors[key] = {
__proto__: null,
configurable: true,
enumerable,
get,
set,
};
}
ObjectDefineProperties(target, descriptors);
}
function defineReplaceableLazyAttribute(target, id, keys, writable = true, check) {
let mod;
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
let value;
let setterCalled = false;
function get() {
if (check !== undefined) {
FunctionPrototypeCall(check, this);
}
if (setterCalled) {
return value;
}
mod ??= require(id);
value ??= mod[key];
return value;
}
ObjectDefineProperty(get, 'name', {
__proto__: null,
value: `get ${key}`,
});
function set(val) {
setterCalled = true;
value = val;
}
ObjectDefineProperty(set, 'name', {
__proto__: null,
value: `set ${key}`,
});
ObjectDefineProperty(target, key, {
__proto__: null,
enumerable: true,
configurable: true,
get,
set: writable ? set : undefined,
});
}
}
function exposeLazyInterfaces(target, id, keys) {
defineLazyProperties(target, id, keys, false);
}
let _DOMException;
const lazyDOMExceptionClass = () => {
_DOMException ??= internalBinding('messaging').DOMException;
return _DOMException;
};
const lazyDOMException = (message, name) => {
_DOMException ??= internalBinding('messaging').DOMException;
if (isErrorStackTraceLimitWritable()) {
const limit = Error.stackTraceLimit;
Error.stackTraceLimit = 0;
const ex = new _DOMException(message, name);
Error.stackTraceLimit = limit;
ErrorCaptureStackTrace(ex, lazyDOMException);
return ex;
}
return new _DOMException(message, name);
};
const kEnumerableProperty = { __proto__: null };
kEnumerableProperty.enumerable = true;
ObjectFreeze(kEnumerableProperty);
const kEmptyObject = ObjectFreeze({ __proto__: null });
function filterOwnProperties(source, keys) {
const filtered = { __proto__: null };
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
if (ObjectPrototypeHasOwnProperty(source, key)) {
filtered[key] = source[key];
}
}
return filtered;
}
/**
* Mimics `obj[key] = value` but ignoring potential prototype inheritance.
* @param {any} obj
* @param {string} key
* @param {any} value
* @returns {any}
*/
function setOwnProperty(obj, key, value) {
return ObjectDefineProperty(obj, key, {
__proto__: null,
configurable: true,
enumerable: true,
value,
writable: true,
});
}
let internalGlobal;
function getInternalGlobal() {
if (internalGlobal == null) {
// Lazy-load to avoid a circular dependency.
const { runInNewContext } = require('vm');
internalGlobal = runInNewContext('this', undefined, { contextName: 'internal' });
}
return internalGlobal;
}
function SideEffectFreeRegExpPrototypeExec(regex, string) {
const { RegExp: RegExpFromAnotherRealm } = getInternalGlobal();
return FunctionPrototypeCall(RegExpFromAnotherRealm.prototype.exec, regex, string);
}
const crossRealmRegexes = new SafeWeakMap();
function getCrossRealmRegex(regex) {
const cached = crossRealmRegexes.get(regex);
if (cached) return cached;
let flagString = '';
if (RegExpPrototypeGetHasIndices(regex)) flagString += 'd';
if (RegExpPrototypeGetGlobal(regex)) flagString += 'g';
if (RegExpPrototypeGetIgnoreCase(regex)) flagString += 'i';
if (RegExpPrototypeGetMultiline(regex)) flagString += 'm';
if (RegExpPrototypeGetDotAll(regex)) flagString += 's';
if (RegExpPrototypeGetUnicode(regex)) flagString += 'u';
if (RegExpPrototypeGetSticky(regex)) flagString += 'y';
const { RegExp: RegExpFromAnotherRealm } = getInternalGlobal();
const crossRealmRegex = new RegExpFromAnotherRealm(RegExpPrototypeGetSource(regex), flagString);
crossRealmRegexes.set(regex, crossRealmRegex);
return crossRealmRegex;
}
function SideEffectFreeRegExpPrototypeSymbolReplace(regex, string, replacement) {
return getCrossRealmRegex(regex)[SymbolReplace](string, replacement);
}
function SideEffectFreeRegExpPrototypeSymbolSplit(regex, string, limit = undefined) {
return getCrossRealmRegex(regex)[SymbolSplit](string, limit);
}
/**
* Helper function to lazy-load an initialize-once value.
* @template T Return value of initializer
* @param {()=>T} initializer Initializer of the lazily loaded value.
* @returns {()=>T}
*/
function getLazy(initializer) {
let value;
let initialized = false;
return function() {
if (initialized === false) {
value = initializer();
initialized = true;
}
return value;
};
}
// Setup user-facing NODE_V8_COVERAGE environment variable that writes
// ScriptCoverage objects to a specified directory.
function setupCoverageHooks(dir) {
const cwd = require('internal/process/execution').tryGetCwd();
const { resolve } = require('path');
const coverageDirectory = resolve(cwd, dir);
const { sourceMapCacheToObject } =
require('internal/source_map/source_map_cache');
if (process.features.inspector) {
internalBinding('profiler').setCoverageDirectory(coverageDirectory);
internalBinding('profiler').setSourceMapCacheGetter(sourceMapCacheToObject);
} else {
process.emitWarning('The inspector is disabled, ' +
'coverage could not be collected',
'Warning');
return '';
}
return coverageDirectory;
}
const handleTypes = ['TCP', 'TTY', 'UDP', 'FILE', 'PIPE', 'UNKNOWN'];
function guessHandleType(fd) {
const type = _guessHandleType(fd);
return handleTypes[type];
}
class WeakReference {
#weak = null;
// eslint-disable-next-line no-unused-private-class-members
#strong = null;
#refCount = 0;
constructor(object) {
this.#weak = new SafeWeakRef(object);
}
incRef() {
this.#refCount++;
if (this.#refCount === 1) {
const derefed = this.#weak.deref();
if (derefed !== undefined) {
this.#strong = derefed;
}
}
return this.#refCount;
}
decRef() {
this.#refCount--;
if (this.#refCount === 0) {
this.#strong = null;
}
return this.#refCount;
}
get() {
return this.#weak.deref();
}
}
const encodingsMap = { __proto__: null };
for (let i = 0; i < encodings.length; ++i)
encodingsMap[encodings[i]] = i;
module.exports = {
getLazy,
assertCrypto,
assertTypeScript,
cachedResult,
convertToValidSignal,
createClassWrapper,
decorateErrorStack,
defineOperation,
defineLazyProperties,
defineReplaceableLazyAttribute,
deprecate,
deprecateInstantiation,
emitExperimentalWarning,
encodingsMap,
exposeInterface,
exposeLazyInterfaces,
exposeNamespace,
exposeGetterAndSetter,
filterDuplicateStrings,
filterOwnProperties,
getConstructorOf,
getCWDURL,
getInternalGlobal,
getStructuredStack,
getSystemErrorMap,
getSystemErrorName,
getSystemErrorMessage,
guessHandleType,
isError,
isUnderNodeModules,
isMacOS,
isWindows,
join,
lazyDOMException,
lazyDOMExceptionClass,
normalizeEncoding,
once,
promisify,
SideEffectFreeRegExpPrototypeExec,
SideEffectFreeRegExpPrototypeSymbolReplace,
SideEffectFreeRegExpPrototypeSymbolSplit,
sleep,
spliceOne,
setupCoverageHooks,
removeColors,
// Symbol used to customize promisify conversion
customPromisifyArgs: kCustomPromisifyArgsSymbol,
// Symbol used to provide a custom inspect function for an object as an
// alternative to using 'inspect'
customInspectSymbol: SymbolFor('nodejs.util.inspect.custom'),
// Used by the buffer module to capture an internal reference to the
// default isEncoding implementation, just in case userland overrides it.
kIsEncodingSymbol: Symbol('kIsEncodingSymbol'),
kVmBreakFirstLineSymbol: Symbol('kVmBreakFirstLineSymbol'),
kEmptyObject,
kEnumerableProperty,
setOwnProperty,
pendingDeprecate,
WeakReference,
};