/
githubmirror
/
deno
Обзор
Документация
Войти
/
githubmirror
/
deno
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
ext/node/polyfills/01_require.js
3 500 строк
110 KB
Bartek Iwańczuk
chore: bump node_compat test suite to Node.js 26.5.1 (#36391)
03 авг 2026, 12:52
Не верифицирован
03 авг 2026, 12:52
bca6182
Код
Авторство
О чём код?
// Copyright 2018-2026 the Deno authors. MIT license. // deno-lint-ignore-file import { core, internals, primordials } from "ext:core/mod.js"; import { op_fs_cwd, op_get_env_no_permission_check, op_import_sync, op_import_sync_with_source, op_module_default_resolve, op_module_hooks_poll_load, op_module_hooks_register, op_module_hooks_respond_load, op_napi_open, op_node_has_child_ipc_pipe, op_node_strip_typescript_types, op_require_as_file_path, op_require_break_on_next_statement, op_require_can_parse_as_esm, op_require_init_paths, op_require_is_deno_dir_package, op_require_is_maybe_cjs, op_require_is_request_relative, op_require_node_module_paths, op_require_package_imports_resolve, op_require_path_basename, op_require_path_dirname, op_require_path_is_absolute, op_require_path_resolve, op_require_proxy_path, op_require_read_file, op_require_read_package_scope, op_require_real_path, op_require_resolve_deno_dir, op_require_resolve_exports, op_require_resolve_lookup_paths, op_require_stat, op_require_try_self, } from "ext:core/ops"; const { ArrayIsArray, ArrayPrototypeIncludes, ArrayPrototypeIndexOf, ArrayPrototypeJoin, ArrayPrototypeMap, ArrayPrototypePush, ArrayPrototypeSlice, ArrayPrototypeSort, ArrayPrototypeSplice, Error, JSONParse, ObjectCreate, ObjectDefineProperty, ObjectEntries, ObjectGetOwnPropertyDescriptor, ObjectGetPrototypeOf, ObjectHasOwn, ObjectKeys, ObjectPrototype, ObjectSetPrototypeOf, Proxy, ReflectSet, RegExpPrototypeExec, RegExpPrototypeTest, SafeArrayIterator, SafeMap, SafeSet, SafeWeakMap, SetPrototypeAdd, SetPrototypeDelete, SetPrototypeHas, String, StringPrototypeCharCodeAt, StringPrototypeEndsWith, StringPrototypeIncludes, StringPrototypeIndexOf, StringPrototypeLastIndexOf, StringPrototypeMatch, StringPrototypeReplace, StringPrototypeSlice, StringPrototypeSplit, StringPrototypeStartsWith, SyntaxError, TypeError, } = primordials; const _httpAgent = core.createLazyLoader("node:_http_agent"); const _httpCommon = core.createLazyLoader("node:_http_common"); const _httpOutgoing = core.createLazyLoader("node:_http_outgoing"); const _httpServer = core.createLazyLoader("node:_http_server"); // Heavy stream class definitions. Lazified - only loaded if a script // actually `require('_stream_*')` or pulls them transitively via // `node:stream` after our lazy stdio refactor. // _tls_common, _tls_wrap are lazy-loaded via `lazyNodeModules` below: their // scripts extend net.Socket at module body, which pulls node:net (and then // node:stream) into the snapshot. const assertStrict = core.createLazyLoader("node:assert/strict"); const internalAsyncHooks = core.loadExtScript( "ext:deno_node/internal/async_hooks.ts", ); const { emitAfter: internalAsyncHooksEmitAfter, emitBefore: internalAsyncHooksEmitBefore, emitDestroy: internalAsyncHooksEmitDestroy, emitInit: internalAsyncHooksEmitInit, } = internalAsyncHooks; const buffer = core.loadExtScript("ext:deno_node/internal/buffer.mjs").default; // child_process, crypto, dgram are lazy-loaded via `lazyNodeModules` below. // Their scripts use `createLazyLoader(...)()` patterns to extend classes // from `node:stream`/`node:net`/etc. at module body time, which pulls the // whole stream/net subtree into the snapshot if loaded eagerly. // cluster is lazy via `lazyNodeModules` below. Its body reads // `NODE_CLUSTER_SCHED_POLICY` from env at module evaluation time; deferring // that to the first `require("cluster")` is what Node does anyway, and the // worker bootstrap already loads cluster.ts explicitly when // `nodeClusterUniqueId` is set (see `__initCluster` below). import console from "node:console"; const diagnosticsChannel = core.loadExtScript("ext:deno_node/diagnostics_channel.js").default; const events = core.loadExtScript("ext:deno_node/_events.mjs").default; // fs/promises is lazy-loaded via `lazyNodeModules` below: its script body // does `createLazyLoader("node:fs")()` which loads `node:fs` (fs_esm.ts), // whose body in turn reads the lazy createReadStream/Utf8Stream getters // off `fs.ts` and pulls the whole internal/fs/streams + node:stream chain // into the snapshot. // http/http2/https are lazy-loaded via `lazyNodeModules` below: their script // bodies eagerly chain into the entire node:_http_* / node:net / node:stream // graph, so running them at snapshot time defeats lazifying _http_*. // internal/child_process pulls deno_process/40_process.js -> 22_body // -> 06_streams (208 KB). Lazy-loaded via lazyNodeModules. // internal/assert/myers_diff, the whole internal/crypto/* family, // internal/dgram, internal/deps/undici/undici and internal/dns/promises are // lazy-loaded via `lazyNodeModules` below. Nothing in this file reads them - // they only exist to be handed out by `require()` - so evaluating them at // `node:module` init just made every CJS entry point pay their parse/compile // cost up front. const internalBuffer = core.loadExtScript("ext:deno_node/internal/buffer.mjs"); const internalErrors = core.loadExtScript("ext:deno_node/internal/errors.ts"); const internalEventTarget = core.createLazyLoader( "ext:deno_node/internal/event_target.mjs", ); const internalFsUtils = core.createLazyLoader( "ext:deno_node/internal/fs/utils.mjs", ); // `internal/fs/promises.ts` evaluates `lazyFs()` at top-level, so triggering // its load during `setupBuiltinModules()` would re-enter the half-built // `node:fs` namespace. A Proxy defers evaluation until the first time the // requiring code reads a property; by then `node:fs` is fully initialized. const lazyInternalFsPromises = core.createLazyLoader( "ext:deno_node/internal/fs/promises.ts", ); let internalFsPromisesCache; const internalFsPromisesProxy = new Proxy(ObjectCreate(null), { get(_target, prop) { return (internalFsPromisesCache ??= lazyInternalFsPromises())[prop]; }, has(_target, prop) { return prop in (internalFsPromisesCache ??= lazyInternalFsPromises()); }, }); // internal/http, internal/http2/core, internal/http2/util are lazy-loaded // via `lazyNodeModules` below. Loading them eagerly here pulls the entire // http2 ESM chain (node:http2 -> http2.ts -> node:http -> http.ts -> the // node:_http_* graph) into the snapshot, defeating the http/_http_* // lazification we set up. // internal/priority_queue, internal/readline/utils, internal/streams/*, // internal/socketaddress, internal/test/binding, internal/timers and // internal/url are lazy-loaded via `lazyNodeModules` below - see the note // above the crypto family. const internalStreamsLazyTransform = core.createLazyLoader( "ext:deno_node/internal/streams/lazy_transform.js", ); const internalUtil = core.loadExtScript("ext:deno_node/internal/util.mjs"); const internalUtilDebuglog = core.loadExtScript( "ext:deno_node/internal/util/debuglog.ts", ); const internalUtilInspect = core.loadExtScript( "ext:deno_node/internal/util/inspect.mjs", ); const internalValidators = core.loadExtScript( "ext:deno_node/internal/validators.mjs", ); const internalConsole = core.loadExtScript( "ext:deno_node/internal/console/constructor.mjs", ).default; // os, punycode, string_decoder, timers, timers/promises, util/types and vm are // lazy via `lazyNodeModules` below - see the note above the crypto family. import pathPosix from "node:path/posix"; import pathWin32 from "node:path/win32"; import path from "node:path"; // node:process is lazy now (see lib.rs / 98_global_scope_shared.js). 01_require // only uses `process` inside require-time functions + the builtin map, never at // module-eval, so resolving it lazily keeps the node process closure out of the // snapshot for programs that never require()/touch process. let _processLazy; const _processMod = () => (_processLazy ??= core.createLazyLoader("node:process")().default); const process = new Proxy({ __proto__: null }, { get: (_t, p) => _processMod()[p], has: (_t, p) => p in _processMod(), set: (_t, p, v) => { _processMod()[p] = v; return true; }, }); const readline = core.createLazyLoader("node:readline"); const readlinePromises = core.createLazyLoader("node:readline/promises"); const repl = core.createLazyLoader("node:repl"); const internalRepl = core.createLazyLoader( "ext:deno_node/internal/repl.ts", ); // node:stream / node:net / node:tty and friends are lazy (see process.ts: // process.stdout/stderr/stdin are lazy getters now, so nothing forces the // stream/net/tty closure into the snapshot). stream/web pulls // ext:deno_web/14_compression.js -> 06_streams (208 KB) too. const tls = core.createLazyLoader("node:tls"); const url = core.loadExtScript("ext:deno_node/url.ts"); const util = core.loadExtScript("ext:deno_node/util.ts"); // worker_threads must stay eager: it registers `internals.__initWorkerThreads` // / `internals.__isWorkerThread`, which the node process bootstrap calls // (`__initWorkerThreads` at startup). It also statically imports node:vm, so // vm stays in the snapshot regardless. const workerThreads = core.loadExtScript( "ext:deno_node/worker_threads.ts", ); // zlib is lazy-loaded via `lazyNodeModules` below: zlib.js extends // `Transform` from `node:stream` at module body, so loading it eagerly // pulls the stream subtree into the snapshot. const internalOptions = core.loadExtScript( "ext:deno_node/internal/options.ts", ); const { getOptionValue } = internalOptions; const nativeModuleExports = ObjectCreate(null); const builtinModules = []; // Modules installed as lazy getters on `nativeModuleExports`. Each value is // a `() => exports` thunk that's only invoked the first time the require name // is accessed. Keeping these out of the eager `nodeModules` map means the // snapshot does not have to compile their bodies (and everything those // bodies transitively pull in via `loadExtScript`/`op_lazy_load_esm`). // Use `() => createLazyLoader("...")().default` for `lazy_loaded_esm` entries // and `() => loadExtScript("...")` for `lazy_loaded_js` entries. const lazyNodeModules = { // Plain builtins that nothing in this file reads - they exist only to be // handed back by `require()`. Evaluating them at `node:module` init made // every CJS entry point (and anything that pulls in `require`) compile them // whether or not the program ever touches them. "assert": () => core.loadExtScript("ext:deno_node/assert.ts").default, "async_hooks": () => core.loadExtScript("ext:deno_node/async_hooks.ts").default, "cluster": () => core.loadExtScript("ext:deno_node/cluster.ts").default, "constants": () => core.loadExtScript("ext:deno_node/constants.ts").default, "dns": () => core.loadExtScript("ext:deno_node/dns.ts").default, "dns/promises": () => core.loadExtScript("ext:deno_node/dns/promises.ts").default, "domain": () => core.loadExtScript("ext:deno_node/domain.ts").default, "fs": () => core.loadExtScript("ext:deno_node/fs.ts"), "os": () => core.loadExtScript("ext:deno_node/os.ts").default, "punycode": () => core.loadExtScript("ext:deno_node/punycode.ts").default, "string_decoder": () => core.loadExtScript("ext:deno_node/string_decoder.ts").default, "timers": () => core.loadExtScript("ext:deno_node/timers.ts"), "timers/promises": () => core.loadExtScript("ext:deno_node/timers/promises.ts"), "util/types": () => core.loadExtScript("ext:deno_node/internal/util/types.ts"), "vm": () => core.loadExtScript("ext:deno_node/vm.js").default, "internal/assert/myers_diff": () => core.loadExtScript("ext:deno_node/internal/assert/myers_diff.js").default, "internal/crypto/certificate": () => core.loadExtScript("ext:deno_node/internal/crypto/certificate.ts").default, "internal/crypto/diffiehellman": () => core.loadExtScript("ext:deno_node/internal/crypto/diffiehellman.ts") .default, "internal/crypto/hash": () => core.loadExtScript("ext:deno_node/internal/crypto/hash.ts").default, "internal/crypto/hkdf": () => core.loadExtScript("ext:deno_node/internal/crypto/hkdf.ts").default, "internal/crypto/keygen": () => core.loadExtScript("ext:deno_node/internal/crypto/keygen.ts").default, "internal/crypto/keys": () => core.loadExtScript("ext:deno_node/internal/crypto/keys.ts").default, "internal/crypto/pbkdf2": () => core.loadExtScript("ext:deno_node/internal/crypto/pbkdf2.ts").default, "internal/crypto/random": () => core.loadExtScript("ext:deno_node/internal/crypto/random.ts").default, "internal/crypto/scrypt": () => core.loadExtScript("ext:deno_node/internal/crypto/scrypt.ts").default, "internal/crypto/sig": () => core.loadExtScript("ext:deno_node/internal/crypto/sig.ts").default, "internal/crypto/util": () => core.loadExtScript("ext:deno_node/internal/crypto/util.ts").default, "internal/crypto/x509": () => core.loadExtScript("ext:deno_node/internal/crypto/x509.ts").default, "internal/dgram": () => core.loadExtScript("ext:deno_node/internal/dgram.ts").default, "internal/deps/undici/undici": () => core.loadExtScript("ext:deno_node/internal/deps/undici/undici.js").default, "internal/dns/promises": () => core.loadExtScript("ext:deno_node/internal/dns/promises.ts").default, "internal/priority_queue": () => core.loadExtScript("ext:deno_node/internal/priority_queue.ts").default, "internal/readline/utils": () => core.loadExtScript("ext:deno_node/internal/readline/utils.mjs").default, "internal/streams/add-abort-signal": () => core.loadExtScript("ext:deno_node/internal/streams/add-abort-signal.js") .default, "internal/streams/state": () => core.loadExtScript("ext:deno_node/internal/streams/state.js").default, "internal/socketaddress": () => core.loadExtScript("ext:deno_node/internal/socketaddress.js"), "internal/test/binding": () => core.loadExtScript("ext:deno_node/internal/test/binding.ts"), "internal/timers": () => core.loadExtScript("ext:deno_node/internal/timers.mjs"), "internal/url": () => core.loadExtScript("ext:deno_node/internal/url.ts"), // Lazy so the WHATWG-streams adapter graph (stream/web -> deno_web // 06_streams, ~1.8MB of snapshot heap) is only loaded when something // actually requires these internals, not eagerly at node:module init. "internal/worker/js_transferable": () => core.loadExtScript("ext:deno_node/internal/worker/js_transferable.js"), "internal/webstreams/adapters": () => core.loadExtScript("ext:deno_node/internal/webstreams/adapters.js"), "internal/webstreams/readablestream": () => core.loadExtScript("ext:deno_node/internal/webstreams/readablestream.js"), "internal/webstreams/util": () => core.loadExtScript("ext:deno_node/internal/webstreams/util.js"), "_http_agent": () => _httpAgent().default, "_http_common": () => _httpCommon().default, "_http_outgoing": () => _httpOutgoing().default, "_http_server": () => _httpServer().default, "http": () => core.loadExtScript("ext:deno_node/http.ts"), "http2": () => core.loadExtScript("ext:deno_node/http2.ts"), "https": () => core.loadExtScript("ext:deno_node/https.ts"), "internal/http": () => core.loadExtScript("ext:deno_node/internal/http.ts").default, "internal/http2/core": () => core.loadExtScript("ext:deno_node/internal/http2/core.ts").default, "internal/http2/util": () => core.loadExtScript("ext:deno_node/internal/http2/util.ts").default, "internal/streams/lazy_transform": () => internalStreamsLazyTransform().default, "child_process": () => core.loadExtScript("ext:deno_node/child_process.ts"), "crypto": () => core.loadExtScript("ext:deno_node/crypto.ts").default, "dgram": () => core.loadExtScript("ext:deno_node/dgram.ts").default, "zlib": () => core.loadExtScript("ext:deno_node/zlib.js"), "tls": () => tls().default, "internal/crypto/cipher": () => core.loadExtScript("ext:deno_node/internal/crypto/cipher.ts").default, "_tls_common": () => core.loadExtScript("ext:deno_node/_tls_common.ts").default, "_tls_wrap": () => core.loadExtScript("ext:deno_node/_tls_wrap.js").default, "repl": () => repl().default, "internal/repl": () => internalRepl().default, "fs/promises": () => core.loadExtScript("ext:deno_node/fs/promises.ts").fsPromises, "test/reporters": () => core.loadExtScript("ext:deno_node/test/reporters.ts").default, "assert/strict": () => assertStrict().default, "internal/event_target": () => internalEventTarget().default, "internal/fs/utils": () => internalFsUtils().default, "readline": () => readline().default, "readline/promises": () => readlinePromises().default, "internal/child_process": () => core.loadExtScript("ext:deno_node/internal/child_process.ts").default, "stream/web": () => core.loadExtScript("ext:deno_node/stream/web.js"), "internal/js_stream_socket": () => core.loadExtScript("ext:deno_node/internal/js_stream_socket.js").default, "internal/net": () => core.loadExtScript("ext:deno_node/internal/net.ts"), "internal/tty": () => core.createLazyLoader("ext:deno_node/internal/tty.js")(), "net": () => core.createLazyLoader("node:net")().default, // `process` must lazy-resolve to the real `node:process` default export // (the proxy at the top of this file is for internal use only). When // `getBuiltinModule('process')` is called we want the actual singleton so // strict-equality against the global `process` holds. "process": () => core.createLazyLoader("node:process")().default, // node:stream/net/tty closure - lazy now that process.stdout/stderr/stdin // are lazy getters (see process.ts). These are the biggest node snapshot // chunk, so keeping them out of the eager heap is the main startup win. "stream": () => core.createLazyLoader("node:stream")().default, "stream/consumers": () => core.loadExtScript("ext:deno_node/stream/consumers.js"), "stream/promises": () => core.createLazyLoader("node:stream/promises")().default, "tty": () => core.createLazyLoader("node:tty")().default, // Rarely needed on the cold-start path; keeping these out of the eager // `nodeModules` map keeps their bodies (and transitive `loadExtScript` // closure) out of the snapshot heap, so they aren't deserialized at every // startup. Match the previous `.default`/no-`.default` shape exactly. "inspector": () => core.loadExtScript("ext:deno_node/inspector.js"), "inspector/promises": () => core.loadExtScript("ext:deno_node/inspector/promises.js"), "perf_hooks": () => core.loadExtScript("ext:deno_node/perf_hooks.js").default, "querystring": () => core.loadExtScript("ext:deno_node/querystring.js").default, "sqlite": () => core.loadExtScript("ext:deno_node/sqlite.ts"), "test": () => core.loadExtScript("ext:deno_node/testing.ts").default, "trace_events": () => core.loadExtScript("ext:deno_node/trace_events.ts").default, "v8": () => core.loadExtScript("ext:deno_node/v8.ts"), "wasi": () => core.loadExtScript("ext:deno_node/wasi.ts").default, "_stream_duplex": () => core.loadExtScript("ext:deno_node/internal/streams/duplex.js").default, "_stream_passthrough": () => core.loadExtScript("ext:deno_node/internal/streams/passthrough.js").default, "_stream_readable": () => core.loadExtScript("ext:deno_node/internal/streams/readable.js").default, "_stream_transform": () => core.loadExtScript("ext:deno_node/internal/streams/transform.js").default, "_stream_writable": () => core.loadExtScript("ext:deno_node/internal/streams/writable.js").default, }; function defineLazyNativeModule(name, loader) { ObjectDefineProperty(nativeModuleExports, name, { __proto__: null, get() { const value = loader(); ObjectDefineProperty(nativeModuleExports, name, { __proto__: null, value, writable: true, enumerable: true, configurable: true, }); return value; }, enumerable: true, configurable: true, }); } // NOTE(bartlomieju): keep this list in sync with `ext/node/lib.rs` function setupBuiltinModules() { const nodeModules = { buffer, console, diagnostics_channel: diagnosticsChannel, events, "internal/async_hooks": internalAsyncHooks, "internal/console/constructor": internalConsole, "internal/buffer": internalBuffer.default, "internal/errors": internalErrors, "internal/fs/promises": internalFsPromisesProxy, "internal/options": internalOptions, "internal/util/debuglog": internalUtilDebuglog.default, "internal/util/inspect": internalUtilInspect, "internal/util": internalUtil, "internal/validators": internalValidators, module: Module, "path/posix": pathPosix, "path/win32": pathWin32, path, // `process` is registered lazily below (see `lazyNodeModules`) so that // `getBuiltinModule('process')` returns the real `node:process` default // export rather than the proxy stand-in used elsewhere in this file. sys: util, url, util, worker_threads: workerThreads, }; // Match Node's schemelessBlockList: these modules can only be imported // via the `node:` scheme (see lib/internal/bootstrap/realm.js), so they // appear in `builtinModules` as `node:<name>` rather than `<name>`. const schemelessBlockList = new SafeSet([ "sqlite", "test", "test/reporters", ]); function registerName(name) { // `internal/*` modules are only exposed under --expose-internals, so // they aren't part of the public builtinModules list. if (StringPrototypeStartsWith(name, "internal/")) { return; } if (SetPrototypeHas(schemelessBlockList, name)) { ArrayPrototypePush(builtinModules, `node:${name}`); } else { ArrayPrototypePush(builtinModules, name); } } for (const [name, moduleExports] of ObjectEntries(nodeModules)) { nativeModuleExports[name] = moduleExports; registerName(name); } for (const [name, loader] of ObjectEntries(lazyNodeModules)) { defineLazyNativeModule(name, loader); registerName(name); } } setupBuiltinModules(); // Loading node:module has to bootstrap node:process. `_next_tick.ts`'s // `nextTick()` returns without queueing anything until `enableNextTick()` runs, // and that only happens inside `__bootstrapNodeProcess()` (node:process's // deferred trigger). Anything reaching `process.nextTick` before then - e.g. // `_events.mjs`'s `addCatch`, which routes a rejected handler promise to the // `error` event under `captureRejections` - silently loses its callback. // // This used to happen by accident: the eager `vm.js` load above did // `createLazyLoader("node:process")()` at its module body. Now that the builtin // map is lazy, say it on purpose. node:process's closure is ~7 modules and // every CommonJS entry point pulls it in anyway. core.createLazyLoader("node:process")(); function pathDirname(filepath) { if (filepath == null) { throw new Error("Empty filepath."); } else if (filepath === "") { return "."; } return op_require_path_dirname(filepath); } function pathResolve(...args) { return op_require_path_resolve(args); } const nativeModulePolyfill = new SafeMap(); const relativeResolveCache = ObjectCreate(null); let requireDepth = 0; let statCache = null; let mainModule = null; let hasBrokenOnInspectBrk = false; let hasInspectBrk = false; // Are we running with --node-modules-dir flag or byonm? let usesLocalNodeModulesDir = false; let patched = false; // module.registerHooks() infrastructure const hookEntries = []; const cjsHookResolvedFilenames = new SafeSet(); let insideResolveHook = false; let insideLoadHook = false; let utf8Decoder; let esmLoadLoopRunning = false; const requireResolveOptionsMarker = Symbol("require.resolve"); const kSourceURL = Symbol("kSourceURL"); function executeResolveHookChain(specifier, context, parent, isMain, options) { // Collect resolve hooks from hookEntries in LIFO order const resolveHooks = []; for (let i = hookEntries.length - 1; i >= 0; i--) { if (hookEntries[i].resolve !== null) { ArrayPrototypePush(resolveHooks, hookEntries[i].resolve); } } if (resolveHooks.length === 0) return null; let index = 0; // Running context accumulates changes across the chain let currentContext = context; function nextResolve(spec, ctx) { // If ctx provided, merge into running context if (ctx !== undefined && ctx !== null) { currentContext = { ...currentContext, ...ctx }; } if (index >= resolveHooks.length) { // Default resolve: use Module._resolveFilename insideResolveHook = true; try { // Handle node: builtins if (StringPrototypeStartsWith(spec, "node:")) { return { url: spec, shortCircuit: true }; } if (nativeModuleCanBeRequiredByUsers(spec)) { return { url: "node:" + spec, shortCircuit: true }; } const resolved = Module._resolveFilename( spec, parent, isMain, options, ); let resolvedUrl; if (StringPrototypeStartsWith(resolved, "node:")) { resolvedUrl = resolved; } else { resolvedUrl = url.pathToFileURL(resolved).href; } return { url: resolvedUrl, shortCircuit: true }; } finally { insideResolveHook = false; } } const hook = resolveHooks[index++]; let nextCalled = false; const wrappedNext = (s, c) => { nextCalled = true; return nextResolve(s, c); }; const result = hook(spec, currentContext, wrappedNext); if (!nextCalled && !result?.shortCircuit) { throw new internalErrors.ERR_INVALID_RETURN_PROPERTY_VALUE( "true", "resolve", "shortCircuit", result?.shortCircuit, ); } if (result?.shortCircuit && typeof result?.url !== "string") { const err = new TypeError( 'Expected a URL string to be returned for the "url" from the "resolve" hook', ); err.code = "ERR_INVALID_RETURN_PROPERTY_VALUE"; throw err; } return result; } return nextResolve(specifier, context); } function executeLoadHookChain(fileUrl, context) { // Collect load hooks from hookEntries in LIFO order const loadHooks = []; for (let i = hookEntries.length - 1; i >= 0; i--) { if (hookEntries[i].load !== null) { ArrayPrototypePush(loadHooks, hookEntries[i].load); } } if (loadHooks.length === 0) return null; let index = 0; let currentContext = context; function nextLoad(loadUrl, ctx) { if (ctx !== undefined && ctx !== null) { currentContext = { ...currentContext, ...ctx }; } if (index >= loadHooks.length) { // Default load: read file from disk // For builtins, return null source if (StringPrototypeStartsWith(loadUrl, "node:")) { return { source: null, format: "builtin", shortCircuit: true }; } const filePath = StringPrototypeStartsWith(loadUrl, "file://") ? url.fileURLToPath(loadUrl) : loadUrl; const source = op_require_read_file(filePath); return { source, format: currentContext?.format ?? undefined, shortCircuit: true, }; } const hook = loadHooks[index++]; let nextCalled = false; const wrappedNext = (u, c) => { nextCalled = true; return nextLoad(u, c); }; const result = hook(loadUrl, currentContext, wrappedNext); if (!nextCalled && !result?.shortCircuit) { throw new internalErrors.ERR_INVALID_RETURN_PROPERTY_VALUE( "true", "load", "shortCircuit", result?.shortCircuit, ); } if ( result?.shortCircuit && !isValidLoadHookSource(result?.source, result?.format) ) { const err = new TypeError( 'Expected a string, an ArrayBuffer, or a TypedArray to be returned for the "source" from the "load" hook', ); err.code = "ERR_INVALID_RETURN_PROPERTY_VALUE"; throw err; } return result; } return nextLoad(fileUrl, context); } function isValidLoadHookSource(source, format) { if (source === null) { return format === "builtin"; } return typeof source === "string" || core.isAnyArrayBuffer(source) || core.isArrayBufferView(source); } function loadHookSourceToString(source) { if (typeof source === "string") { return source; } if (core.isAnyArrayBuffer(source)) { return (utf8Decoder ??= new TextDecoder()).decode(new Uint8Array(source)); } return (utf8Decoder ??= new TextDecoder()).decode( new Uint8Array(source.buffer, source.byteOffset, source.byteLength), ); } // ESM resolve hook chain: runs hooks in LIFO order. // Returns { url } if hooks resolved, or null for fallthrough to default. function executeEsmResolveHookChain(specifier, context) { const resolveHooks = []; for (let i = hookEntries.length - 1; i >= 0; i--) { if (hookEntries[i].resolve !== null) { ArrayPrototypePush(resolveHooks, hookEntries[i].resolve); } } if (resolveHooks.length === 0) return null; let index = 0; let currentContext = context; function nextResolve(spec, ctx) { if (ctx !== undefined && ctx !== null) { currentContext = { ...currentContext, ...ctx }; } if (index >= resolveHooks.length) { if (StringPrototypeStartsWith(spec, "node:")) { return { url: spec, shortCircuit: true }; } insideResolveHook = true; try { const resolved = op_module_default_resolve( spec, currentContext.parentURL ?? "", ); return { url: resolved, shortCircuit: true }; } catch { // Last-ditch fallback so hooks can still observe purely synthetic // specifiers that Deno's resolver rejects (e.g. ad-hoc URLs invented // by user code). try { const resolved = new URL(spec, currentContext.parentURL).href; return { url: resolved, shortCircuit: true }; } catch { return { url: null, shortCircuit: true }; } } finally { insideResolveHook = false; } } const hook = resolveHooks[index++]; let nextCalled = false; const wrappedNext = (s, c) => { nextCalled = true; return nextResolve(s, c); }; const result = hook(spec, currentContext, wrappedNext); if (!nextCalled && !result?.shortCircuit) { throw new TypeError( "resolve hook must return { shortCircuit: true } or call nextResolve", ); } return result; } return nextResolve(specifier, context); } function esmResolveHookCallback(specifier, referrer, importAttributes) { const attrs = { __proto__: null }; if (importAttributes !== null && typeof importAttributes === "object") { for (const key in importAttributes) { attrs[key] = importAttributes[key]; } } const context = { parentURL: referrer || undefined, conditions: ["node", "import", "module-sync", "node-addons"], importAttributes: attrs, }; try { const result = executeEsmResolveHookChain(specifier, context); return result?.url ?? null; } catch (e) { return { error: String(e) }; } } // ESM load hook chain: runs hooks in LIFO order. // Returns `null` when no load hooks are registered, otherwise // `{ result, effectiveUrl }` where `result` is the hook chain's return value // and `effectiveUrl` is the URL the chain ultimately delegated to via // `nextLoad(newUrl)`: used by the load loop when falling through to Rust // default loading so the source comes from the URL the user redirected to, // not the original. function executeEsmLoadHookChain(fileUrl, context) { const loadHooks = []; for (let i = hookEntries.length - 1; i >= 0; i--) { if (hookEntries[i].load !== null) { ArrayPrototypePush(loadHooks, hookEntries[i].load); } } if (loadHooks.length === 0) return null; let index = 0; let currentContext = context; let effectiveUrl = fileUrl; function nextLoad(loadUrl, ctx) { effectiveUrl = loadUrl; if (ctx !== undefined && ctx !== null) { currentContext = { ...currentContext, ...ctx }; } if (index >= loadHooks.length) { // End of chain. Synthesize a default load result so user hooks // that call `await nextLoad(...)` observe a real `source` they // can transform (matches Node, where `defaultLoad` returns the // on-disk source). if (StringPrototypeStartsWith(loadUrl, "node:")) { return { source: null, format: "builtin", shortCircuit: true }; } if (StringPrototypeStartsWith(loadUrl, "file://")) { // `type: "bytes"` modules cannot be faithfully represented as a JS // string here; fall through to Rust default loading, which reads the // file as bytes and produces a correctly-typed module. (Reading it as // a string would otherwise trip "Source code for Bytes module must be // provided as bytes".) if (currentContext?.importAttributes?.type === "bytes") { return { source: null, shortCircuit: true }; } try { const source = op_require_read_file(url.fileURLToPath(loadUrl)); return { source, format: currentContext?.format, shortCircuit: true, }; } catch { // Any sync read failure (file absent from disk because it's // embedded in a compiled binary's eszip, permission errors, // transient IO) falls through to Rust default loading via // the load loop, which surfaces a clearer error if the // module truly cannot be loaded. return { source: null, shortCircuit: true }; } } // For other schemes (data:, http(s):, etc.) we cannot synchronously // produce source here; fall through to Rust default loading. return { source: null, shortCircuit: true }; } const hook = loadHooks[index++]; let nextCalled = false; const wrappedNext = (u, c) => { nextCalled = true; return nextLoad(u, c); }; const result = hook(loadUrl, currentContext, wrappedNext); if (!nextCalled && !result?.shortCircuit) { throw new TypeError( "load hook must return { shortCircuit: true } or call nextLoad", ); } return result; } const result = nextLoad(fileUrl, context); return { result, effectiveUrl }; } function _startEsmLoadLoop() { if (esmLoadLoopRunning) return; esmLoadLoopRunning = true; (async () => { while (true) { const pollPromise = op_module_hooks_poll_load(); core.unrefOpPromise(pollPromise); const req = await pollPromise; if (req === null) break; const [id, fileUrl, rawAttributes] = req; const importAttributes = { __proto__: null }; if (rawAttributes !== null && typeof rawAttributes === "object") { for (const key in rawAttributes) { importAttributes[key] = rawAttributes[key]; } } const context = { format: undefined, conditions: ["node", "import", "module-sync", "node-addons"], importAttributes, }; try { const chainResult = executeEsmLoadHookChain(fileUrl, context); const result = chainResult?.result ?? null; const effectiveUrl = chainResult?.effectiveUrl ?? null; if (result?.format === "builtin") { op_module_hooks_respond_load(id, null, "builtin", null, null); } else if (result !== null && result.source != null) { const source = loadHookSourceToString(result.source); const format = result.format || null; op_module_hooks_respond_load(id, source, format, null, null); } else { // Fallthrough: tell Rust to use default loading. Pass the URL the // hook chain ultimately delegated to (may differ from the original // when a hook called `nextLoad(newUrl)`) so source is fetched from // there while the module keeps the original URL as its identity. op_module_hooks_respond_load(id, null, null, null, effectiveUrl); } } catch (e) { op_module_hooks_respond_load(id, null, null, String(e), null); } } })(); } function _activateEsmHooks() { let hasResolve = false; let hasLoad = false; for (let i = 0; i < hookEntries.length; i++) { if (hookEntries[i].resolve !== null) hasResolve = true; if (hookEntries[i].load !== null) hasLoad = true; } op_module_hooks_register(hasResolve ? esmResolveHookCallback : null, hasLoad); if (hasLoad) _startEsmLoadLoop(); } let internalModuleStat = op_require_stat; function stat(filename) { if (statCache !== null) { const result = statCache.get(filename); if (result !== undefined) { return result; } } const result = internalModuleStat(filename); if (statCache !== null && result >= 0) { statCache.set(filename, result); } return result; } function updateChildren(parent, child, scan) { if (!parent) { return; } const children = parent.children; if (children && !(scan && ArrayPrototypeIncludes(children, child))) { ArrayPrototypePush(children, child); } } // Given a path inside a node_modules tree, find the package root by // locating the last "node_modules" path component and taking the next // segment (or two for scoped packages). Returns null if no node_modules // component is found. function findPackageRootFromNodeModules(filepath) { // Find the last occurrence of /node_modules/ or \node_modules\ in the path let nmIdx = -1; let sep = "/"; const fwdIdx = StringPrototypeLastIndexOf(filepath, "/node_modules/"); const bwdIdx = StringPrototypeLastIndexOf(filepath, "\\node_modules\\"); if (fwdIdx !== -1 && fwdIdx > bwdIdx) { nmIdx = fwdIdx; sep = "/"; } else if (bwdIdx !== -1) { nmIdx = bwdIdx; sep = "\\"; } if (nmIdx === -1) return null; const afterNm = nmIdx + sep.length + "node_modules".length + sep.length; const rest = StringPrototypeSlice(filepath, afterNm); const parts = StringPrototypeSplit(rest, sep); if (parts.length === 0 || parts[0] === "") return null; if (StringPrototypeStartsWith(parts[0], "@") && parts.length > 1) { // Scoped package: @scope/name return StringPrototypeSlice(filepath, 0, afterNm) + parts[0] + sep + parts[1]; } return StringPrototypeSlice(filepath, 0, afterNm) + parts[0]; } function tryFile(requestPath, _isMain) { const rc = stat(requestPath); if (rc !== 0) return; return toRealPath(requestPath); } function tryPackage(requestPath, exts, isMain, originalPath) { const packageJsonPath = pathResolve( requestPath, "package.json", ); const pkg = op_require_read_package_scope(packageJsonPath)?.main; if (!pkg) { return tryExtensions( pathResolve(requestPath, "index"), exts, isMain, ); } const filename = pathResolve(requestPath, pkg); // Find the package root for the path traversal check. For nested // package.json files inside node_modules (e.g. pkg/sub/package.json with // "main": "../cjs/sub.js"), we allow resolving up to the package root // (node_modules/pkg/) rather than restricting to the nested directory. const packageRoot = findPackageRootFromNodeModules(requestPath) ?? requestPath; // Ensure the resolved main path doesn't escape the package directory // via path traversal (e.g. "main": "../../secret.json") if ( !StringPrototypeStartsWith(filename, packageRoot + "/") && !StringPrototypeStartsWith(filename, packageRoot + "\\") && filename !== packageRoot ) { const err = new Error( `Cannot find module '${filename}'. ` + 'Please verify that the package.json has a valid "main" entry', ); err.code = "MODULE_NOT_FOUND"; err.path = pathResolve(requestPath, "package.json"); err.requestPath = originalPath; throw err; } let actual = tryFile(filename, isMain) || tryExtensions(filename, exts, isMain) || tryExtensions( pathResolve(filename, "index"), exts, isMain, ); if (actual === false) { actual = tryExtensions( pathResolve(requestPath, "index"), exts, isMain, ); if (!actual) { // eslint-disable-next-line no-restricted-syntax const err = new Error( `Cannot find module '${filename}'. ` + 'Please verify that the package.json has a valid "main" entry', ); err.code = "MODULE_NOT_FOUND"; err.path = pathResolve( requestPath, "package.json", ); err.requestPath = originalPath; throw err; } else { process.emitWarning( `Invalid 'main' field in '${packageJsonPath}' of '${pkg}'. ` + "Please either fix that or report it to the module author", "DeprecationWarning", "DEP0128", ); } } return actual; } const realpathCache = new SafeMap(); function toRealPath(requestPath) { const maybeCached = realpathCache.get(requestPath); if (maybeCached) { return maybeCached; } const rp = op_require_real_path(requestPath); realpathCache.set(requestPath, rp); return rp; } function tryExtensions(p, exts, isMain) { for (let i = 0; i < exts.length; i++) { const filename = tryFile(p + exts[i], isMain); if (filename) { return filename; } } return false; } // Find the longest (possibly multi-dot) extension registered in // Module._extensions function findLongestRegisteredExtension(filename) { const name = op_require_path_basename(filename); let currentExtension; let index; let startIndex = 0; while ((index = StringPrototypeIndexOf(name, ".", startIndex)) !== -1) { startIndex = index + 1; if (index === 0) continue; // Skip dotfiles like .gitignore currentExtension = StringPrototypeSlice(name, index); if (Module._extensions[currentExtension]) { return currentExtension; } } return ".js"; } function getExportsForCircularRequire(module) { if ( module.exports && // Skip Proxy module.exports so the warning machinery never invokes the // user-visible getPrototypeOf / setPrototypeOf traps. Matches the // !isProxy(...) guard in Node's lib/internal/modules/cjs/loader.js. !core.isProxy(module.exports) && ObjectGetPrototypeOf(module.exports) === ObjectPrototype && // Exclude transpiled ES6 modules / TypeScript code because those may // employ unusual patterns for accessing 'module.exports'. That should // be okay because ES6 modules have a different approach to circular // dependencies anyway. !module.exports.__esModule ) { // This is later unset once the module is done loading. ObjectSetPrototypeOf( module.exports, CircularRequirePrototypeWarningProxy, ); } return module.exports; } function emitCircularRequireWarning(prop) { process.emitWarning( `Accessing non-existent property '${String(prop)}' of module exports ` + "inside circular dependency", ); } // A Proxy that can be used as the prototype of a module.exports object and // warns when non-existent properties are accessed. const CircularRequirePrototypeWarningProxy = new Proxy({}, { get(target, prop) { // Allow __esModule access in any case because it is used in the output // of transpiled code to determine whether something comes from an // ES module, and is not used as a regular key of `module.exports`. if (prop in target || prop === "__esModule") return target[prop]; emitCircularRequireWarning(prop); return undefined; }, getOwnPropertyDescriptor(target, prop) { if ( ObjectHasOwn(target, prop) || prop === "__esModule" ) { return ObjectGetOwnPropertyDescriptor(target, prop); } emitCircularRequireWarning(prop); return undefined; }, }); const moduleParentCache = new SafeWeakMap(); function Module(id = "", parent) { this.id = id; this.path = pathDirname(id); // Use ObjectDefineProperty so that user-installed Object.prototype.exports // setters/getters are not invoked during module construction. Mirrors // setOwnProperty() in Node's lib/internal/util.js. ObjectDefineProperty(this, "exports", { __proto__: null, configurable: true, enumerable: true, value: {}, writable: true, }); moduleParentCache.set(this, parent); updateChildren(parent, this, false); this.filename = null; this.loaded = false; this.children = []; } let parentDeprecationEmitted = false; function emitParentDeprecation() { if (parentDeprecationEmitted) return; if (!getOptionValue("--pending-deprecation")) return; parentDeprecationEmitted = true; process.emitWarning( "module.parent is deprecated due to accuracy issues. Please use " + "require.main to find program entry point instead.", "DeprecationWarning", "DEP0144", ); } ObjectDefineProperty(Module.prototype, "parent", { __proto__: null, configurable: true, enumerable: true, get() { emitParentDeprecation(); return moduleParentCache.get(this); }, set(value) { emitParentDeprecation(); moduleParentCache.set(this, value); }, }); Module.builtinModules = builtinModules; Module._extensions = ObjectCreate(null); Module._cache = ObjectCreate(null); Module._pathCache = ObjectCreate(null); let modulePaths = []; Module.globalPaths = modulePaths; ObjectDefineProperty(Module, "_stat", { __proto__: null, configurable: true, get() { return internalModuleStat; }, set(value) { internalUtil.emitExperimentalWarning("Module._stat"); internalModuleStat = value; Module.stat = value; return true; }, }); const CHAR_FORWARD_SLASH = 47; const TRAILING_SLASH_REGEX = /(?:^|\/)\.?\.$/; // This only applies to requests of a specific form: // 1. name/.* // 2. @scope/name/.* const EXPORTS_PATTERN = /^((?:@[^/\\%]+\/)?[^./\\%][^/\\%]*)(\/.*)?$/; function resolveExports( modulesPath, request, parentPath, usesLocalNodeModulesDir, ) { // The implementation's behavior is meant to mirror resolution in ESM. const [, name, expansion = ""] = StringPrototypeMatch(request, EXPORTS_PATTERN) || []; if (!name) { return; } return op_require_resolve_exports( usesLocalNodeModulesDir, modulesPath, request, name, expansion, parentPath ?? "", ) ?? false; } Module._findPath = function (request, paths, isMain, parentPath) { const absoluteRequest = op_require_path_is_absolute(request); if (absoluteRequest) { paths = [""]; } else if (!paths || paths.length === 0) { return false; } const cacheKey = request + "\x00" + ArrayPrototypeJoin(paths, "\x00"); const entry = Module._pathCache[cacheKey]; if (entry) { return entry; } let exts; let trailingSlash = request.length > 0 && StringPrototypeCharCodeAt(request, request.length - 1) === CHAR_FORWARD_SLASH; if (!trailingSlash) { trailingSlash = RegExpPrototypeTest(TRAILING_SLASH_REGEX, request); } // For each path for (let i = 0; i < paths.length; i++) { // Don't search further if path doesn't exist const curPath = paths[i]; if (curPath && stat(curPath) < 1) continue; if (!absoluteRequest) { const exportsResolved = resolveExports( curPath, request, parentPath, usesLocalNodeModulesDir, ); if (exportsResolved) { return exportsResolved; } } let basePath; if (usesLocalNodeModulesDir) { basePath = pathResolve(curPath, request); } else { const isDenoDirPackage = op_require_is_deno_dir_package( curPath, ); const isRelative = op_require_is_request_relative( request, ); basePath = (isDenoDirPackage && !isRelative) ? pathResolve(curPath, packageSpecifierSubPath(request)) : pathResolve(curPath, request); } let filename; const rc = stat(basePath); if (!trailingSlash) { if (rc === 0) { // File. filename = toRealPath(basePath); } if (!filename) { // Try it with each of the extensions if (exts === undefined) { exts = ObjectKeys(Module._extensions); } filename = tryExtensions(basePath, exts, isMain); } } if (!filename && rc === 1) { // Directory. // try it with each of the extensions at "index" if (exts === undefined) { exts = ObjectKeys(Module._extensions); } filename = tryPackage(basePath, exts, isMain, request); } if (filename) { Module._pathCache[cacheKey] = filename; return filename; } } return false; }; /** * Get a list of potential module directories * @param {string} fromPath The directory name of the module * @returns {string[]} List of module directories */ Module._nodeModulePaths = function (fromPath) { return op_require_node_module_paths(fromPath); }; Module._resolveLookupPaths = function (request, parent) { if (typeof request !== "string") { throw new internalErrors.ERR_INVALID_ARG_TYPE( "request", "string", request, ); } // Return null for built-in modules, matching Node.js behavior. // Libraries like requizzle rely on this to detect native modules. const normalizedRequest = StringPrototypeStartsWith(request, "node:") ? StringPrototypeSlice(request, 5) : request; if ( isBuiltin(request) || normalizedRequest in nativeModuleExports ) { return null; } const paths = []; if (op_require_is_request_relative(request)) { ArrayPrototypePush( paths, parent?.filename ? op_require_path_dirname(parent.filename) : ".", ); return paths; } if ( !usesLocalNodeModulesDir && parent?.filename && parent.filename.length > 0 ) { const denoDirPath = op_require_resolve_deno_dir( request, parent.filename, ); if (denoDirPath) { ArrayPrototypePush(paths, denoDirPath); } } const lookupPathsResult = op_require_resolve_lookup_paths( request, parent?.paths, parent?.filename ?? "", ); if (lookupPathsResult) { ArrayPrototypePush(paths, ...new SafeArrayIterator(lookupPathsResult)); } return paths; }; Module._load = function (request, parent, isMain) { // A `node:`-prefixed `require()` of a specifier that isn't a user-requirable // builtin throws ERR_UNKNOWN_BUILTIN_MODULE. This covers unknown ids and // `internal/*` modules (Node only exposes those under `--expose-internals`). // `require.resolve()` goes through `_resolveFilename` directly and instead // reports MODULE_NOT_FOUND, so this check lives here rather than there. if ( typeof request === "string" && StringPrototypeStartsWith(request, "node:") && !(hookEntries.length > 0 && !insideResolveHook) ) { const id = StringPrototypeSlice(request, 5); if ( !(id in nativeModuleExports) || StringPrototypeStartsWith(id, "internal/") ) { throw new internalErrors.ERR_UNKNOWN_BUILTIN_MODULE(request); } } let relResolveCacheIdentifier; if (parent) { // Fast path for (lazy loaded) modules in the same directory. The indirect // caching is required to allow cache invalidation without changing the old // cache key names. relResolveCacheIdentifier = `${parent.path}\x00${request}`; const filename = relativeResolveCache[relResolveCacheIdentifier]; if (filename !== undefined) { const cachedModule = Module._cache[filename]; if (cachedModule !== undefined) { updateChildren(parent, cachedModule, true); if (!cachedModule.loaded) { return getExportsForCircularRequire(cachedModule); } return cachedModule.exports; } delete relativeResolveCache[relResolveCacheIdentifier]; } } const filename = Module._resolveFilename(request, parent, isMain); const cachedModule = Module._cache[filename]; if ( cachedModule !== undefined && !StringPrototypeStartsWith(filename, "node:") ) { updateChildren(parent, cachedModule, true); if (!cachedModule.loaded) { return getExportsForCircularRequire(cachedModule); } return cachedModule.exports; } const isBuiltinFilename = StringPrototypeStartsWith(filename, "node:") || nativeModuleCanBeRequiredByUsers(filename); if (isBuiltinFilename) { const builtinFilename = StringPrototypeStartsWith(filename, "node:") ? filename : "node:" + filename; // Slice 'node:' prefix const id = StringPrototypeSlice(builtinFilename, 5); // Run load hooks for builtins if registered. Node invokes the load hook // chain on every require() of a builtin, so do this before the cache // lookup; otherwise the second require would short-circuit and the hook // wouldn't fire. let builtinHookResult = null; if (hookEntries.length > 0 && !insideLoadHook) { let hasLoadHook = false; for (let i = 0; i < hookEntries.length; i++) { if (hookEntries[i].load !== null) { hasLoadHook = true; break; } } if (hasLoadHook) { const context = { format: "builtin", conditions: ["node", "require"], importAttributes: { __proto__: null }, }; insideLoadHook = true; try { builtinHookResult = executeLoadHookChain(builtinFilename, context); } finally { insideLoadHook = false; } } } // Hook-overridden builtins are cached under the `node:`-prefixed key. // `require("util")` resolves to a bare name, so the early cache lookup // above misses; check the prefixed key here so repeated requires reuse // the same module instance. const cachedBuiltin = Module._cache[builtinFilename]; if (cachedBuiltin !== undefined) { updateChildren(parent, cachedBuiltin, true); if (!cachedBuiltin.loaded) { return getExportsForCircularRequire(cachedBuiltin); } return cachedBuiltin.exports; } if (builtinHookResult != null) { const result = builtinHookResult; // If the hook changed the format away from "builtin", use the // hook-provided source instead of loading the native module. // This matches Node.js behavior where hooks can replace builtins // by returning a different format (e.g. "commonjs"). if ( result.format && result.format !== "builtin" && result.source != null ) { const mod = new Module(builtinFilename, parent); Module._cache[builtinFilename] = mod; const source = loadHookSourceToString(result.source); if (result.format === "commonjs") { mod._compile(source, builtinFilename, "commonjs"); } else if (result.format === "json") { mod.exports = JSONParse(stripBOM(source)); } else if (result.format === "module") { loadESMFromCJS(mod, builtinFilename, source, true); } else { mod._compile(source, builtinFilename, undefined, true); } mod.loaded = true; return mod.exports; } if (result.format === "builtin") { const module = loadNativeModule(id, id); if (module) { return module.exports; } const mod = new Module(builtinFilename, parent); mod.exports = {}; mod.loaded = true; Module._cache[builtinFilename] = mod; return mod.exports; } } maybeEmitNativeModuleDeprecation(id); const module = loadNativeModule(id, id); if (!module) { // TODO: // throw new ERR_UNKNOWN_BUILTIN_MODULE(filename); throw new Error("Unknown built-in module"); } return module.exports; } if (cachedModule !== undefined) { updateChildren(parent, cachedModule, true); if (!cachedModule.loaded) { return getExportsForCircularRequire(cachedModule); } return cachedModule.exports; } // A resolve hook that redirected `require('zlib')` to a file path must // not silently fall back to the native module via the original request. if (!SetPrototypeHas(cjsHookResolvedFilenames, filename)) { maybeEmitNativeModuleDeprecation(filename); const mod = loadNativeModule(filename, request); if (mod) { return mod.exports; } } // Don't call updateChildren(), Module constructor already does. const module = cachedModule || new Module(filename, parent); if (isMain) { process.mainModule = module; mainModule = module; module.id = "."; } Module._cache[filename] = module; if (parent !== undefined) { relativeResolveCache[relResolveCacheIdentifier] = filename; } let threw = true; try { try { module.load(filename); threw = false; } finally { if (threw) { delete Module._cache[filename]; SetPrototypeDelete(cjsHookResolvedFilenames, filename); if (parent !== undefined) { delete relativeResolveCache[relResolveCacheIdentifier]; const children = parent?.children; if (ArrayIsArray(children)) { const index = ArrayPrototypeIndexOf(children, module); if (index !== -1) { ArrayPrototypeSplice(children, index, 1); } } } } else if ( module.exports && // Skip Proxy module.exports so the cleanup pass after a circular // require doesn't invoke user-visible getPrototypeOf traps. Matches // Node's lib/internal/modules/cjs/loader.js behavior. !core.isProxy(module.exports) && ObjectGetPrototypeOf(module.exports) === CircularRequirePrototypeWarningProxy ) { ObjectSetPrototypeOf(module.exports, ObjectPrototype); } } } catch (err) { // For a top-level CommonJS throw in the entry module, fire // 'uncaughtExceptionMonitor' and 'uncaughtException' synchronously with // origin === 'uncaughtException', matching Node.js semantics. // // Without this, the throw bubbles up to the ESM wrapper that loads the // main CJS module, becomes a module evaluation rejection, and is routed // through Deno's unhandled-rejection path. if ( isMain && parent === null && typeof process !== "undefined" && typeof process._fatalException === "function" ) { if (process._fatalException(err)) { return module.exports; } if (err !== null && typeof err === "object") { const set = internals._dispatchedFatalErrors; if (set !== undefined) set.add(err); } } throw err; } if (isMain && parent === null) { core.processTicksAndRejections(); } return module.exports; }; Module._resolveFilename = function ( request, parent, isMain, options, ) { if (typeof request !== "string") { throw new internalErrors.ERR_INVALID_ARG_TYPE( "request", "string", request, ); } // Run resolve hooks if registered (and not already inside a hook) if ( hookEntries.length > 0 && !insideResolveHook && // Dynamic import of CJS goes through an internal self-require to execute // the CommonJS module. That is not a user resolve operation and Node's // registerHooks tests expect only the original import specifier to be // observable. request !== parent?.filename ) { const parentURL = parent?.[kSourceURL] ?? (parent?.filename ? url.pathToFileURL(parent.filename).href : undefined); const context = { conditions: ["node", "require"], importAttributes: { __proto__: null }, parentURL, }; const result = executeResolveHookChain( request, context, parent, isMain, options, ); if (result != null && result.url != null) { if ( options?.[requireResolveOptionsMarker] && StringPrototypeStartsWith(result.url, "node:") ) { return StringPrototypeSlice(result.url, 5); } if (StringPrototypeStartsWith(result.url, "file://")) { try { const filename = url.fileURLToPath(result.url); SetPrototypeAdd(cjsHookResolvedFilenames, filename); return filename; } catch { // Virtual file:// URLs may not have valid OS paths (e.g. // file:///virtual.js on Windows). Return the URL as-is and // let the load hook handle it. SetPrototypeAdd(cjsHookResolvedFilenames, result.url); return result.url; } } // node: and other schemes returned as-is SetPrototypeAdd(cjsHookResolvedFilenames, result.url); return result.url; } } if (nativeModuleCanBeRequiredByUsers(request)) { return request; } if (StringPrototypeStartsWith(request, "node:")) { const id = StringPrototypeSlice(request, 5); if (id in nativeModuleExports) { return request; } if (hookEntries.length > 0 && !insideResolveHook) { return request; } // `require.resolve("node:unknown")` reports MODULE_NOT_FOUND, unlike // `require("node:unknown")` which throws ERR_UNKNOWN_BUILTIN_MODULE from // `Module._load`. const err = new Error(`Cannot find module '${request}'`); err.code = "MODULE_NOT_FOUND"; throw err; } let paths; if (typeof options === "object" && options !== null) { if (ArrayIsArray(options.paths)) { // Validate all path entries are strings before using them. for (let i = 0; i < options.paths.length; i++) { if (typeof options.paths[i] !== "string") { throw new internalErrors.ERR_INVALID_ARG_TYPE( "options.paths", "string", options.paths[i], ); } } const isRelative = op_require_is_request_relative(request); if (isRelative) { // Resolve relative entries to absolute paths so _findPath can // stat them correctly. paths = []; for (let i = 0; i < options.paths.length; i++) { ArrayPrototypePush( paths, pathResolve(process.cwd(), options.paths[i]), ); } } else { const fakeParent = new Module("", null); paths = []; for (let i = 0; i < options.paths.length; i++) { const path = options.paths[i]; fakeParent.paths = Module._nodeModulePaths(path); const lookupPaths = Module._resolveLookupPaths(request, fakeParent); for (let j = 0; j < lookupPaths.length; j++) { if (!ArrayPrototypeIncludes(paths, lookupPaths[j])) { ArrayPrototypePush(paths, lookupPaths[j]); } } } } } else if (options.paths === undefined) { paths = Module._resolveLookupPaths(request, parent); } else { throw new internalErrors.ERR_INVALID_ARG_VALUE( "options.paths", options.paths, ); } } else { paths = Module._resolveLookupPaths(request, parent); } if (parent?.filename) { if (request[0] === "#") { const maybeResolved = op_require_package_imports_resolve( parent.filename, request, ); if (maybeResolved) { return maybeResolved; } } } // Try module self resolution first const parentPath = trySelfParentPath(parent); const selfResolved = parentPath != null ? op_require_try_self(parentPath, request) : undefined; if (selfResolved) { const cacheKey = request + "\x00" + (paths.length === 1 ? paths[0] : ArrayPrototypeJoin(paths, "\x00")); Module._pathCache[cacheKey] = selfResolved; return selfResolved; } // Look up the filename first, since that's the cache key. const filename = Module._findPath( request, paths, isMain, parentPath, ); if (filename) { return op_require_real_path(filename); } // fallback and attempt to resolve bare specifiers using // the global cache when not using --node-modules-dir if ( !usesLocalNodeModulesDir && ArrayIsArray(options?.paths) && request[0] !== "." && request[0] !== "#" && !request.startsWith("file:///") && !op_require_is_request_relative(request) && !op_require_path_is_absolute(request) ) { try { return Module._resolveFilename(request, parent, isMain, { ...options, paths: undefined, }); } catch { // ignore } } if ( typeof request === "string" && (StringPrototypeEndsWith(request, "$deno$eval.cjs") || StringPrototypeEndsWith(request, "$deno$eval.cts") || StringPrototypeEndsWith(request, "$deno$stdin.cjs") || StringPrototypeEndsWith(request, "$deno$stdin.cts")) ) { return request; } const requireStack = []; for (let cursor = parent; cursor; cursor = moduleParentCache.get(cursor)) { ArrayPrototypePush(requireStack, cursor.filename || cursor.id); } let message = `Cannot find module '${request}'`; if (requireStack.length > 0) { message = message + "\nRequire stack:\n- " + ArrayPrototypeJoin(requireStack, "\n- "); } // eslint-disable-next-line no-restricted-syntax const err = new Error(message); err.code = "MODULE_NOT_FOUND"; err.requireStack = requireStack; throw err; }; function trySelfParentPath(parent) { if (parent == null) { return undefined; } if (typeof parent.filename === "string") { return parent.filename; } if (parent.id === "<repl>" || parent.id === "internal/preload") { return op_fs_cwd(); } return undefined; } /** * Internal CommonJS API to always require modules before requiring the actual * one when calling `require("my-module")`. This is used by require hooks such * as `ts-node/register`. * @param {string[]} requests List of modules to preload */ Module._preloadModules = function (requests) { if (!ArrayIsArray(requests) || requests.length === 0) { return; } const parent = new Module("internal/preload", null); // All requested files must be resolved against cwd parent.paths = Module._nodeModulePaths(process.cwd()); for (let i = 0; i < requests.length; i++) { parent.require(requests[i]); } }; Module.prototype.load = function (filename) { if (this.loaded) { throw new Error("Module already loaded"); } // Canonicalize the path so it's not pointing to the symlinked directory // in `node_modules` directory of the referrer. // When load hooks are active, the file may not exist on disk (virtual // modules), so we fall back to the original filename. let hasLoadHooks = false; if (hookEntries.length > 0 && !insideLoadHook) { for (let i = 0; i < hookEntries.length; i++) { if (hookEntries[i].load !== null) { hasLoadHooks = true; break; } } } if (hasLoadHooks) { try { this.filename = op_require_real_path(filename); } catch { this.filename = filename; } } else { this.filename = op_require_real_path(filename); } this.paths = Module._nodeModulePaths(pathDirname(this.filename)); // Run load hooks if registered if (hasLoadHooks) { { let fileUrl; if (StringPrototypeStartsWith(this.filename, "node:")) { fileUrl = this.filename; } else if ( StringPrototypeStartsWith(this.filename, "file://") || StringPrototypeIncludes(this.filename, "://") ) { // Already a URL (e.g. from a resolve hook returning a virtual URL) fileUrl = this.filename; } else { fileUrl = url.pathToFileURL(this.filename).href; } const context = { format: undefined, conditions: ["node", "require"], importAttributes: { __proto__: null }, }; insideLoadHook = true; let result; try { result = executeLoadHookChain(fileUrl, context); } finally { insideLoadHook = false; } if (result != null && result.source != null) { const format = result.format; const source = loadHookSourceToString(result.source); if (format === "module") { loadESMFromCJS(this, this.filename, source, true); } else if (format === "commonjs") { this._compile(source, this.filename, "commonjs"); } else if (format === "json") { try { this.exports = JSONParse(stripBOM(source)); } catch (err) { err.message = this.filename + ": " + err.message; throw err; } } else { // Default to CJS when format is unspecified this._compile(source, this.filename, undefined, true); } this.loaded = true; return; } } } const extension = findLongestRegisteredExtension(filename); Module._extensions[extension](this, this.filename); this.loaded = true; // TODO: do caching }; // Loads a module at the given file path. Returns that module's // `exports` property. const moduleRequireDc = diagnosticsChannel.tracingChannel("module.require"); Module.prototype.require = function (id) { if (typeof id !== "string") { throw new internalErrors.ERR_INVALID_ARG_TYPE("id", "string", id); } if (id === "") { throw new internalErrors.ERR_INVALID_ARG_VALUE( "id", id, "must be a non-empty string", ); } requireDepth++; // `tracingChannel('module.require').traceSync` publishes: // start: { parentFilename, id } before the load // end: { parentFilename, id, result } on success (in finally) // error: { parentFilename, id, error } when require throws; end still // fires in finally with the error context, matching Node. const parentFilename = this.filename; try { if (moduleRequireDc.hasSubscribers) { return moduleRequireDc.traceSync( Module._load, { parentFilename, id }, // deno-lint-ignore no-undef Module, id, this, /* isMain */ false, ); } return Module._load(id, this, /* isMain */ false); } finally { requireDepth--; } }; const wrapper = [ "(function (exports, require, module, __filename, __dirname) { ", "\n});", ]; export let wrap = function (script) { script = script.replace(/^#!.*?\n/, ""); return `${Module.wrapper[0]}${script}${Module.wrapper[1]}`; }; let wrapperProxy = new Proxy(wrapper, { set(target, property, value, receiver) { patched = true; return ReflectSet(target, property, value, receiver); }, defineProperty(target, property, descriptor) { patched = true; return ObjectDefineProperty(target, property, descriptor); }, }); ObjectDefineProperty(Module, "wrap", { get() { return wrap; }, set(value) { patched = true; wrap = value; }, }); ObjectDefineProperty(Module, "wrapper", { get() { return wrapperProxy; }, set(value) { patched = true; wrapperProxy = value; }, }); function isEsmSyntaxError(error) { return error instanceof SyntaxError && ( StringPrototypeIncludes( error.message, "Cannot use import statement outside a module", ) || StringPrototypeIncludes(error.message, "Unexpected token 'export'") ); } function enrichCJSError(error) { if (isEsmSyntaxError(error)) { console.error( 'To load an ES module, set "type": "module" in the package.json or use ' + "the .mjs extension.", ); } } function wrapSafe( filename, content, cjsModuleInstance, format, ) { let f; let err; if (patched) { [f, err] = core.evalContext( Module.wrap(content), url.pathToFileURL(filename).toString(), [format !== "module"], ); } else { [f, err] = core.compileFunction( content, url.pathToFileURL(filename).toString(), [format !== "module"], [ "exports", "require", "module", "__filename", "__dirname", ], ); } if (err) { if (process.mainModule === cjsModuleInstance) { enrichCJSError(err.thrown); } throw err.thrown; } return f; } Module.prototype._compile = function ( content, filename, format, sourceFromHook = false, ) { const useSourceImport = sourceFromHook || SetPrototypeDelete(cjsHookResolvedFilenames, filename); if (format === "module") { return loadESMFromCJS(this, filename, content, useSourceImport); } let compiledWrapper; try { compiledWrapper = wrapSafe(filename, content, this, format); } catch (err) { if ( format !== "commonjs" && err instanceof SyntaxError && (op_require_can_parse_as_esm(content) || isEsmSyntaxError(err)) ) { return loadESMFromCJS(this, filename, content, useSourceImport); } throw err; } const dirname = pathDirname(filename); const require = makeRequireFunction(this); const exports = this.exports; const thisValue = exports; if (requireDepth === 0) { statCache = new SafeMap(); } if (hasInspectBrk && !hasBrokenOnInspectBrk) { hasBrokenOnInspectBrk = true; op_require_break_on_next_statement(); } const result = compiledWrapper.call( thisValue, exports, require, this, filename, dirname, ); if (requireDepth === 0) { statCache = null; } return result; }; Module._extensions[".js"] = function (module, filename) { // We don't define everything on Module.extensions in // order to prevent probing for these files if ( StringPrototypeEndsWith(filename, ".js") || StringPrototypeEndsWith(filename, ".ts") || StringPrototypeEndsWith(filename, ".jsx") || StringPrototypeEndsWith(filename, ".tsx") ) { return loadMaybeCjs(module, filename); } else if (StringPrototypeEndsWith(filename, ".mts")) { return loadESMFromCJS(module, filename); } else if (StringPrototypeEndsWith(filename, ".cts")) { return loadCjs(module, filename); } else { return loadMaybeCjs(module, filename); } }; Module._extensions[".cjs"] = loadCjs; Module._extensions[".mjs"] = loadESMFromCJS; Module._extensions[".wasm"] = loadESMFromCJS; function loadMaybeCjs(module, filename) { const content = op_require_read_file(filename); const format = op_require_is_maybe_cjs(filename) ? undefined : "module"; module._compile(content, filename, format); } function loadCjs(module, filename) { const content = op_require_read_file(filename); module._compile(content, filename, "commonjs"); } // Walks the chain of first-requiring parents, innermost first. The chain is // the require() stack at first load and so is acyclic, but a `seen` guard // keeps a corrupted cache from spinning here forever. function getRequireStack(parent) { const requireStack = []; const seen = new SafeSet(); for (let cursor = parent; cursor; cursor = moduleParentCache.get(cursor)) { if (SetPrototypeHas(seen, cursor)) break; SetPrototypeAdd(seen, cursor); ArrayPrototypePush(requireStack, cursor.filename || cursor.id); } return requireStack; } function _throwRequireAsyncModule(specifier, module) { // Use moduleParentCache directly to avoid triggering the module.parent // deprecation getter when --pending-deprecation is set. const parentModule = module ? moduleParentCache.get(module) : undefined; const parent = parentModule?.filename ?? "<unknown>"; throw new internalErrors.ERR_REQUIRE_ASYNC_MODULE( specifier, parent, getRequireStack(parentModule), ); } function loadESMFromCJS(module, filename, code, sourceFromHook = false) { const specifier = url.pathToFileURL(filename).toString(); let namespace; try { namespace = sourceFromHook && code !== undefined ? op_import_sync_with_source(specifier, code) : op_import_sync(specifier); } catch (e) { if ( e instanceof Error && StringPrototypeIncludes( e.message, "Top-level await is not allowed in synchronous evaluation", ) ) { _throwRequireAsyncModule(specifier, module); } throw e; } if (ObjectHasOwn(namespace, "module.exports")) { module.exports = namespace["module.exports"]; } else { module.exports = namespace; } } function stripBOM(content) { if (StringPrototypeCharCodeAt(content, 0) === 0xfeff) { content = StringPrototypeSlice(content, 1); } return content; } // Native extension for .json Module._extensions[".json"] = function (module, filename) { const content = op_require_read_file(filename); try { module.exports = JSONParse(stripBOM(content)); } catch (err) { err.message = filename + ": " + err.message; throw err; } }; // Async hooks wrappers for NAPI - called from Rust via V8 function calls. function napiAsyncHooksEmitInit(asyncId, type, triggerAsyncId, resource) { internalAsyncHooksEmitInit(asyncId, type, triggerAsyncId, resource); } function napiAsyncHooksEmitBefore(asyncId) { internalAsyncHooksEmitBefore(asyncId); } function napiAsyncHooksEmitAfter(asyncId) { internalAsyncHooksEmitAfter(asyncId); } function napiAsyncHooksEmitDestroy(asyncId) { internalAsyncHooksEmitDestroy(asyncId); } // Native extension for .node Module._extensions[".node"] = function (module, filename) { if (filename.endsWith("cpufeatures.node")) { throw new Error("Using cpu-features module is currently not supported"); } module.exports = op_napi_open( filename, globalThis, buffer.Buffer.from, reportError, napiAsyncHooksEmitInit, napiAsyncHooksEmitBefore, napiAsyncHooksEmitAfter, napiAsyncHooksEmitDestroy, ); }; function createRequireFromPath(filename, sourceURL) { const proxyPath = op_require_proxy_path(filename) ?? filename; const mod = new Module(proxyPath); mod.filename = proxyPath; mod.paths = Module._nodeModulePaths(mod.path); if (sourceURL !== undefined) { // Preserve the original URL (with query/hash) for resolve hooks' // `context.parentURL`, which would otherwise lose those parts via // pathToFileURL(filename). mod[kSourceURL] = sourceURL; } return makeRequireFunction(mod); } function makeRequireFunction(mod) { const require = function require(path) { return mod.require(path); }; function resolve(request, options) { options = options == null ? {} : { __proto__: null, ...options }; options[requireResolveOptionsMarker] = true; return Module._resolveFilename(request, mod, false, options); } require.resolve = resolve; function paths(request) { return Module._resolveLookupPaths(request, mod); } resolve.paths = paths; // Use ObjectDefineProperty so user-installed Object.prototype.main setters // are not invoked when require() is constructed. Mirrors setOwnProperty() // in Node's lib/internal/modules/helpers.js. ObjectDefineProperty(require, "main", { __proto__: null, configurable: true, enumerable: true, value: mainModule, writable: true, }); // Enable support to add extra extension types. require.extensions = Module._extensions; require.cache = Module._cache; return require; } // Matches to: // - /foo/... // - \foo\... // - C:/foo/... // - C:\foo\... const RE_START_OF_ABS_PATH = /^([/\\]|[a-zA-Z]:[/\\])/; const RE_URL_SCHEME = /^[a-zA-Z][a-zA-Z\d+\-.]*:/; function isAbsolute(filenameOrUrl) { return RE_START_OF_ABS_PATH.test(filenameOrUrl); } // Match Node's error reason (see lib/internal/modules/cjs/loader.js). const kCreateRequireError = "must be a file URL object, file URL string, or absolute path string"; function createRequire(filenameOrUrl) { let fileUrlStr; if (filenameOrUrl instanceof URL) { if (filenameOrUrl.protocol !== "file:") { throw new internalErrors.ERR_INVALID_ARG_VALUE( "filename", filenameOrUrl, kCreateRequireError, ); } fileUrlStr = filenameOrUrl.toString(); } else if (typeof filenameOrUrl === "string") { if (!filenameOrUrl.startsWith("file:") && !isAbsolute(filenameOrUrl)) { throw new internalErrors.ERR_INVALID_ARG_VALUE( "filename", filenameOrUrl, kCreateRequireError, ); } fileUrlStr = filenameOrUrl; } else { throw new internalErrors.ERR_INVALID_ARG_VALUE( "filename", filenameOrUrl, kCreateRequireError, ); } const filename = op_require_as_file_path(fileUrlStr) ?? fileUrlStr; return createRequireFromPath(filename, fileUrlStr); } function isBuiltin(moduleName) { if (typeof moduleName !== "string") { return false; } if (StringPrototypeStartsWith(moduleName, "node:")) { moduleName = StringPrototypeSlice(moduleName, 5); } else if (moduleName === "test" || moduleName === "test/reporters") { // test is only a builtin if it has the "node:" scheme // see https://github.com/nodejs/node/blob/73025c4dec042e344eeea7912ed39f7b7c4a3991/test/parallel/test-module-isBuiltin.js#L14 return false; } return moduleName in nativeModuleExports && !StringPrototypeStartsWith(moduleName, "internal/"); } function getBuiltinModule(id) { if (typeof id !== "string") { throw new internalErrors.ERR_INVALID_ARG_TYPE("id", "string", id); } if (!isBuiltin(id)) { return undefined; } if (StringPrototypeStartsWith(id, "node:")) { // Slice 'node:' prefix id = StringPrototypeSlice(id, 5); } const mod = loadNativeModule(id, id); if (mod) { return mod.exports; } return undefined; } Module.isBuiltin = isBuiltin; Module.createRequire = createRequire; function packageNameFromBareSpecifier(specifier) { if ( op_require_is_request_relative(specifier) || isAbsolute(specifier) || RegExpPrototypeTest(RE_URL_SCHEME, specifier) ) { return null; } const parts = StringPrototypeSplit(specifier, "/"); if (parts[0] === "") { return null; } if (StringPrototypeStartsWith(parts[0], "@")) { if (parts.length < 2 || parts[1] === "") { return specifier; } return `${parts[0]}/${parts[1]}`; } return parts[0]; } function findClosestPackageJSON(filePath) { let currentPath = stat(filePath) === 1 ? filePath : pathDirname(filePath); while (true) { const packageJsonPath = pathResolve(currentPath, "package.json"); if (op_require_read_package_scope(packageJsonPath)) { return toRealPath(packageJsonPath); } const parentPath = pathDirname(currentPath); if (parentPath === currentPath) { return undefined; } currentPath = parentPath; } } function basePathFromFileURLOrPath(base) { if (base instanceof URL) { if (base.protocol !== "file:") { throw new internalErrors.ERR_INVALID_URL_SCHEME("file"); } return op_require_as_file_path(base.href); } if (typeof base !== "string") { throw new internalErrors.ERR_INVALID_ARG_TYPE("base", "string", base); } if (StringPrototypeStartsWith(base, "file:")) { return op_require_as_file_path(base); } return base; } function findPackageJSONForBareSpecifier(packageName, base) { if (base === undefined) { return undefined; } const basePath = basePathFromFileURLOrPath(base); const baseDir = stat(basePath) === 1 ? basePath : pathDirname(basePath); const parent = new Module("", null); parent.filename = pathResolve(baseDir, "$deno$find_package_json.js"); parent.paths = Module._nodeModulePaths(baseDir); const lookupPaths = Module._resolveLookupPaths(packageName, parent); if (lookupPaths === null) { return undefined; } for (let i = 0; i < lookupPaths.length; i++) { const lookupPath = lookupPaths[i]; const candidatePackageJsonPaths = [ pathResolve(lookupPath, packageName, "package.json"), pathResolve(lookupPath, "package.json"), ]; for (let j = 0; j < candidatePackageJsonPaths.length; j++) { const packageJsonPath = candidatePackageJsonPaths[j]; if (op_require_read_package_scope(packageJsonPath)) { return toRealPath(packageJsonPath); } } } return undefined; } function pathFromResolvedFileUrl(resolved) { if (!StringPrototypeStartsWith(resolved, "file:")) { throw new internalErrors.ERR_INVALID_URL_SCHEME("file"); } return op_require_as_file_path(resolved); } function resolveSpecifierForPackageJSON(specifier, base) { if (specifier instanceof URL) { return specifier.href; } specifier = String(specifier); if (StringPrototypeStartsWith(specifier, "file:")) { return specifier; } if (RegExpPrototypeTest(RE_URL_SCHEME, specifier)) { return specifier; } let parentURL = "data:"; if (base !== undefined) { if (base instanceof URL) { parentURL = base.href; } else if (typeof base === "string") { parentURL = base; } else { throw new internalErrors.ERR_INVALID_ARG_TYPE("base", "string", base); } } return op_module_default_resolve(specifier, parentURL); } function findPackageJSON(specifier, base = undefined) { const specifierString = specifier instanceof URL ? specifier.href : String(specifier); const packageName = packageNameFromBareSpecifier(specifierString); if (packageName !== null) { const packageJsonPath = findPackageJSONForBareSpecifier(packageName, base); if (packageJsonPath !== undefined) { return packageJsonPath; } } const resolved = resolveSpecifierForPackageJSON(specifier, base); const filePath = pathFromResolvedFileUrl(resolved); return findClosestPackageJSON(filePath); } Module.findPackageJSON = findPackageJSON; Module._initPaths = function () { const paths = op_require_init_paths(); modulePaths = paths; Module.globalPaths = ArrayPrototypeSlice(modulePaths); }; function syncBuiltinESMExports() {} Module.syncBuiltinESMExports = syncBuiltinESMExports; // Mostly used by tools like ts-node. Module.runMain = function () { Module._load(process.argv[1], null, true); }; Module.Module = Module; nativeModuleExports.module = Module; // Modules that emit a deprecation warning the first time they are required via // the CJS loader (`require('_stream_readable')` etc.). Maps the module name to // [message, code]. Matches Node's `BuiltinModule#compileForPublicLoader` -- // `process.getBuiltinModule()` does NOT trigger these warnings. const deprecatedNativeModules = ObjectCreate(null); deprecatedNativeModules._tls_common = [ "The _tls_common module is deprecated. Use `node:tls` instead.", "DEP0192", ]; deprecatedNativeModules._tls_wrap = [ "The _tls_wrap module is deprecated. Use `node:tls` instead.", "DEP0192", ]; deprecatedNativeModules._stream_duplex = [ "The _stream_duplex module is deprecated. Use `node:stream` instead.", "DEP0193", ]; deprecatedNativeModules._stream_passthrough = [ "The _stream_passthrough module is deprecated. Use `node:stream` instead.", "DEP0193", ]; deprecatedNativeModules._stream_readable = [ "The _stream_readable module is deprecated. Use `node:stream` instead.", "DEP0193", ]; deprecatedNativeModules._stream_transform = [ "The _stream_transform module is deprecated. Use `node:stream` instead.", "DEP0193", ]; deprecatedNativeModules._stream_writable = [ "The _stream_writable module is deprecated. Use `node:stream` instead.", "DEP0193", ]; deprecatedNativeModules.punycode = [ "The `punycode` module is deprecated. Please use a userland " + "alternative instead.", "DEP0040", ]; const emittedNativeModuleDeprecations = new SafeSet(); function maybeEmitNativeModuleDeprecation(request) { const deprecation = deprecatedNativeModules[request]; if (deprecation === undefined) return; if (SetPrototypeHas(emittedNativeModuleDeprecations, request)) return; SetPrototypeAdd(emittedNativeModuleDeprecations, request); process.emitWarning( deprecation[0], "DeprecationWarning", deprecation[1], ); } function loadNativeModule(_id, request) { if (nativeModulePolyfill.has(request)) { return nativeModulePolyfill.get(request); } const modExports = nativeModuleExports[request]; if (modExports) { const nodeMod = new Module(request); nodeMod.exports = modExports; nodeMod.loaded = true; nativeModulePolyfill.set(request, nodeMod); return nodeMod; } return undefined; } function nativeModuleCanBeRequiredByUsers(request) { // `in` rather than bracket access avoids triggering the lazy getters // installed by `defineLazyNativeModule`. return request in nativeModuleExports; } /** @param specifier {string} */ function packageSpecifierSubPath(specifier) { let parts = StringPrototypeSplit(specifier, "/"); if (StringPrototypeStartsWith(parts[0], "@")) { parts = ArrayPrototypeSlice(parts, 2); } else { parts = ArrayPrototypeSlice(parts, 1); } return ArrayPrototypeJoin(parts, "/"); } // VLQ Base64 decoding for source maps const BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; const BASE64_LOOKUP = new Int32Array(128); for (let i = 0; i < 128; i++) BASE64_LOOKUP[i] = -1; for (let i = 0; i < BASE64_CHARS.length; i++) { BASE64_LOOKUP[StringPrototypeCharCodeAt(BASE64_CHARS, i)] = i; } const VLQ_BASE_SHIFT = 5; const VLQ_BASE = 1 << VLQ_BASE_SHIFT; // 32 const VLQ_BASE_MASK = VLQ_BASE - 1; // 31 const VLQ_CONTINUATION_BIT = VLQ_BASE; // 32 /** * Decode a single VLQ value from a string iterator. * @param {string} str * @param {{ pos: number }} iter * @returns {number} */ function decodeVLQ(str, iter) { let result = 0; let shift = 0; let digit; do { if (iter.pos >= str.length) { return 0; } const charCode = StringPrototypeCharCodeAt(str, iter.pos++); digit = BASE64_LOOKUP[charCode]; if (digit === -1) { return 0; } result += (digit & VLQ_BASE_MASK) << shift; shift += VLQ_BASE_SHIFT; } while (digit & VLQ_CONTINUATION_BIT); // The sign is encoded in the least significant bit const negative = result & 1; // Use unsigned right shift, so that the 32nd bit is properly shifted // to the 31st, and the 32nd becomes unset. result >>>= 1; if (!negative) { return result; } // We need to OR here to ensure the 32nd bit (the sign bit in an Int32) is // always set for negative numbers. If `result` were 1, (meaning `negative` // is true and all other bits were zeros), `result` would now be 0. But -0 // doesn't flip the 32nd bit as intended. return -result | (1 << 31); } /** * Parse VLQ-encoded source map mappings string into an array of mapping entries. * @param {string} mappings * @param {string[]} sources * @param {string} sourceRoot * @returns {Array<{generatedLine: number, generatedColumn: number, originalSource: string, originalLine: number, originalColumn: number, name?: string}>} */ function parseMappings(mappings, sources, names, sourceRoot) { const entries = []; if (!mappings) return entries; let generatedLine = 0; let previousGeneratedColumn = 0; let previousOriginalLine = 0; let previousOriginalColumn = 0; let previousSource = 0; let previousName = 0; const iter = { pos: 0 }; while (iter.pos < mappings.length) { const ch = mappings[iter.pos]; if (ch === ";") { generatedLine++; previousGeneratedColumn = 0; iter.pos++; continue; } if (ch === ",") { iter.pos++; continue; } // Decode segment: generatedColumn, [sourceIndex, originalLine, originalColumn, [nameIndex]] const generatedColumn = previousGeneratedColumn + decodeVLQ(mappings, iter); previousGeneratedColumn = generatedColumn; // Check if there are more fields (source mapping) if (iter.pos < mappings.length) { const next = mappings[iter.pos]; if (next !== "," && next !== ";") { const sourceIndex = previousSource + decodeVLQ(mappings, iter); previousSource = sourceIndex; const originalLine = previousOriginalLine + decodeVLQ(mappings, iter); previousOriginalLine = originalLine; const originalColumn = previousOriginalColumn + decodeVLQ(mappings, iter); previousOriginalColumn = originalColumn; let source = sources[sourceIndex] || ""; if ( sourceRoot && !StringPrototypeStartsWith(source, "/") && !RegExpPrototypeTest(/^\w+:\/\//, source) ) { source = sourceRoot + source; } let name; // Check for optional name index if ( iter.pos < mappings.length && mappings[iter.pos] !== "," && mappings[iter.pos] !== ";" ) { const nameIndex = previousName + decodeVLQ(mappings, iter); previousName = nameIndex; name = names ? names[nameIndex] : undefined; } ArrayPrototypePush(entries, { generatedLine, generatedColumn, originalSource: source, originalLine, originalColumn, name, }); } } // Segments with only generated column (no source mapping) are skipped, // matching Node.js behavior - only full mapping entries are included. } return entries; } /** * Compare two source map entries for sorting/binary search. */ function compareEntries(a, b) { if (a.generatedLine !== b.generatedLine) { return a.generatedLine - b.generatedLine; } return a.generatedColumn - b.generatedColumn; } /** * Binary search for the entry that contains the given generated position. */ function findEntryInMappings(entries, line, column) { let low = 0; let high = entries.length - 1; let best = -1; while (low <= high) { const mid = (low + high) >> 1; const entry = entries[mid]; const cmp = entry.generatedLine - line || entry.generatedColumn - column; if (cmp === 0) { return entry; } else if (cmp < 0) { best = mid; low = mid + 1; } else { high = mid - 1; } } if (best >= 0) { const entry = entries[best]; if (entry.generatedLine === line) { return entry; } } return null; } /** * Deep clone an object (simple JSON-safe objects). */ function deepClone(obj) { if (obj === null || typeof obj !== "object") return obj; if (ArrayIsArray(obj)) return ArrayPrototypeMap(obj, deepClone); const clone = {}; const keys = ObjectKeys(obj); for (let i = 0; i < keys.length; i++) { clone[keys[i]] = deepClone(obj[keys[i]]); } return clone; } /** * SourceMap class implementing Node.js's module.SourceMap API. * @see https://nodejs.org/api/module.html#class-modulesourcemap */ class SourceMap { #payload; #lineLengths; #mappings; /** * @param {object} payload - Source Map V3 payload object * @param {{ lineLengths?: number[] }} [options] */ constructor(payload, options) { if ( typeof payload !== "object" || payload === null || ArrayIsArray(payload) ) { let received; if (payload === null) { received = " Received null"; } else if (typeof payload === "object") { const proto = ObjectGetPrototypeOf(payload); const name = proto?.constructor?.name; received = name ? ` Received an instance of ${name}` : ` Received ${typeof payload}`; } else { let inspected = String(payload); if (inspected.length > 28) { inspected = StringPrototypeSlice(inspected, 0, 25) + "..."; } received = ` Received type ${typeof payload} (${inspected})`; } const err = new TypeError( `The "payload" argument must be of type object.${received}`, ); err.code = "ERR_INVALID_ARG_TYPE"; throw err; } this.#payload = deepClone(payload); this.#lineLengths = options?.lineLengths ? ArrayPrototypeSlice(options.lineLengths) : undefined; // Parse mappings - handle both regular and index source maps this.#mappings = this.#parseMap(payload); // Sort entries by generated position ArrayPrototypeSort(this.#mappings, compareEntries); } /** * Parse source map payload into mapping entries. * Handles both regular source maps and index source maps (with sections). */ #parseMap(payload) { if (payload.sections) { // Index Source Map V3 const entries = []; const sections = payload.sections; for (let i = 0; i < sections.length; i++) { const section = sections[i]; const offset = section.offset || { line: 0, column: 0 }; const map = section.map; const sectionEntries = parseMappings( map.mappings, map.sources || [], map.names || [], map.sourceRoot || "", ); // Apply section offset for (let j = 0; j < sectionEntries.length; j++) { const entry = sectionEntries[j]; entry.generatedLine += offset.line; if (entry.generatedLine === offset.line) { entry.generatedColumn += offset.column; } ArrayPrototypePush(entries, entry); } } // For index maps, flatten the sources and mappings into the payload clone if (!this.#payload.sources) { this.#payload.sources = []; } if (!this.#payload.mappings) { this.#payload.mappings = payload.mappings || undefined; } return entries; } return parseMappings( payload.mappings, payload.sources || [], payload.names || [], payload.sourceRoot || "", ); } /** * Getter for the payload used to construct the SourceMap instance. * Returns a clone of the original payload. */ get payload() { return this.#payload; } /** * Getter for line lengths, if provided in the constructor options. */ get lineLengths() { return this.#lineLengths; } /** * Given a 0-indexed line offset and column offset in the generated source, * returns an object representing the SourceMap range in the original file * if found, or an empty object if not. * * @param {number} lineOffset - Zero-indexed line number in generated source * @param {number} columnOffset - Zero-indexed column number in generated source * @returns {{ generatedLine: number, generatedColumn: number, originalSource: string, originalLine: number, originalColumn: number } | {}} */ findEntry(lineOffset, columnOffset) { if (this.#mappings.length === 0) return {}; const entry = findEntryInMappings(this.#mappings, lineOffset, columnOffset); if (!entry) return {}; return { generatedLine: entry.generatedLine, generatedColumn: entry.generatedColumn, originalSource: entry.originalSource, originalLine: entry.originalLine, originalColumn: entry.originalColumn, }; } /** * Given 1-indexed lineNumber and columnNumber from a call site in the generated * source, find the corresponding call site location in the original source. * * @param {number} lineNumber - 1-indexed line number * @param {number} columnNumber - 1-indexed column number * @returns {{ name?: string, fileName: string, lineNumber: number, columnNumber: number } | {}} */ findOrigin(lineNumber, columnNumber) { const entry = this.findEntry(lineNumber - 1, columnNumber - 1); if ( entry.originalSource === undefined || entry.originalLine === undefined || entry.originalColumn === undefined || entry.generatedLine === undefined || entry.generatedColumn === undefined ) { return {}; } const lineOffset = lineNumber - entry.generatedLine; const columnOffset = columnNumber - entry.generatedColumn; const result = { fileName: entry.originalSource, lineNumber: entry.originalLine + lineOffset, columnNumber: entry.originalColumn + columnOffset, }; if (entry.name !== undefined) { result.name = entry.name; } return result; } } // Cache for findSourceMap: path -> SourceMap | null (null means checked but not found) const sourceMapCache = new SafeMap(); // Regex to match //# sourceMappingURL=<url> or //@ sourceMappingURL=<url> const SOURCE_MAP_URL_RE = /\/\/[#@]\s*sourceMappingURL\s*=\s*(\S+)\s*(?:\n|\r\n?)?$/; /** * Extract the sourceMappingURL from the last non-empty line of content. * @param {string} content * @returns {string | null} */ function extractSourceMapUrl(content) { // Search backwards from the end for the sourceMappingURL comment. // The comment must appear in the last non-empty line. const match = RegExpPrototypeExec(SOURCE_MAP_URL_RE, content); return match ? match[1] : null; } /** * Resolve a source map from a sourceMappingURL. * Handles both inline data URIs and external file references. * @param {string} url - The sourceMappingURL value * @param {string} filePath - The path of the file containing the reference * @returns {object | null} - Parsed source map payload or null */ function resolveSourceMapPayload(url, filePath) { // Handle inline base64 data URIs if (StringPrototypeStartsWith(url, "data:")) { const dataUrlMatch = StringPrototypeMatch( url, /^data:application\/json;(?:charset=utf-?8;)?base64,(.+)$/, ); if (dataUrlMatch) { try { const decoded = atob(dataUrlMatch[1]); return JSONParse(decoded); } catch { return null; } } return null; } // Handle external source map files try { let mapPath; if ( StringPrototypeStartsWith(url, "/") || RegExpPrototypeTest(/^[a-zA-Z]:\\/, url) ) { // Absolute path mapPath = url; } else { // Relative path - resolve against the source file's directory const dir = op_require_path_dirname(filePath); mapPath = op_require_path_resolve([dir, url]); } const mapContent = op_require_read_file(mapPath); if (mapContent) { return JSONParse(mapContent); } } catch { // File not found or invalid JSON - return null } return null; } /** * @param {string} path * @returns {SourceMap | undefined} */ export function findSourceMap(path) { // Normalize the path to avoid duplicate cache entries for equivalent paths // (e.g. "/foo/bar.js" vs "/foo/./bar.js") path = op_require_path_resolve([path]); if (sourceMapCache.has(path)) { const cached = sourceMapCache.get(path); return cached === null ? undefined : cached; } try { const content = op_require_read_file(path); if (!content) { sourceMapCache.set(path, null); return undefined; } const url = extractSourceMapUrl(content); if (!url) { sourceMapCache.set(path, null); return undefined; } const payload = resolveSourceMapPayload(url, path); if (!payload) { sourceMapCache.set(path, null); return undefined; } // Compute lineLengths from the source file content const lines = StringPrototypeSplit( StringPrototypeReplace(content, /\n$/, ""), "\n", ); const lineLengths = []; for (let i = 0; i < lines.length; i++) { ArrayPrototypePush(lineLengths, lines[i].length); } const sourceMap = new SourceMap(payload, { lineLengths }); sourceMapCache.set(path, sourceMap); return sourceMap; } catch { sourceMapCache.set(path, null); return undefined; } } Module.findSourceMap = findSourceMap; Module.SourceMap = SourceMap; /** * @param {string} code * @param {{ mode?: "strip" | "transform", sourceMap?: boolean, sourceUrl?: string }} [options] * @returns {string} */ export function stripTypeScriptTypes(code, options = undefined) { if (typeof code !== "string") { throw new internalErrors.ERR_INVALID_ARG_TYPE("code", "string", code); } if ( options !== undefined && (typeof options !== "object" || options === null) ) { throw new internalErrors.ERR_INVALID_ARG_TYPE("options", "object", options); } const mode = options?.mode ?? "strip"; if (mode !== "strip" && mode !== "transform") { throw new internalErrors.ERR_INVALID_ARG_VALUE( "options.mode", mode, "must be one of: 'strip', 'transform'", ); } if ( options?.sourceMap !== undefined && typeof options.sourceMap !== "boolean" ) { throw new internalErrors.ERR_INVALID_ARG_TYPE( "options.sourceMap", "boolean", options.sourceMap, ); } if ( options?.sourceUrl !== undefined && typeof options.sourceUrl !== "string" ) { throw new internalErrors.ERR_INVALID_ARG_TYPE( "options.sourceUrl", "string", options.sourceUrl, ); } const sourceMap = options?.sourceMap === true; if (mode === "strip" && sourceMap) { throw new internalErrors.ERR_INVALID_ARG_VALUE( "options.sourceMap", sourceMap, "must be one of: false, undefined", ); } let result; try { result = op_node_strip_typescript_types(code, mode, sourceMap); } catch (err) { if (mode === "strip") { const syntaxError = new SyntaxError(err.message); syntaxError.code = "ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX"; throw syntaxError; } throw err; } if (!sourceMap && options?.sourceUrl !== undefined) { result += `\n\n//# sourceURL=${options.sourceUrl}`; } return result; } Module.stripTypeScriptTypes = stripTypeScriptTypes; /** * @param {string | URL} _specifier * @param {string | URL} _parentUrl * @param {{ parentURL: string | URL, data: any, transferList: any[] }} [_options] */ export function register(_specifier, _parentUrl, _options) { // TODO(@marvinhagemeister): Stub implementation for programs registering // TypeScript loaders. We don't support registering loaders for file // types that Deno itself doesn't support at the moment. return undefined; } /** * Register synchronous module loader hooks. * @param {{ resolve?: Function, load?: Function }} hooks * @returns {{ deregister: () => void }} */ export function registerHooks(hooks) { const { resolve, load } = hooks; if (resolve) { internalValidators.validateFunction(resolve, "hooks.resolve"); } if (load) { internalValidators.validateFunction(load, "hooks.load"); } const entry = { resolve: typeof resolve === "function" ? resolve : null, load: typeof load === "function" ? load : null, }; ArrayPrototypePush(hookEntries, entry); // Activate ESM hooks in Rust module loader _activateEsmHooks(); return { deregister() { const idx = ArrayPrototypeIndexOf(hookEntries, entry); if (idx !== -1) { ArrayPrototypeSplice(hookEntries, idx, 1); } // Update Rust-side active flags _activateEsmHooks(); }, }; } Module.registerHooks = registerHooks; let initialized = false; function initialize(args) { const { usesLocalNodeModulesDir: usesLocalNodeModulesDirArg, argv0, runningOnMainThread, workerId, maybeWorkerMetadata, nodeDebug, nodeClusterUniqueId, nodeClusterSchedPolicy, warmup = false, moduleSpecifier = null, } = args; if (!warmup) { if (initialized) { throw new Error("Node runtime already initialized"); } initialized = true; if (usesLocalNodeModulesDirArg) { usesLocalNodeModulesDir = true; } internals.__bootstrapNodeProcess( argv0, Deno.args, Deno.version, nodeDebug ?? "", false, runningOnMainThread, ); internals.__initWorkerThreads( runningOnMainThread, workerId, maybeWorkerMetadata, moduleSpecifier, ); // `child_process.ts` is in `lazy_loaded_js` (see ext/node/lib.rs), so its // module body - which registers `internals.__setupChildProcessIpcChannel` // - only runs once `loadExtScript` is called. Skip both when there is no // IPC pipe configured. (NOTE: under node-defer this `initialize` does not // auto-run, so a forked IPC child does not yet get this setup -- known // follow-up; see process.ts bootstrap trigger.) if (op_node_has_child_ipc_pipe()) { core.loadExtScript("ext:deno_node/child_process.ts"); internals.__setupChildProcessIpcChannel(); } if (nodeClusterUniqueId) { core.loadExtScript("ext:deno_node/cluster.ts"); internals.__initCluster(nodeClusterUniqueId, nodeClusterSchedPolicy); } // (stream-wrap GothamState registration moved to process.ts's // __bootstrapNodeProcess, which this calls above at 3090 -- single // registration point that also covers the node-defer path.) nativeModuleExports["internal/console/constructor"].bindStreamsLazy( nativeModuleExports["console"], nativeModuleExports["process"], ); nativeModuleExports["internal/console/constructor"].bindStreamsLazy( globalThis.console, nativeModuleExports["process"], ); } else { internals.__bootstrapNodeProcess( undefined, undefined, undefined, undefined, true, ); } } globalThis.nodeBootstrap = initialize; // node-defer: `initialize()` is the only place that sets // `usesLocalNodeModulesDir`, but it does not auto-run when node:module is // loaded lazily (see below). Apply the node_modules-dir mode from the stashed // bootstrap args at module-eval so `require.resolve(x, { paths })` and the // bare-specifier resolution fallback behave the same as in the eager path. if (!initialized && internals.__nodeBootstrapArgs?.usesLocalNodeModulesDir) { usesLocalNodeModulesDir = true; } // Pre-enable any trace event categories requested via the spawning process's // --trace-event-categories flag (propagated as an env var by child_process). // Runs at module-eval (not inside `initialize`, which doesn't auto-run under // node-defer) so node.async_hooks tracing works in every isolate, including // worker threads. No-ops unless tracing was explicitly requested, so it never // forces node:process to load for ordinary programs. let traceEventsPreEnabled = false; function preEnableTraceEvents() { if (traceEventsPreEnabled) { return; } traceEventsPreEnabled = true; const traceCategoriesEnv = op_get_env_no_permission_check( "DENO_NODE_TRACE_EVENT_CATEGORIES", ); if (!traceCategoriesEnv) { return; } const categories = traceCategoriesEnv.split(",").filter((c) => c.length > 0); if (categories.length === 0) { return; } const traceEvents = core.loadExtScript("ext:deno_node/trace_events.ts"); // Surface the flag through process.execArgv so test fixtures that probe it // (e.g. node's test-trace-events-api) see the same shape they would in Node. const proc = nativeModuleExports["process"]; if (proc && Array.isArray(proc.execArgv)) { proc.execArgv.push("--trace-event-categories", traceCategoriesEnv); } try { traceEvents.createTracing({ categories }).enable(); } catch { // Invalid categories must not block startup. } } preEnableTraceEvents(); // node-defer: node:process's own deferred trigger runs the process half of // the bootstrap (`__bootstrapNodeProcess`) on first node:* use. The other // half of `initialize` (worker_threads alias, IPC, cluster, trace_events) used // to run unconditionally; under node-defer each // piece is now handled where it belongs: // - worker_threads MessageChannel/MessagePort alias: at the bottom of // ext/node/polyfills/worker_threads.ts module body, so importing // node:worker_threads is enough to install the globals. // - IPC fork bootstrap: 99_main.js runs the full eager bootstrap when // `op_node_has_child_ipc_pipe()` is true (forked child path). // - cluster init / trace_events env-var pre-enable: // still pending; only matter when those features are actively used and // are tracked as follow-ups, not regressions for ordinary programs. function closeIdleConnections() { try { const http = nativeModuleExports["http"]; if (http?.globalAgent) { http.globalAgent.destroy(); } } catch { // Ignore } try { const https = nativeModuleExports["https"]; if (https?.globalAgent) { https.globalAgent.destroy(); } } catch { // Ignore } } internals.closeIdleConnections = closeIdleConnections; export { builtinModules, createRequire, findPackageJSON, getBuiltinModule, isBuiltin, Module, SourceMap, syncBuiltinESMExports, }; export const _cache = Module._cache; export const _extensions = Module._extensions; export const _findPath = Module._findPath; export const _initPaths = Module._initPaths; export const _load = Module._load; export const _nodeModulePaths = Module._nodeModulePaths; export const _pathCache = Module._pathCache; export const _preloadModules = Module._preloadModules; export const _resolveFilename = Module._resolveFilename; export const _resolveLookupPaths = Module._resolveLookupPaths; export const _stat = Module._stat; export const globalPaths = Module.globalPaths; export const runMain = Module.runMain; export default Module;