diff options
author | 2023-07-22 04:33:54 -0700 | |
---|---|---|
committer | 2023-07-22 04:33:54 -0700 | |
commit | 3418feb2e99546efe033f72145a0ccc90c7e81ad (patch) | |
tree | db855ccc98ff9358b2783bcbacf17f774ff5f415 | |
parent | c6a3467625fede0fe9901ab53b0aabd651866b64 (diff) | |
download | bun-3418feb2e99546efe033f72145a0ccc90c7e81ad.tar.gz bun-3418feb2e99546efe033f72145a0ccc90c7e81ad.tar.zst bun-3418feb2e99546efe033f72145a0ccc90c7e81ad.zip |
Fixes #3744
-rw-r--r-- | src/bun.js/modules/NodeModuleModule.cpp | 140 | ||||
-rw-r--r-- | test/js/node/module/node-module-module.test.js | 18 |
2 files changed, 142 insertions, 16 deletions
diff --git a/src/bun.js/modules/NodeModuleModule.cpp b/src/bun.js/modules/NodeModuleModule.cpp index 3019ea95c..57fc1834d 100644 --- a/src/bun.js/modules/NodeModuleModule.cpp +++ b/src/bun.js/modules/NodeModuleModule.cpp @@ -8,6 +8,116 @@ using namespace Zig; using namespace JSC; +// This is a mix of bun's builtin module names and also the ones reported by +// node v20.4.0 +static constexpr ASCIILiteral builtinModuleNames[] = { + "_http_agent"_s, + "_http_client"_s, + "_http_common"_s, + "_http_incoming"_s, + "_http_outgoing"_s, + "_http_server"_s, + "_stream_duplex"_s, + "_stream_passthrough"_s, + "_stream_readable"_s, + "_stream_transform"_s, + "_stream_wrap"_s, + "_stream_writable"_s, + "_tls_common"_s, + "_tls_wrap"_s, + "assert"_s, + "assert/strict"_s, + "async_hooks"_s, + "buffer"_s, + "bun"_s, + "bun:events_native"_s, + "bun:ffi"_s, + "bun:jsc"_s, + "bun:sqlite"_s, + "bun:wrap"_s, + "child_process"_s, + "cluster"_s, + "console"_s, + "constants"_s, + "crypto"_s, + "detect-libc"_s, + "dgram"_s, + "diagnostics_channel"_s, + "dns"_s, + "dns/promises"_s, + "domain"_s, + "events"_s, + "fs"_s, + "fs/promises"_s, + "http"_s, + "http2"_s, + "https"_s, + "inspector"_s, + "inspector/promises"_s, + "module"_s, + "net"_s, + "os"_s, + "path"_s, + "path/posix"_s, + "path/win32"_s, + "perf_hooks"_s, + "process"_s, + "punycode"_s, + "querystring"_s, + "readline"_s, + "readline/promises"_s, + "repl"_s, + "stream"_s, + "stream/consumers"_s, + "stream/promises"_s, + "stream/web"_s, + "string_decoder"_s, + "sys"_s, + "timers"_s, + "timers/promises"_s, + "tls"_s, + "trace_events"_s, + "tty"_s, + "undici"_s, + "url"_s, + "util"_s, + "util/types"_s, + "v8"_s, + "vm"_s, + "wasi"_s, + "worker_threads"_s, + "ws"_s, + "zlib"_s, +}; + +static bool isBuiltinModule(const String &namePossiblyWithNodePrefix) { + String name = namePossiblyWithNodePrefix; + if (name.startsWith("node:"_s)) + name = name.substringSharingImpl(5); + + for (auto &builtinModule : builtinModuleNames) { + if (name == builtinModule) + return true; + } + return false; +} + +JSC_DEFINE_HOST_FUNCTION(jsFunctionIsBuiltinModule, + (JSC::JSGlobalObject * globalObject, + JSC::CallFrame *callFrame)) { + JSC::VM &vm = globalObject->vm(); + auto scope = DECLARE_THROW_SCOPE(vm); + JSValue moduleName = callFrame->argument(0); + if (!moduleName.isString()) { + return JSValue::encode(jsBoolean(false)); + } + + auto moduleStr = moduleName.toWTFString(globalObject); + RETURN_IF_EXCEPTION(scope, JSValue::encode(jsBoolean(false))); + + return JSValue::encode(jsBoolean(isBuiltinModule(moduleStr))); +} + JSC_DEFINE_HOST_FUNCTION(jsFunctionNodeModuleCreateRequire, (JSC::JSGlobalObject * globalObject, JSC::CallFrame *callFrame)) { @@ -95,6 +205,9 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionResolveFileName, } } } +template <std::size_t N, class T> consteval std::size_t countof(T (&)[N]) { + return N; +} namespace Zig { void generateNodeModuleModule(JSC::JSGlobalObject *globalObject, @@ -135,6 +248,12 @@ void generateNodeModuleModule(JSC::JSGlobalObject *globalObject, ImplementationVisibility::Public, NoIntrinsic, jsFunctionSourceMap, nullptr)); + append(Identifier::fromString(vm, "isBuiltin"_s), + JSFunction::create(vm, globalObject, 1, String("isBuiltin"_s), + jsFunctionIsBuiltinModule, + ImplementationVisibility::Public, NoIntrinsic, + jsFunctionIsBuiltinModule, nullptr)); + append(JSC::Identifier::fromString(vm, "_resolveFilename"_s), JSFunction::create(vm, globalObject, 3, String("_resolveFilename"_s), jsFunctionResolveFileName, @@ -158,21 +277,12 @@ void generateNodeModuleModule(JSC::JSGlobalObject *globalObject, vm, globalObject->arrayStructureForIndexingTypeDuringAllocation( ArrayWithContiguous), - 7); - builtinModules->putDirectIndex(globalObject, 0, - JSC::jsString(vm, String("node:assert"_s))); - builtinModules->putDirectIndex(globalObject, 1, - JSC::jsString(vm, String("node:buffer"_s))); - builtinModules->putDirectIndex(globalObject, 2, - JSC::jsString(vm, String("node:events"_s))); - builtinModules->putDirectIndex(globalObject, 3, - JSC::jsString(vm, String("node:util"_s))); - builtinModules->putDirectIndex(globalObject, 4, - JSC::jsString(vm, String("node:path"_s))); - builtinModules->putDirectIndex(globalObject, 5, - JSC::jsString(vm, String("bun:ffi"_s))); - builtinModules->putDirectIndex(globalObject, 6, - JSC::jsString(vm, String("bun:sqlite"_s))); + countof(builtinModuleNames)); + + for (unsigned i = 0; i < countof(builtinModuleNames); ++i) { + builtinModules->putDirectIndex( + globalObject, i, JSC::jsString(vm, String(builtinModuleNames[i]))); + } append(JSC::Identifier::fromString(vm, "builtinModules"_s), builtinModules); diff --git a/test/js/node/module/node-module-module.test.js b/test/js/node/module/node-module-module.test.js index 434bac829..fdde93d0e 100644 --- a/test/js/node/module/node-module-module.test.js +++ b/test/js/node/module/node-module-module.test.js @@ -1,7 +1,23 @@ import { expect, test } from "bun:test"; -import { _nodeModulePaths } from "module"; +import { _nodeModulePaths, builtinModules, isBuiltin } from "module"; import Module from "module"; +test("builtinModules exists", () => { + expect(Array.isArray(builtinModules)).toBe(true); + expect(builtinModules).toHaveLength(77); +}); + +test("isBuiltin() works", () => { + expect(isBuiltin("fs")).toBe(true); + expect(isBuiltin("path")).toBe(true); + expect(isBuiltin("crypto")).toBe(true); + expect(isBuiltin("assert")).toBe(true); + expect(isBuiltin("util")).toBe(true); + expect(isBuiltin("events")).toBe(true); + expect(isBuiltin("node:events")).toBe(true); + expect(isBuiltin("node:bacon")).toBe(false); +}); + test("module.globalPaths exists", () => { expect(Array.isArray(require("module").globalPaths)).toBe(true); }); |