mirror of
https://github.com/oven-sh/bun
synced 2026-02-03 23:48:52 +00:00
Compare commits
6 Commits
ciro/fix-a
...
don/fix/pr
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7633980307 | ||
|
|
76efdb7956 | ||
|
|
619cba2ade | ||
|
|
dbd0481666 | ||
|
|
11284c94a6 | ||
|
|
dd0e5b6b40 |
@@ -63,7 +63,6 @@ pub const BunObject = struct {
|
||||
pub const enableANSIColors = toJSGetter(Bun.enableANSIColors);
|
||||
pub const hash = toJSGetter(Bun.getHashObject);
|
||||
pub const inspect = toJSGetter(Bun.getInspect);
|
||||
pub const main = toJSGetter(Bun.getMain);
|
||||
pub const origin = toJSGetter(Bun.getOrigin);
|
||||
pub const semver = toJSGetter(Bun.getSemver);
|
||||
pub const stderr = toJSGetter(Bun.getStderr);
|
||||
@@ -123,7 +122,6 @@ pub const BunObject = struct {
|
||||
@export(&BunObject.enableANSIColors, .{ .name = getterName("enableANSIColors") });
|
||||
@export(&BunObject.hash, .{ .name = getterName("hash") });
|
||||
@export(&BunObject.inspect, .{ .name = getterName("inspect") });
|
||||
@export(&BunObject.main, .{ .name = getterName("main") });
|
||||
@export(&BunObject.origin, .{ .name = getterName("origin") });
|
||||
@export(&BunObject.stderr, .{ .name = getterName("stderr") });
|
||||
@export(&BunObject.stdin, .{ .name = getterName("stdin") });
|
||||
@@ -569,55 +567,55 @@ pub fn enableANSIColors(globalThis: *JSC.JSGlobalObject, _: *JSC.JSObject) JSC.J
|
||||
return JSValue.jsBoolean(Output.enable_ansi_colors);
|
||||
}
|
||||
|
||||
pub fn getMain(globalThis: *JSC.JSGlobalObject, _: *JSC.JSObject) JSC.JSValue {
|
||||
const vm = globalThis.bunVM();
|
||||
// pub fn getMain(globalThis: *JSC.JSGlobalObject, _: *JSC.JSObject) JSC.JSValue {
|
||||
// const vm = globalThis.bunVM();
|
||||
|
||||
// Attempt to use the resolved filesystem path
|
||||
// This makes `eval('require.main === module')` work when the main module is a symlink.
|
||||
// This behavior differs slightly from Node. Node sets the `id` to `.` when the main module is a symlink.
|
||||
use_resolved_path: {
|
||||
if (vm.main_resolved_path.isEmpty()) {
|
||||
// If it's from eval, don't try to resolve it.
|
||||
if (strings.hasSuffixComptime(vm.main, "[eval]")) {
|
||||
break :use_resolved_path;
|
||||
}
|
||||
if (strings.hasSuffixComptime(vm.main, "[stdin]")) {
|
||||
break :use_resolved_path;
|
||||
}
|
||||
// // Attempt to use the resolved filesystem path
|
||||
// // This makes `eval('require.main === module')` work when the main module is a symlink.
|
||||
// // This behavior differs slightly from Node. Node sets the `id` to `.` when the main module is a symlink.
|
||||
// use_resolved_path: {
|
||||
// if (vm.main_resolved_path.isEmpty()) {
|
||||
// // If it's from eval, don't try to resolve it.
|
||||
// if (strings.hasSuffixComptime(vm.main, "[eval]")) {
|
||||
// break :use_resolved_path;
|
||||
// }
|
||||
// if (strings.hasSuffixComptime(vm.main, "[stdin]")) {
|
||||
// break :use_resolved_path;
|
||||
// }
|
||||
|
||||
const fd = bun.sys.openatA(
|
||||
if (comptime Environment.isWindows) bun.invalid_fd else bun.FD.cwd(),
|
||||
vm.main,
|
||||
// const fd = bun.sys.openatA(
|
||||
// if (comptime Environment.isWindows) bun.invalid_fd else bun.FD.cwd(),
|
||||
// vm.main,
|
||||
|
||||
// Open with the minimum permissions necessary for resolving the file path.
|
||||
if (comptime Environment.isLinux) bun.O.PATH else bun.O.RDONLY,
|
||||
// // Open with the minimum permissions necessary for resolving the file path.
|
||||
// if (comptime Environment.isLinux) bun.O.PATH else bun.O.RDONLY,
|
||||
|
||||
0,
|
||||
).unwrap() catch break :use_resolved_path;
|
||||
// 0,
|
||||
// ).unwrap() catch break :use_resolved_path;
|
||||
|
||||
defer _ = bun.sys.close(fd);
|
||||
if (comptime Environment.isWindows) {
|
||||
var wpath: bun.WPathBuffer = undefined;
|
||||
const fdpath = bun.getFdPathW(fd, &wpath) catch break :use_resolved_path;
|
||||
vm.main_resolved_path = bun.String.createUTF16(fdpath);
|
||||
} else {
|
||||
var path: bun.PathBuffer = undefined;
|
||||
const fdpath = bun.getFdPath(fd, &path) catch break :use_resolved_path;
|
||||
// defer _ = bun.sys.close(fd);
|
||||
// if (comptime Environment.isWindows) {
|
||||
// var wpath: bun.WPathBuffer = undefined;
|
||||
// const fdpath = bun.getFdPathW(fd, &wpath) catch break :use_resolved_path;
|
||||
// vm.main_resolved_path = bun.String.createUTF16(fdpath);
|
||||
// } else {
|
||||
// var path: bun.PathBuffer = undefined;
|
||||
// const fdpath = bun.getFdPath(fd, &path) catch break :use_resolved_path;
|
||||
|
||||
// Bun.main === otherId will be compared many times, so let's try to create an atom string if we can.
|
||||
if (bun.String.tryCreateAtom(fdpath)) |atom| {
|
||||
vm.main_resolved_path = atom;
|
||||
} else {
|
||||
vm.main_resolved_path = bun.String.createUTF8(fdpath);
|
||||
}
|
||||
}
|
||||
}
|
||||
// // Bun.main === otherId will be compared many times, so let's try to create an atom string if we can.
|
||||
// if (bun.String.tryCreateAtom(fdpath)) |atom| {
|
||||
// vm.main_resolved_path = atom;
|
||||
// } else {
|
||||
// vm.main_resolved_path = bun.String.createUTF8(fdpath);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
return vm.main_resolved_path.toJS(globalThis);
|
||||
}
|
||||
// return vm.main_resolved_path.toJS(globalThis);
|
||||
// }
|
||||
|
||||
return ZigString.init(vm.main).toJS(globalThis);
|
||||
}
|
||||
// return ZigString.init(vm.main).toJS(globalThis);
|
||||
// }
|
||||
|
||||
pub fn getArgv(globalThis: *JSC.JSGlobalObject, _: *JSC.JSObject) JSC.JSValue {
|
||||
return JSC.Node.Process.getArgv(globalThis);
|
||||
|
||||
@@ -79,6 +79,11 @@ namespace Bun {
|
||||
|
||||
extern "C" bool has_bun_garbage_collector_flag_enabled;
|
||||
|
||||
static JSValue BunObject__mainModule(JSC::VM& vm, JSC::JSObject* bunObject)
|
||||
{
|
||||
return jsCast<Zig::GlobalObject*>(bunObject->globalObject())->mainModule();
|
||||
}
|
||||
|
||||
static JSValue BunObject_getter_wrap_ArrayBufferSink(VM& vm, JSObject* bunObject)
|
||||
{
|
||||
return jsCast<Zig::GlobalObject*>(bunObject->globalObject())->ArrayBufferSink();
|
||||
@@ -699,8 +704,8 @@ JSC_DEFINE_HOST_FUNCTION(functionFileURLToPath, (JSC::JSGlobalObject * globalObj
|
||||
@begin bunObjectTable
|
||||
$ constructBunShell DontDelete|PropertyCallback
|
||||
ArrayBufferSink BunObject_getter_wrap_ArrayBufferSink DontDelete|PropertyCallback
|
||||
Cookie constructCookieObject DontDelete|ReadOnly|PropertyCallback
|
||||
CookieMap constructCookieMapObject DontDelete|ReadOnly|PropertyCallback
|
||||
Cookie constructCookieObject DontDelete|ReadOnly|PropertyCallback
|
||||
CookieMap constructCookieMapObject DontDelete|ReadOnly|PropertyCallback
|
||||
CryptoHasher BunObject_getter_wrap_CryptoHasher DontDelete|PropertyCallback
|
||||
FFI BunObject_getter_wrap_FFI DontDelete|PropertyCallback
|
||||
FileSystemRouter BunObject_getter_wrap_FileSystemRouter DontDelete|PropertyCallback
|
||||
@@ -728,14 +733,14 @@ JSC_DEFINE_HOST_FUNCTION(functionFileURLToPath, (JSC::JSGlobalObject * globalObj
|
||||
color BunObject_callback_color DontDelete|Function 2
|
||||
deepEquals functionBunDeepEquals DontDelete|Function 2
|
||||
deepMatch functionBunDeepMatch DontDelete|Function 2
|
||||
deflateSync BunObject_callback_deflateSync DontDelete|Function 1
|
||||
deflateSync BunObject_callback_deflateSync DontDelete|Function 1
|
||||
dns constructDNSObject ReadOnly|DontDelete|PropertyCallback
|
||||
enableANSIColors BunObject_getter_wrap_enableANSIColors DontDelete|PropertyCallback
|
||||
env constructEnvObject ReadOnly|DontDelete|PropertyCallback
|
||||
escapeHTML functionBunEscapeHTML DontDelete|Function 2
|
||||
fetch constructBunFetchObject ReadOnly|DontDelete|PropertyCallback
|
||||
file BunObject_callback_file DontDelete|Function 1
|
||||
fileURLToPath functionFileURLToPath DontDelete|Function 1
|
||||
fetch constructBunFetchObject ReadOnly|DontDelete|PropertyCallback
|
||||
file BunObject_callback_file DontDelete|Function 1
|
||||
fileURLToPath functionFileURLToPath DontDelete|Function 1
|
||||
gc Generated::BunObject::jsGc DontDelete|Function 1
|
||||
generateHeapSnapshot functionGenerateHeapSnapshot DontDelete|Function 1
|
||||
gunzipSync BunObject_callback_gunzipSync DontDelete|Function 1
|
||||
@@ -747,8 +752,8 @@ JSC_DEFINE_HOST_FUNCTION(functionFileURLToPath, (JSC::JSGlobalObject * globalObj
|
||||
isMainThread constructIsMainThread ReadOnly|DontDelete|PropertyCallback
|
||||
jest BunObject_callback_jest DontEnum|DontDelete|Function 1
|
||||
listen BunObject_callback_listen DontDelete|Function 1
|
||||
udpSocket BunObject_callback_udpSocket DontDelete|Function 1
|
||||
main BunObject_getter_wrap_main DontDelete|PropertyCallback
|
||||
udpSocket BunObject_callback_udpSocket DontDelete|Function 1
|
||||
main BunObject__mainModule DontDelete|PropertyCallback
|
||||
mmap BunObject_callback_mmap DontDelete|Function 1
|
||||
nanoseconds functionBunNanoseconds DontDelete|Function 0
|
||||
openInEditor BunObject_callback_openInEditor DontDelete|Function 1
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "napi.h"
|
||||
|
||||
#include "BunProcess.h"
|
||||
#include "headers-handwritten.h"
|
||||
#include <JavaScriptCore/InternalFieldTuple.h>
|
||||
#include <JavaScriptCore/JSMicrotask.h>
|
||||
#include <JavaScriptCore/ObjectConstructor.h>
|
||||
@@ -116,8 +117,6 @@ namespace Bun {
|
||||
using namespace JSC;
|
||||
|
||||
#define processObjectBindingCodeGenerator processObjectInternalsBindingCodeGenerator
|
||||
#define setProcessObjectInternalsMainModuleCodeGenerator processObjectInternalsSetMainModuleCodeGenerator
|
||||
#define setProcessObjectMainModuleCodeGenerator setMainModuleCodeGenerator
|
||||
|
||||
#if !defined(BUN_WEBKIT_VERSION)
|
||||
#define BUN_WEBKIT_VERSION "unknown"
|
||||
@@ -3508,6 +3507,58 @@ extern "C" void Process__emitErrorEvent(Zig::GlobalObject* global, EncodedJSValu
|
||||
}
|
||||
}
|
||||
|
||||
JSC_DEFINE_CUSTOM_GETTER(processMainModule, (JSC::JSGlobalObject * lexicalGlobalObject, JSC::EncodedJSValue thisValue, JSC::PropertyName name))
|
||||
{
|
||||
VM& vm = lexicalGlobalObject->vm();
|
||||
auto scope = DECLARE_THROW_SCOPE(vm);
|
||||
|
||||
auto* thisObject = jsDynamicCast<Process*>(JSValue::decode(thisValue));
|
||||
if (UNLIKELY(!thisObject)) {
|
||||
throwVMTypeError(lexicalGlobalObject, scope, "Expected 'this' to be a Process object"_s);
|
||||
return {};
|
||||
}
|
||||
JSVMClientData* clientData = WebCore::clientData(vm);
|
||||
ASSERT(clientData);
|
||||
|
||||
// check if we've cached it already
|
||||
JSC::Identifier mainIdent = clientData->builtinNames().mainPrivateName();
|
||||
if (JSValue mainValue = thisObject->getDirect(vm, mainIdent)) {
|
||||
return JSValue::encode(mainValue);
|
||||
}
|
||||
|
||||
auto* global = reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject);
|
||||
|
||||
auto* requireCache = global->lazyRequireCacheObject();
|
||||
auto* mm = global->mainModule();
|
||||
if (UNLIKELY(mm->length() == 0)) {
|
||||
thisObject->putDirect(vm, mainIdent, jsUndefined(), 0);
|
||||
return JSValue::encode(jsUndefined());
|
||||
}
|
||||
auto prop = PropertyName(JSC::Identifier::fromString(vm, WTFMove(mm->getString(global))));
|
||||
auto mainModule = requireCache->getIfPropertyExists(global, prop);
|
||||
thisObject->putDirect(vm, mainIdent, mainModule, 0);
|
||||
return JSValue::encode(mainModule);
|
||||
}
|
||||
|
||||
JSC_DEFINE_CUSTOM_SETTER(setProcessMainModule, (JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, JSC::EncodedJSValue encodedValue, JSC::PropertyName))
|
||||
{
|
||||
VM& vm = globalObject->vm();
|
||||
auto scope = DECLARE_THROW_SCOPE(vm);
|
||||
|
||||
JSVMClientData* clientData = WebCore::clientData(vm);
|
||||
ASSERT(clientData);
|
||||
|
||||
auto* thisObject = jsDynamicCast<Process*>(JSValue::decode(thisValue));
|
||||
if (UNLIKELY(!thisObject)) {
|
||||
throwVMTypeError(globalObject, scope, "Expected 'this' to be a Process object"_s);
|
||||
return false;
|
||||
}
|
||||
|
||||
JSC::Identifier mainIdent = clientData->builtinNames().mainPrivateName();
|
||||
thisObject->putDirect(vm, mainIdent, JSValue::decode(encodedValue), 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Source for Process.lut.h
|
||||
@begin processObjectTable
|
||||
abort Process_functionAbort Function 1
|
||||
@@ -3541,7 +3592,7 @@ extern "C" void Process__emitErrorEvent(Zig::GlobalObject* global, EncodedJSValu
|
||||
hrtime constructProcessHrtimeObject PropertyCallback
|
||||
isBun constructIsBun PropertyCallback
|
||||
kill Process_functionKill Function 2
|
||||
mainModule processObjectInternalsMainModuleCodeGenerator Builtin|Accessor
|
||||
mainModule processMainModule CustomAccessor
|
||||
memoryUsage constructMemoryUsage PropertyCallback
|
||||
moduleLoadList Process_stubEmptyArray PropertyCallback
|
||||
nextTick constructProcessNextTickFn PropertyCallback
|
||||
|
||||
@@ -761,6 +761,70 @@ pub const JSGlobalObject = opaque {
|
||||
return Zig__GlobalObject__resetModuleRegistryMap(global, map);
|
||||
}
|
||||
|
||||
/// Name of main module. This is usually a path, but can be something else
|
||||
/// when Bun is not run on a file (e.g. `[eval]` for `bun --eval <code>`).
|
||||
/// Always returns a `JSC::JSString*`.
|
||||
///
|
||||
/// You usually don't need to call this directly since this is lazily
|
||||
/// initialized and cached on the global object.
|
||||
fn determineMainModule(globalThis: *JSC.JSGlobalObject) callconv(.C) JSC.JSValue {
|
||||
const bun_vm = globalThis.bunVM();
|
||||
|
||||
// Attempt to use the resolved filesystem path
|
||||
// This makes `eval('require.main === module')` work when the main module is a symlink.
|
||||
// This behavior differs slightly from Node. Node sets the `id` to `.` when the main module is a symlink.
|
||||
use_resolved_path: {
|
||||
if (bun_vm.main_resolved_path.isEmpty()) {
|
||||
// If it's from eval, don't try to resolve it.
|
||||
if (strings.hasSuffixComptime(bun_vm.main, "[eval]")) {
|
||||
@branchHint(.unlikely);
|
||||
break :use_resolved_path;
|
||||
}
|
||||
if (strings.hasSuffixComptime(bun_vm.main, "[stdin]")) {
|
||||
@branchHint(.unlikely);
|
||||
break :use_resolved_path;
|
||||
}
|
||||
if (bun_vm.main.len == 0) {
|
||||
@branchHint(.cold);
|
||||
return bun.String.empty.toJS(globalThis);
|
||||
}
|
||||
|
||||
const fd = bun.sys.openatA(
|
||||
if (comptime bun.Environment.isWindows) bun.invalid_fd else bun.FD.cwd(),
|
||||
bun_vm.main,
|
||||
|
||||
// Open with the minimum permissions necessary for resolving the file path.
|
||||
if (comptime bun.Environment.isLinux) bun.O.PATH else bun.O.RDONLY,
|
||||
|
||||
0,
|
||||
).unwrap() catch break :use_resolved_path;
|
||||
|
||||
defer _ = bun.sys.close(fd);
|
||||
if (comptime bun.Environment.isWindows) {
|
||||
var wpath: bun.WPathBuffer = undefined;
|
||||
const fdpath = bun.getFdPathW(fd, &wpath) catch break :use_resolved_path;
|
||||
bun_vm.main_resolved_path = bun.String.createUTF16(fdpath);
|
||||
} else {
|
||||
var path: bun.PathBuffer = undefined;
|
||||
const fdpath = bun.getFdPath(fd, &path) catch break :use_resolved_path;
|
||||
|
||||
// Bun.main === otherId will be compared many times, so let's try to create an atom string if we can.
|
||||
if (bun.String.tryCreateAtom(fdpath)) |atom| {
|
||||
bun_vm.main_resolved_path = atom;
|
||||
} else {
|
||||
bun_vm.main_resolved_path = bun.String.createUTF8(fdpath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return bun_vm.main_resolved_path.toJS(globalThis);
|
||||
}
|
||||
|
||||
// NOTE: we cannot assume `main` is ascii.
|
||||
var main_module = bun.String.init(bun_vm.main);
|
||||
return main_module.transferToJS(globalThis);
|
||||
}
|
||||
|
||||
pub fn resolve(res: *ErrorableString, global: *JSGlobalObject, specifier: *bun.String, source: *bun.String, query: *ZigString) callconv(.C) void {
|
||||
JSC.markBinding(@src());
|
||||
return JSC.VirtualMachine.resolve(res, global, specifier.*, source.*, query, true) catch {
|
||||
@@ -782,6 +846,7 @@ pub const JSGlobalObject = opaque {
|
||||
pub const Extern = [_][]const u8{ "create", "getModuleRegistryMap", "resetModuleRegistryMap" };
|
||||
|
||||
comptime {
|
||||
@export(&determineMainModule, .{ .name = "Zig__GlobalObject__determineMainModule" });
|
||||
@export(&resolve, .{ .name = "Zig__GlobalObject__resolve" });
|
||||
@export(&reportUncaughtException, .{ .name = "Zig__GlobalObject__reportUncaughtException" });
|
||||
@export(&onCrash, .{ .name = "Zig__GlobalObject__onCrash" });
|
||||
|
||||
@@ -219,7 +219,8 @@ namespace JSCastingHelpers = JSC::JSCastingHelpers;
|
||||
|
||||
constexpr size_t DEFAULT_ERROR_STACK_TRACE_LIMIT = 10;
|
||||
|
||||
// #include <iostream>
|
||||
// defined in JSGlobalObject.zig
|
||||
extern "C" JSC::EncodedJSValue Zig__GlobalObject__determineMainModule(JSC::JSGlobalObject* globalObject);
|
||||
|
||||
Structure* createMemoryFootprintStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject);
|
||||
|
||||
@@ -3335,6 +3336,13 @@ void GlobalObject::finishCreation(VM& vm)
|
||||
InternalModuleRegistry::createStructure(init.vm, init.owner)));
|
||||
});
|
||||
|
||||
m_mainModule.initLater(
|
||||
[](const JSC::LazyProperty<JSC::JSGlobalObject, JSString>::Initializer& init) {
|
||||
JSC::JSValue mainModule = JSValue::decode(Zig__GlobalObject__determineMainModule(init.owner));
|
||||
ASSERT(mainModule.isString());
|
||||
init.set(jsCast<JSC::JSString*>(mainModule));
|
||||
});
|
||||
|
||||
m_processBindingBuffer.initLater(
|
||||
[](const JSC::LazyProperty<JSC::JSGlobalObject, JSC::JSObject>::Initializer& init) {
|
||||
init.set(
|
||||
|
||||
@@ -263,6 +263,8 @@ public:
|
||||
JSObject* requireFunctionUnbound() const { return m_requireFunctionUnbound.getInitializedOnMainThread(this); }
|
||||
JSObject* requireResolveFunctionUnbound() const { return m_requireResolveFunctionUnbound.getInitializedOnMainThread(this); }
|
||||
Bun::InternalModuleRegistry* internalModuleRegistry() const { return m_internalModuleRegistry.getInitializedOnMainThread(this); }
|
||||
/// Name of entrypoint module. Usually a path.
|
||||
JSString* mainModule() const { return m_mainModule.getInitializedOnMainThread(this); }
|
||||
|
||||
JSObject* processBindingBuffer() const { return m_processBindingBuffer.getInitializedOnMainThread(this); }
|
||||
JSObject* processBindingConstants() const { return m_processBindingConstants.getInitializedOnMainThread(this); }
|
||||
@@ -612,6 +614,7 @@ public:
|
||||
LazyProperty<JSGlobalObject, JSObject> m_requireFunctionUnbound;
|
||||
LazyProperty<JSGlobalObject, JSObject> m_requireResolveFunctionUnbound;
|
||||
LazyProperty<JSGlobalObject, Bun::InternalModuleRegistry> m_internalModuleRegistry;
|
||||
LazyProperty<JSGlobalObject, JSString> m_mainModule; // string | undefined. may be null.
|
||||
LazyProperty<JSGlobalObject, JSObject> m_processBindingBuffer;
|
||||
LazyProperty<JSGlobalObject, JSObject> m_processBindingConstants;
|
||||
LazyProperty<JSGlobalObject, JSObject> m_processBindingFs;
|
||||
|
||||
@@ -329,23 +329,6 @@ export function initializeNextTickQueue(process, nextTickQueue, drainMicrotasksF
|
||||
return nextTick;
|
||||
}
|
||||
|
||||
$getter;
|
||||
export function mainModule() {
|
||||
var existing = $getByIdDirectPrivate(this, "main");
|
||||
// note: this doesn't handle "process.mainModule = undefined"
|
||||
if (typeof existing !== "undefined") {
|
||||
return existing;
|
||||
}
|
||||
|
||||
return $requireMap.$get(Bun.main);
|
||||
}
|
||||
|
||||
$overriddenName = "set mainModule";
|
||||
export function setMainModule(value) {
|
||||
$putByIdDirectPrivate(this, "main", value);
|
||||
return true;
|
||||
}
|
||||
|
||||
type InternalEnvMap = Record<string, string>;
|
||||
type EditWindowsEnvVarCb = (key: string, value: null | string) => void;
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { spawnSync, which } from "bun";
|
||||
import { describe, expect, it } from "bun:test";
|
||||
import { describe, it, expect } from "bun:test";
|
||||
import { existsSync, readFileSync, writeFileSync } from "fs";
|
||||
import { bunEnv, bunExe, isWindows, tmpdirSync } from "harness";
|
||||
import path, { basename, join, resolve } from "path";
|
||||
import { basename, join, resolve } from "path";
|
||||
import { familySync } from "detect-libc";
|
||||
|
||||
expect.extend({
|
||||
@@ -1099,3 +1099,40 @@ it("process.memoryUsage.arrayBuffers", () => {
|
||||
array.buffer;
|
||||
expect(process.memoryUsage().arrayBuffers).toBeGreaterThanOrEqual(initial + 16 * 1024 * 1024);
|
||||
});
|
||||
|
||||
describe("process.mainModule", () => {
|
||||
it("is undefined when run via REPL", async () => {
|
||||
await Bun.$`${bunExe()} -e 'assert(process.mainModule === undefined)'`.nothrow();
|
||||
});
|
||||
|
||||
it("can be written to", () => {
|
||||
const descriptor = Object.getOwnPropertyDescriptor(process, "mainModule");
|
||||
expect(descriptor.configurable).toBe(true);
|
||||
|
||||
const prev = process.mainModule;
|
||||
expect(() => {
|
||||
// @ts-expect-error
|
||||
process.mainModule = "foo";
|
||||
}).not.toThrow();
|
||||
// @ts-expect-error
|
||||
expect(process.mainModule).toBe("foo");
|
||||
process.mainModule = prev;
|
||||
});
|
||||
|
||||
describe("When accessed from a file", () => {
|
||||
it.failing("is a NodeJS.Module object", () => {
|
||||
expect(process.mainModule).toBeObject();
|
||||
expect(process.mainModule).toMatchObject({
|
||||
children: expect.arrayContaining([expect.any(Object)]),
|
||||
exports: { foo: "bar" },
|
||||
filename: __filename,
|
||||
id: expect.any(String),
|
||||
isPreloading: expect.any(Boolean),
|
||||
loaded: true,
|
||||
path: __dirname,
|
||||
paths: expect.arrayContaining([expect.any(String)]),
|
||||
require: expect.any(Function),
|
||||
});
|
||||
});
|
||||
}); // when accessed from a file
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user