explosions

This commit is contained in:
dave caruso
2024-12-18 14:42:07 -08:00
parent e48fc5e849
commit 0c31be7ad1
12 changed files with 321 additions and 44 deletions

View File

@@ -535,6 +535,22 @@ pub fn inspect(globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) bun.J
return ret;
}
export fn Bun__inspect(globalThis: *JSGlobalObject, value: JSValue) ZigString {
// very stable memory address
var array = MutableString.init(getAllocator(globalThis), 0) catch unreachable;
var buffered_writer = MutableString.BufferedWriter{ .context = &array };
const writer = buffered_writer.writer();
var formatter = ConsoleObject.Formatter{
.globalThis = globalThis,
.quote_strings = true,
};
writer.print("{}", .{value.toFmt(&formatter)}) catch return ZigString.Empty;
buffered_writer.flush() catch return ZigString.Empty;
return ZigString.init(array.slice()).withEncoding();
}
pub fn getInspect(globalObject: *JSC.JSGlobalObject, _: *JSC.JSObject) JSC.JSValue {
const fun = JSC.createCallback(globalObject, ZigString.static("inspect"), 2, inspect);
var str = ZigString.init("nodejs.util.inspect.custom");
@@ -944,14 +960,11 @@ export fn Bun__resolve(global: *JSGlobalObject, specifier: JSValue, source: JSVa
return JSC.JSPromise.resolvedPromiseValue(global, value);
}
export fn Bun__resolveSync(global: *JSGlobalObject, specifier: JSValue, source: JSValue, is_esm: bool) JSC.JSValue {
const specifier_str = specifier.toBunString(global);
defer specifier_str.deref();
export fn Bun__resolveSync(global: *JSGlobalObject, specifier: *const bun.String, source: JSValue, is_esm: bool) JSC.JSValue {
const source_str = source.toBunString(global);
defer source_str.deref();
return JSC.toJSHostValue(global, doResolveWithArgs(global, specifier_str, source_str, is_esm, true));
return JSC.toJSHostValue(global, doResolveWithArgs(global, specifier.*, source_str, is_esm, true));
}
export fn Bun__resolveSyncWithStrings(global: *JSGlobalObject, specifier: *bun.String, source: *bun.String, is_esm: bool) JSC.JSValue {
@@ -4566,8 +4579,11 @@ const InternalTestingAPIs = struct {
};
comptime {
_ = Crypto.JSPasswordObject.JSPasswordObject__create;
BunObject.exportAll();
if (Environment.export_cpp_apis) {
_ = Crypto.JSPasswordObject.JSPasswordObject__create;
_ = Bun__inspect;
BunObject.exportAll();
}
}
const assert = bun.assert;

View File

@@ -375,8 +375,7 @@ JSC_DEFINE_HOST_FUNCTION(Process_functionDlopen,
#else
WTF::String msg = WTF::String::fromUTF8(dlerror());
#endif
JSC::throwTypeError(globalObject, scope, msg);
return {};
return Bun::ERR::DLOPEN_FAILED(scope, globalObject, msg);
}
if (callCountAtStart != globalObject->napiModuleRegisterCallCount) {
@@ -1868,6 +1867,8 @@ static JSValue constructProcessConfigObject(VM& vm, JSObject* processObject)
JSC::JSObject* variables = JSC::constructEmptyObject(globalObject, globalObject->objectPrototype(), 1);
variables->putDirect(vm, JSC::Identifier::fromString(vm, "v8_enable_i8n_support"_s),
JSC::jsNumber(1), 0);
variables->putDirect(vm, JSC::Identifier::fromString(vm, "node_module_version"_s),
JSC::jsNumber(REPORTED_NODEJS_ABI_VERSION), 0);
variables->putDirect(vm, JSC::Identifier::fromString(vm, "enable_lto"_s), JSC::jsBoolean(false), 0);
config->putDirect(vm, JSC::Identifier::fromString(vm, "target_defaults"_s), JSC::constructEmptyObject(globalObject), 0);
config->putDirect(vm, JSC::Identifier::fromString(vm, "variables"_s), variables, 0);

View File

@@ -29,6 +29,7 @@
* different value. In that case, it will have a stale value.
*/
#include "ErrorCode.h"
#include "headers.h"
#include "JavaScriptCore/Synchronousness.h"

View File

@@ -1,4 +1,6 @@
#include "ErrorCode.h"
#include "root.h"
#include "ZigGlobalObject.h"
#include "DOMException.h"
#include "JavaScriptCore/Error.h"
@@ -23,6 +25,8 @@
#include "JavaScriptCore/JSInternalFieldObjectImplInlines.h"
#include "JSDOMException.h"
#include "ErrorCode.h"
static JSC::JSObject* createErrorPrototype(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::ErrorType type, WTF::ASCIILiteral name, WTF::ASCIILiteral code, bool isDOMExceptionPrototype = false)
{
JSC::JSObject* prototype;
@@ -171,6 +175,9 @@ JSObject* createError(Zig::JSGlobalObject* globalObject, ErrorCode code, JSC::JS
return createError(vm, globalObject, code, message);
}
// export fn Bun__inspect(globalThis: *JSGlobalObject, value: JSValue) ZigString
extern "C" ZigString Bun__inspect(JSC::JSGlobalObject* globalObject, JSValue value);
WTF::String JSValueToStringSafe(JSC::JSGlobalObject* globalObject, JSValue arg)
{
ASSERT(!arg.isEmpty());
@@ -179,11 +186,7 @@ WTF::String JSValueToStringSafe(JSC::JSGlobalObject* globalObject, JSValue arg)
auto cell = arg.asCell();
switch (cell->type()) {
case JSC::JSType::StringType: {
return arg.toWTFStringForConsole(globalObject);
}
case JSC::JSType::SymbolType: {
auto symbol = jsCast<Symbol*>(cell);
auto result = symbol->tryGetDescriptiveString();
if (result.has_value())
@@ -197,14 +200,14 @@ WTF::String JSValueToStringSafe(JSC::JSGlobalObject* globalObject, JSValue arg)
auto name = JSC::getCalculatedDisplayName(vm, cell->getObject());
if (catchScope.exception()) {
catchScope.clearException();
name = "Function"_s;
name = ""_s;
}
if (!name.isNull() && name.length() > 0) {
return makeString("[Function: "_s, name, ']');
}
return "Function"_s;
return "[Function: (anonymous)]"_s;
break;
}
@@ -213,34 +216,132 @@ WTF::String JSValueToStringSafe(JSC::JSGlobalObject* globalObject, JSValue arg)
}
}
return arg.toWTFStringForConsole(globalObject);
ZigString zstring = Bun__inspect(globalObject, arg);
BunString bstring(BunStringTag::ZigString, BunStringImpl(zstring));
return bstring.toWTFString();
}
WTF::String determineSpecificType(JSC::JSGlobalObject* globalObject, JSValue value)
{
auto& vm = globalObject->vm();
auto scope = DECLARE_CATCH_SCOPE(vm);
if (value.isNull()) {
return String("null"_s);
}
if (value.isUndefined()) {
return String("undefined"_s);
}
if (value.isBigInt()) {
auto str = value.toStringOrNull(globalObject);
if (!str) return {};
return makeString("type bigint ("_s, str->getString(globalObject), "n)"_s);
}
if (value.isNumber()) {
double d = value.asNumber();
double infinity = std::numeric_limits<double>::infinity();
if (value == 0) return (1 / d == -infinity) ? String("type number (-0)"_s) : String("type number (0)"_s);
if (d != d) return String("type number (NaN)"_s);
if (d == infinity) return String("type number (Infinity)"_s);
if (d == -infinity) return String("type number (-Infinity)"_s);
auto str = value.toStringOrNull(globalObject);
if (!str) return {};
return makeString("type number ("_s, str->getString(globalObject), ")"_s);
}
if (value.isBoolean()) {
return value.asBoolean() ? String("type boolean (true)"_s) : String("type boolean (false)"_s);
}
if (value.isSymbol()) {
auto cell = value.asCell();
auto symbol = jsCast<Symbol*>(cell);
auto result = symbol->tryGetDescriptiveString();
auto description = result.has_value() ? result.value() : String("Symbol()"_s);
return makeString("type symbol ("_s, description, ")"_s);
}
if (value.isCallable()) {
auto& vm = globalObject->vm();
auto scope = DECLARE_CATCH_SCOPE(vm);
auto cell = value.asCell();
auto name = JSC::getCalculatedDisplayName(vm, cell->getObject());
if (scope.exception()) {
scope.clearException();
name = String(""_s);
}
if (!name.isNull() && name.length() > 0) {
return makeString("function "_s, name);
}
return String("function"_s);
}
if (value.isObject()) {
auto constructor = value.get(globalObject, vm.propertyNames->constructor);
RETURN_IF_EXCEPTION(scope, {});
if (constructor.toBoolean(globalObject)) {
auto name = constructor.get(globalObject, vm.propertyNames->name);
RETURN_IF_EXCEPTION(scope, {});
auto str = name.toString(globalObject);
RETURN_IF_EXCEPTION(scope, {});
return makeString("an instance of "_s, str->getString(globalObject));
}
// return `${lazyInternalUtilInspect().inspect(value, { depth: -1 })}`;
auto str = JSValueToStringSafe(globalObject, value);
RETURN_IF_EXCEPTION(scope, {});
return str;
}
if (value.isString()) {
auto str = value.toString(globalObject)->getString(globalObject);
if (str.length() > 28) {
str = str.substring(0, 25);
str = makeString(str, "..."_s);
if (!str.contains('\'')) {
return makeString("type string ('"_s, str, "')"_s);
}
}
// return `type string (${JSONStringify(value)})`;
str = JSValueToStringSafe(globalObject, value);
RETURN_IF_EXCEPTION(scope, {});
return makeString("type string ("_s, str, ")"_s);
}
// value = lazyInternalUtilInspect().inspect(value, { colors: false });
auto str = JSValueToStringSafe(globalObject, value);
RETURN_IF_EXCEPTION(scope, {});
return str;
}
namespace Message {
WTF::String ERR_INVALID_ARG_TYPE(JSC::ThrowScope& scope, JSC::JSGlobalObject* globalObject, const StringView& arg_name, const StringView& expected_type, JSValue actual_value)
{
auto actual_value_string = JSValueToStringSafe(globalObject, actual_value);
auto actual_value_string = determineSpecificType(globalObject, actual_value);
RETURN_IF_EXCEPTION(scope, {});
return makeString("The \""_s, arg_name, "\" argument must be of type "_s, expected_type, ". Received: "_s, actual_value_string);
return makeString("The \""_s, arg_name, "\" argument must be of type "_s, expected_type, ". Received "_s, actual_value_string);
}
WTF::String ERR_INVALID_ARG_TYPE(JSC::ThrowScope& scope, JSC::JSGlobalObject* globalObject, const StringView& arg_name, ArgList expected_types, JSValue actual_value)
{
WTF::StringBuilder result;
auto actual_value_string = JSValueToStringSafe(globalObject, actual_value);
auto actual_value_string = determineSpecificType(globalObject, actual_value);
RETURN_IF_EXCEPTION(scope, {});
result.append("The \""_s, arg_name, "\" argument must be of type "_s);
result.append("The "_s);
if (arg_name.contains(' ')) {
result.append(arg_name);
} else {
result.append("\""_s);
result.append(arg_name);
result.append("\" argument"_s);
}
result.append(" must be of type "_s);
unsigned length = expected_types.size();
if (length == 1) {
result.append(expected_types.at(0).toWTFString(globalObject));
} else if (length == 2) {
result.append(expected_types.at(0).toWTFString(globalObject));
result.append(" or "_s);
result.append(", or "_s);
result.append(expected_types.at(1).toWTFString(globalObject));
} else {
for (unsigned i = 0; i < length - 1; i++) {
@@ -249,11 +350,11 @@ WTF::String ERR_INVALID_ARG_TYPE(JSC::ThrowScope& scope, JSC::JSGlobalObject* gl
JSValue expected_type = expected_types.at(i);
result.append(expected_type.toWTFString(globalObject));
}
result.append(" or "_s);
result.append(", or "_s);
result.append(expected_types.at(length - 1).toWTFString(globalObject));
}
result.append(". Received: "_s, actual_value_string);
result.append(". Received "_s, actual_value_string);
return result.toString();
}
@@ -291,20 +392,26 @@ WTF::String ERR_OUT_OF_RANGE(JSC::ThrowScope& scope, JSC::JSGlobalObject* global
auto input = JSValueToStringSafe(globalObject, val_input);
RETURN_IF_EXCEPTION(scope, {});
return makeString("The value of \""_s, arg_name, "\" is out of range. It must be "_s, range, ". Received: "_s, input);
return makeString("The value of \""_s, arg_name, "\" is out of range. It must be "_s, range, ". Received "_s, input);
}
}
namespace ERR {
JSC::EncodedJSValue throwCode(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject, ErrorCode code, const WTF::String& message)
{
throwScope.throwException(globalObject, createError(globalObject, code, message));
return {};
}
JSC::EncodedJSValue INVALID_ARG_TYPE(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject, const WTF::String& arg_name, const WTF::String& expected_type, JSC::JSValue val_actual_value)
{
auto arg_kind = arg_name.startsWith("options."_s) ? "property"_s : "argument"_s;
auto arg_kind = String(arg_name).startsWith("options."_s) ? "property"_s : "argument"_s;
auto ty_first_char = expected_type[0];
auto ty_kind = ty_first_char >= 'A' && ty_first_char <= 'Z' ? "an instance of"_s : "of type"_s;
auto actual_value = JSValueToStringSafe(globalObject, val_actual_value);
auto actual_value = determineSpecificType(globalObject, val_actual_value);
RETURN_IF_EXCEPTION(throwScope, {});
auto message = makeString("The \""_s, arg_name, "\" "_s, arg_kind, " must be "_s, ty_kind, " "_s, expected_type, ". Received "_s, actual_value);
@@ -320,7 +427,7 @@ JSC::EncodedJSValue INVALID_ARG_TYPE(JSC::ThrowScope& throwScope, JSC::JSGlobalO
auto ty_first_char = expected_type[0];
auto ty_kind = ty_first_char >= 'A' && ty_first_char <= 'Z' ? "an instance of"_s : "of type"_s;
auto actual_value = JSValueToStringSafe(globalObject, val_actual_value);
auto actual_value = determineSpecificType(globalObject, val_actual_value);
RETURN_IF_EXCEPTION(throwScope, {});
auto message = makeString("The \""_s, arg_name, "\" "_s, arg_kind, " must be "_s, ty_kind, " "_s, expected_type, ". Received "_s, actual_value);
@@ -438,8 +545,12 @@ JSC::EncodedJSValue STRING_TOO_LONG(JSC::ThrowScope& throwScope, JSC::JSGlobalOb
return {};
}
JSC::EncodedJSValue BUFFER_OUT_OF_BOUNDS(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject)
JSC::EncodedJSValue BUFFER_OUT_OF_BOUNDS(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject, const WTF::String& name)
{
if (!name.isEmpty()) {
throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_BUFFER_OUT_OF_BOUNDS, makeString("\""_s, name, "\" is outside of buffer bounds"_s)));
return {};
}
throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_BUFFER_OUT_OF_BOUNDS, "Attempt to access memory outside buffer bounds"_s));
return {};
}
@@ -469,6 +580,12 @@ JSC::EncodedJSValue SOCKET_BAD_PORT(JSC::ThrowScope& throwScope, JSC::JSGlobalOb
return {};
}
JSC::EncodedJSValue DLOPEN_FAILED(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* global, const WTF::String& message)
{
throwScope.throwException(global, createError(global, ErrorCode::ERR_DLOPEN_FAILED, message));
return {};
}
}
static JSC::JSValue ERR_INVALID_ARG_TYPE(JSC::ThrowScope& scope, JSC::JSGlobalObject* globalObject, JSValue arg0, JSValue arg1, JSValue arg2)

View File

@@ -92,6 +92,7 @@ JSC::EncodedJSValue STRING_TOO_LONG(JSC::ThrowScope& throwScope, JSC::JSGlobalOb
JSC::EncodedJSValue BUFFER_OUT_OF_BOUNDS(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject);
JSC::EncodedJSValue UNKNOWN_SIGNAL(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject, JSC::JSValue signal, bool triedUppercase = false);
JSC::EncodedJSValue SOCKET_BAD_PORT(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject, JSC::JSValue name, JSC::JSValue port, bool allowZero);
JSC::EncodedJSValue DLOPEN_FAILED(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* global, const WTF::String& message);
}

View File

@@ -49,6 +49,7 @@ export default [
["ERR_STREAM_RELEASE_LOCK", Error, "AbortError"],
["ERR_INCOMPATIBLE_OPTION_PAIR", TypeError, "TypeError"],
["ERR_INVALID_URI", URIError, "URIError"],
["ERR_DLOPEN_FAILED", Error],
// Bun-specific
["ERR_FORMDATA_PARSE_ERROR", TypeError],

View File

@@ -1,3 +1,4 @@
#include "ErrorCode.h"
#include "root.h"
#include "headers.h"
@@ -189,9 +190,13 @@ extern "C" JSC::EncodedJSValue functionImportMeta__resolveSync(JSC::JSGlobalObje
JSC::JSValue moduleName = callFrame->argument(0);
JSC::JSValue fromValue = callFrame->argument(1);
if (moduleName.isUndefinedOrNull()) {
JSC::throwTypeError(globalObject, scope, "expects a string"_s);
scope.release();
if (!moduleName.isString()) {
Bun::ERR::INVALID_ARG_TYPE(scope, lexicalGlobalObject, "id"_s, "string"_s, moduleName);
return {};
}
auto moduleNameString = moduleName.toWTFString(globalObject);
if (moduleNameString.isEmpty()) {
Bun::ERR::INVALID_ARG_VALUE(scope, lexicalGlobalObject, "id"_s, moduleName, "must be a non-empty string"_s);
return {};
}
@@ -260,7 +265,8 @@ extern "C" JSC::EncodedJSValue functionImportMeta__resolveSync(JSC::JSGlobalObje
}
}
auto result = Bun__resolveSync(globalObject, JSC::JSValue::encode(moduleName), from, isESM);
BunString moduleNameBunString = Bun::toString(moduleNameString);
auto result = Bun__resolveSync(globalObject, &moduleNameBunString, from, isESM);
RETURN_IF_EXCEPTION(scope, {});
if (!JSC::JSValue::decode(result).isString()) {
@@ -284,9 +290,13 @@ extern "C" JSC::EncodedJSValue functionImportMeta__resolveSyncPrivate(JSC::JSGlo
JSValue from = callFrame->argument(1);
bool isESM = callFrame->argument(2).asBoolean();
if (moduleName.isUndefinedOrNull()) {
JSC::throwTypeError(lexicalGlobalObject, scope, "expected module name as a string"_s);
scope.release();
if (!moduleName.isString()) {
Bun::ERR::INVALID_ARG_TYPE(scope, lexicalGlobalObject, "id"_s, "string"_s, moduleName);
return {};
}
auto moduleNameString = moduleName.toWTFString(globalObject);
if (moduleNameString.isEmpty()) {
Bun::ERR::INVALID_ARG_VALUE(scope, lexicalGlobalObject, "id"_s, moduleName, "must be a non-empty string"_s);
return {};
}
@@ -294,9 +304,8 @@ extern "C" JSC::EncodedJSValue functionImportMeta__resolveSyncPrivate(JSC::JSGlo
if (globalObject->onLoadPlugins.hasVirtualModules()) {
if (moduleName.isString()) {
auto moduleString = moduleName.toWTFString(globalObject);
if (auto resolvedString = globalObject->onLoadPlugins.resolveVirtualModule(moduleString, from.toWTFString(globalObject))) {
if (moduleString == resolvedString.value())
if (auto resolvedString = globalObject->onLoadPlugins.resolveVirtualModule(moduleNameString, from.toWTFString(globalObject))) {
if (moduleNameString == resolvedString.value())
return JSC::JSValue::encode(moduleName);
return JSC::JSValue::encode(jsString(vm, resolvedString.value()));
}
@@ -331,7 +340,8 @@ extern "C" JSC::EncodedJSValue functionImportMeta__resolveSyncPrivate(JSC::JSGlo
}
}
auto result = Bun__resolveSync(lexicalGlobalObject, JSC::JSValue::encode(moduleName), JSValue::encode(from), isESM);
BunString moduleNameBunString = Bun::toString(moduleNameString);
auto result = Bun__resolveSync(lexicalGlobalObject, &moduleNameBunString, JSValue::encode(from), isESM);
RETURN_IF_EXCEPTION(scope, {});
if (!JSC::JSValue::decode(result).isString()) {

View File

@@ -11,7 +11,7 @@
extern "C" JSC_DECLARE_HOST_FUNCTION(functionImportMeta__resolveSync);
extern "C" JSC_DECLARE_HOST_FUNCTION(functionImportMeta__resolveSyncPrivate);
extern "C" JSC::EncodedJSValue Bun__resolve(JSC::JSGlobalObject* global, JSC::EncodedJSValue specifier, JSC::EncodedJSValue from, bool is_esm);
extern "C" JSC::EncodedJSValue Bun__resolveSync(JSC::JSGlobalObject* global, JSC::EncodedJSValue specifier, JSC::EncodedJSValue from, bool is_esm);
extern "C" JSC::EncodedJSValue Bun__resolveSync(JSC::JSGlobalObject* global, const BunString* specifier, JSC::EncodedJSValue from, bool is_esm);
extern "C" JSC::EncodedJSValue Bun__resolveSyncWithSource(JSC::JSGlobalObject* global, JSC::EncodedJSValue specifier, BunString* from, bool is_esm);
extern "C" JSC::EncodedJSValue Bun__resolveSyncWithStrings(JSC::JSGlobalObject* global, BunString* specifier, BunString* from, bool is_esm);

View File

@@ -202,6 +202,10 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionIsBuiltinModule,
auto moduleStr = moduleName.toWTFString(globalObject);
RETURN_IF_EXCEPTION(scope, JSValue::encode(jsBoolean(false)));
// Bun does not yet implement this module, but to mimic node:module, this special case is needed.
if (moduleStr == "node:test"_s) {
return JSValue::encode(jsBoolean(true));
}
return JSValue::encode(jsBoolean(Bun::isBuiltinModule(moduleStr)));
}
@@ -329,13 +333,15 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionResolveFileName,
JSC::JSValue moduleName = callFrame->argument(0);
JSC::JSValue fromValue = callFrame->argument(1);
auto scope = DECLARE_THROW_SCOPE(globalObject->vm());
if (moduleName.isUndefinedOrNull()) {
auto scope = DECLARE_THROW_SCOPE(globalObject->vm());
JSC::throwTypeError(globalObject, scope,
"Module._resolveFilename expects a string"_s);
scope.release();
return JSC::JSValue::encode(JSC::JSValue {});
}
WTF::String moduleNameString = moduleName.toWTFString(globalObject);
RETURN_IF_EXCEPTION(scope, {});
if (
// fast path: it's a real CommonJS module object.
@@ -354,8 +360,8 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionResolveFileName,
}
}
auto scope = DECLARE_THROW_SCOPE(globalObject->vm());
auto result = Bun__resolveSync(globalObject, JSC::JSValue::encode(moduleName), JSValue::encode(fromValue), false);
BunString moduleNameBunString = Bun::toString(moduleNameString);
auto result = Bun__resolveSync(globalObject, &moduleNameBunString, JSValue::encode(fromValue), false);
RETURN_IF_EXCEPTION(scope, {});
if (!JSC::JSValue::decode(result).isString()) {

View File

@@ -0,0 +1,16 @@
'use strict';
require('../common');
const assert = require('assert');
const { isBuiltin } = require('module');
// Includes modules in lib/ (even deprecated ones)
assert(isBuiltin('http'));
assert(isBuiltin('sys'));
assert(isBuiltin('node:fs'));
assert(isBuiltin('node:test'));
// Does not include internal modules
assert(!isBuiltin('internal/errors'));
assert(!isBuiltin('test'));
assert(!isBuiltin(''));
assert(!isBuiltin(undefined));

View File

@@ -0,0 +1,98 @@
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
'use strict';
const common = require('../common');
const assert = require('assert');
const { execSync } = require('child_process');
const errorMessagesByPlatform = {
win32: ['is not a valid Win32 application'],
linux: ['file too short', 'Exec format error'],
sunos: ['unknown file type', 'not an ELF file'],
darwin: ['file too short', 'not a mach-o file'],
aix: ['Cannot load module',
'Cannot run a file that does not have a valid format.',
'Exec format error'],
ibmi: ['Cannot load module',
'The module has too many section headers',
'or the file has been truncated.'],
};
// If we don't know a priori what the error would be, we accept anything.
const platform = common.isIBMi ? 'ibmi' : process.platform;
const errorMessages = errorMessagesByPlatform[platform] || [''];
// On Windows, error messages are MUI dependent
// Ref: https://github.com/nodejs/node/issues/13376
let localeOk = true;
if (common.isWindows) {
const powerShellFindMUI =
'powershell -NoProfile -ExecutionPolicy Unrestricted -c ' +
'"(Get-UICulture).TwoLetterISOLanguageName"';
try {
// If MUI != 'en' we'll ignore the content of the message
localeOk = execSync(powerShellFindMUI).toString('utf8').trim() === 'en';
} catch {
// It's only a best effort try to find the MUI
}
}
assert.throws(
() => { require('../fixtures/module-loading-error.node'); },
(e) => {
if (localeOk && !errorMessages.some((msg) => e.message.includes(msg)))
return false;
return e.name === 'Error';
}
);
const re = /^The "id" argument must be of type string\. Received /;
[1, false, null, undefined, {}].forEach((value) => {
console.log(value);
assert.throws(
() => { require(value); },
{
name: 'TypeError',
code: 'ERR_INVALID_ARG_TYPE',
message: re
});
});
assert.throws(
() => { require(''); },
{
name: 'TypeError',
code: 'ERR_INVALID_ARG_VALUE',
// Bun uses `"` instead of `'` in util.inspect
message: 'The argument \'id\' must be a non-empty string. Received ""'
});
// Folder read operation succeeds in AIX.
// For libuv change, see https://github.com/libuv/libuv/pull/2025.
// https://github.com/nodejs/node/pull/48477#issuecomment-1604586650
assert.throws(
() => { require('../fixtures/packages/is-dir'); },
common.isAIX ? { code: 'ERR_INVALID_PACKAGE_CONFIG' } : {
code: 'MODULE_NOT_FOUND',
message: /Cannot find module '\.\.\/fixtures\/packages\/is-dir'/
}
);

View File

@@ -0,0 +1,10 @@
'use strict';
require('../common');
const assert = require('assert');
// check for existence
assert(Object.hasOwn(process.config.variables, 'node_module_version'));
// Ensure that `node_module_version` is an Integer > 0
assert(Number.isInteger(process.config.variables.node_module_version));
assert(process.config.variables.node_module_version > 0);