diff options
author | 2023-09-14 21:26:37 -0700 | |
---|---|---|
committer | 2023-09-14 21:26:37 -0700 | |
commit | ced69d38180e963da1206f9932db76666cec9f72 (patch) | |
tree | a4c4462ff8747adc7d092891b1c299dfbb0ecc4a /src | |
parent | b262b0153a2d9667fcb47a970e8027d3b54f8a0a (diff) | |
download | bun-ced69d38180e963da1206f9932db76666cec9f72.tar.gz bun-ced69d38180e963da1206f9932db76666cec9f72.tar.zst bun-ced69d38180e963da1206f9932db76666cec9f72.zip |
async-ify all node:fs functions (#5360)
* async all node:fs functions
* draw the rest of the owl
* LLVM & Clang 16
---------
Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/bun.js/event_loop.zig | 241 | ||||
-rw-r--r-- | src/bun.js/node/node_fs.zig | 2222 | ||||
-rw-r--r-- | src/bun.js/node/node_fs_binding.zig | 62 | ||||
-rw-r--r-- | src/bun.js/node/types.zig | 80 | ||||
-rw-r--r-- | src/js/node/fs.js | 74 | ||||
-rw-r--r-- | src/js/node/fs.promises.ts | 107 | ||||
-rw-r--r-- | src/js/out/InternalModuleRegistryConstants.h | 12 |
7 files changed, 1349 insertions, 1449 deletions
diff --git a/src/bun.js/event_loop.zig b/src/bun.js/event_loop.zig index c7de557f4..ed9d5b195 100644 --- a/src/bun.js/event_loop.zig +++ b/src/bun.js/event_loop.zig @@ -303,6 +303,48 @@ const PollPendingModulesTask = JSC.ModuleLoader.AsyncModule.Queue; // const PromiseTask = JSInternalPromise.Completion.PromiseTask; const GetAddrInfoRequestTask = JSC.DNS.GetAddrInfoRequest.Task; const JSCDeferredWorkTask = JSCScheduler.JSCDeferredWorkTask; + +const Stat = JSC.Node.Async.stat; +const Lstat = JSC.Node.Async.lstat; +const Fstat = JSC.Node.Async.fstat; +const Open = JSC.Node.Async.open; +const ReadFile = JSC.Node.Async.readFile; +const WriteFile = JSC.Node.Async.writeFile; +const CopyFile = JSC.Node.Async.copyFile; +const Read = JSC.Node.Async.read; +const Write = JSC.Node.Async.write; +const Truncate = JSC.Node.Async.truncate; +const FTruncate = JSC.Node.Async.ftruncate; +const Readdir = JSC.Node.Async.readdir; +const Readv = JSC.Node.Async.readv; +const Writev = JSC.Node.Async.writev; +const Close = JSC.Node.Async.close; +const Rm = JSC.Node.Async.rm; +const Rmdir = JSC.Node.Async.rmdir; +const Chown = JSC.Node.Async.chown; +const FChown = JSC.Node.Async.fchown; +const Utimes = JSC.Node.Async.utimes; +const Lutimes = JSC.Node.Async.lutimes; +const Chmod = JSC.Node.Async.chmod; +const Fchmod = JSC.Node.Async.fchmod; +const Link = JSC.Node.Async.link; +const Symlink = JSC.Node.Async.symlink; +const Readlink = JSC.Node.Async.readlink; +const Realpath = JSC.Node.Async.realpath; +const Mkdir = JSC.Node.Async.mkdir; +const Fsync = JSC.Node.Async.fsync; +const Rename = JSC.Node.Async.rename; +const Fdatasync = JSC.Node.Async.fdatasync; +const Access = JSC.Node.Async.access; +const AppendFile = JSC.Node.Async.appendFile; +const Mkdtemp = JSC.Node.Async.mkdtemp; +const Exists = JSC.Node.Async.exists; +const Futimes = JSC.Node.Async.futimes; +const Lchmod = JSC.Node.Async.lchmod; +const Lchown = JSC.Node.Async.lchown; +const Unlink = JSC.Node.Async.unlink; + +// Task.get(ReadFileTask) -> ?ReadFileTask pub const Task = TaggedPointerUnion(.{ FetchTasklet, Microtask, @@ -321,9 +363,45 @@ pub const Task = TaggedPointerUnion(.{ GetAddrInfoRequestTask, FSWatchTask, JSCDeferredWorkTask, - - // PromiseTask, - // TimeoutTasklet, + Stat, + Lstat, + Fstat, + Open, + ReadFile, + WriteFile, + CopyFile, + Read, + Write, + Truncate, + FTruncate, + Readdir, + Close, + Rm, + Rmdir, + Chown, + FChown, + Utimes, + Lutimes, + Chmod, + Fchmod, + Link, + Symlink, + Readlink, + Realpath, + Mkdir, + Fsync, + Fdatasync, + Writev, + Readv, + Rename, + Access, + AppendFile, + Mkdtemp, + Exists, + Futimes, + Lchmod, + Lchown, + Unlink, }); const UnboundedQueue = @import("./unbounded_queue.zig").UnboundedQueue; pub const ConcurrentTask = struct { @@ -535,7 +613,6 @@ pub const EventLoop = struct { } extern fn JSC__JSGlobalObject__drainMicrotasks(*JSC.JSGlobalObject) void; fn drainMicrotasksWithGlobal(this: *EventLoop, globalObject: *JSC.JSGlobalObject) void { - JSC.markBinding(@src()); JSC__JSGlobalObject__drainMicrotasks(globalObject); this.drainDeferredTasks(); } @@ -662,6 +739,162 @@ pub const EventLoop = struct { any.runFromJS(); any.deinit(); }, + @field(Task.Tag, typeBaseName(@typeName(Stat))) => { + var any: *Stat = task.get(Stat).?; + any.runFromJSThread(); + }, + @field(Task.Tag, typeBaseName(@typeName(Lstat))) => { + var any: *Lstat = task.get(Lstat).?; + any.runFromJSThread(); + }, + @field(Task.Tag, typeBaseName(@typeName(Fstat))) => { + var any: *Fstat = task.get(Fstat).?; + any.runFromJSThread(); + }, + @field(Task.Tag, typeBaseName(@typeName(Open))) => { + var any: *Open = task.get(Open).?; + any.runFromJSThread(); + }, + @field(Task.Tag, typeBaseName(@typeName(ReadFile))) => { + var any: *ReadFile = task.get(ReadFile).?; + any.runFromJSThread(); + }, + @field(Task.Tag, typeBaseName(@typeName(WriteFile))) => { + var any: *WriteFile = task.get(WriteFile).?; + any.runFromJSThread(); + }, + @field(Task.Tag, typeBaseName(@typeName(CopyFile))) => { + var any: *CopyFile = task.get(CopyFile).?; + any.runFromJSThread(); + }, + @field(Task.Tag, typeBaseName(@typeName(Read))) => { + var any: *Read = task.get(Read).?; + any.runFromJSThread(); + }, + @field(Task.Tag, typeBaseName(@typeName(Write))) => { + var any: *Write = task.get(Write).?; + any.runFromJSThread(); + }, + @field(Task.Tag, typeBaseName(@typeName(Truncate))) => { + var any: *Truncate = task.get(Truncate).?; + any.runFromJSThread(); + }, + @field(Task.Tag, typeBaseName(@typeName(Writev))) => { + var any: *Writev = task.get(Writev).?; + any.runFromJSThread(); + }, + @field(Task.Tag, typeBaseName(@typeName(Readv))) => { + var any: *Readv = task.get(Readv).?; + any.runFromJSThread(); + }, + @field(Task.Tag, typeBaseName(@typeName(Rename))) => { + var any: *Rename = task.get(Rename).?; + any.runFromJSThread(); + }, + @field(Task.Tag, typeBaseName(@typeName(FTruncate))) => { + var any: *FTruncate = task.get(FTruncate).?; + any.runFromJSThread(); + }, + @field(Task.Tag, typeBaseName(@typeName(Readdir))) => { + var any: *Readdir = task.get(Readdir).?; + any.runFromJSThread(); + }, + @field(Task.Tag, typeBaseName(@typeName(Close))) => { + var any: *Close = task.get(Close).?; + any.runFromJSThread(); + }, + @field(Task.Tag, typeBaseName(@typeName(Rm))) => { + var any: *Rm = task.get(Rm).?; + any.runFromJSThread(); + }, + @field(Task.Tag, typeBaseName(@typeName(Rmdir))) => { + var any: *Rmdir = task.get(Rmdir).?; + any.runFromJSThread(); + }, + @field(Task.Tag, typeBaseName(@typeName(Chown))) => { + var any: *Chown = task.get(Chown).?; + any.runFromJSThread(); + }, + @field(Task.Tag, typeBaseName(@typeName(FChown))) => { + var any: *FChown = task.get(FChown).?; + any.runFromJSThread(); + }, + @field(Task.Tag, typeBaseName(@typeName(Utimes))) => { + var any: *Utimes = task.get(Utimes).?; + any.runFromJSThread(); + }, + @field(Task.Tag, typeBaseName(@typeName(Lutimes))) => { + var any: *Lutimes = task.get(Lutimes).?; + any.runFromJSThread(); + }, + @field(Task.Tag, typeBaseName(@typeName(Chmod))) => { + var any: *Chmod = task.get(Chmod).?; + any.runFromJSThread(); + }, + @field(Task.Tag, typeBaseName(@typeName(Fchmod))) => { + var any: *Fchmod = task.get(Fchmod).?; + any.runFromJSThread(); + }, + @field(Task.Tag, typeBaseName(@typeName(Link))) => { + var any: *Link = task.get(Link).?; + any.runFromJSThread(); + }, + @field(Task.Tag, typeBaseName(@typeName(Symlink))) => { + var any: *Symlink = task.get(Symlink).?; + any.runFromJSThread(); + }, + @field(Task.Tag, typeBaseName(@typeName(Readlink))) => { + var any: *Readlink = task.get(Readlink).?; + any.runFromJSThread(); + }, + @field(Task.Tag, typeBaseName(@typeName(Realpath))) => { + var any: *Realpath = task.get(Realpath).?; + any.runFromJSThread(); + }, + @field(Task.Tag, typeBaseName(@typeName(Mkdir))) => { + var any: *Mkdir = task.get(Mkdir).?; + any.runFromJSThread(); + }, + @field(Task.Tag, typeBaseName(@typeName(Fsync))) => { + var any: *Fsync = task.get(Fsync).?; + any.runFromJSThread(); + }, + @field(Task.Tag, typeBaseName(@typeName(Fdatasync))) => { + var any: *Fdatasync = task.get(Fdatasync).?; + any.runFromJSThread(); + }, + @field(Task.Tag, typeBaseName(@typeName(Access))) => { + var any: *Access = task.get(Access).?; + any.runFromJSThread(); + }, + @field(Task.Tag, typeBaseName(@typeName(AppendFile))) => { + var any: *AppendFile = task.get(AppendFile).?; + any.runFromJSThread(); + }, + @field(Task.Tag, typeBaseName(@typeName(Mkdtemp))) => { + var any: *Mkdtemp = task.get(Mkdtemp).?; + any.runFromJSThread(); + }, + @field(Task.Tag, typeBaseName(@typeName(Exists))) => { + var any: *Exists = task.get(Exists).?; + any.runFromJSThread(); + }, + @field(Task.Tag, typeBaseName(@typeName(Futimes))) => { + var any: *Futimes = task.get(Futimes).?; + any.runFromJSThread(); + }, + @field(Task.Tag, typeBaseName(@typeName(Lchmod))) => { + var any: *Lchmod = task.get(Lchmod).?; + any.runFromJSThread(); + }, + @field(Task.Tag, typeBaseName(@typeName(Lchown))) => { + var any: *Lchown = task.get(Lchown).?; + any.runFromJSThread(); + }, + @field(Task.Tag, typeBaseName(@typeName(Unlink))) => { + var any: *Unlink = task.get(Unlink).?; + any.runFromJSThread(); + }, else => if (Environment.allow_assert) { bun.Output.prettyln("\nUnexpected tag: {s}\n", .{@tagName(task.tag())}); } else { diff --git a/src/bun.js/node/node_fs.zig b/src/bun.js/node/node_fs.zig index d9e3ed119..752d0e2fb 100644 --- a/src/bun.js/node/node_fs.zig +++ b/src/bun.js/node/node_fs.zig @@ -55,468 +55,147 @@ else // TODO: 0; +const SliceWithUnderlyingStringOrBuffer = JSC.Node.SliceWithUnderlyingStringOrBuffer; const ArrayBuffer = JSC.MarkedArrayBuffer; const Buffer = JSC.Buffer; const FileSystemFlags = JSC.Node.FileSystemFlags; +pub const Async = struct { + pub const access = NewAsyncFSTask(Return.Access, Arguments.Access, NodeFS.access); + pub const appendFile = NewAsyncFSTask(Return.AppendFile, Arguments.AppendFile, NodeFS.appendFile); + pub const chmod = NewAsyncFSTask(Return.Chmod, Arguments.Chmod, NodeFS.chmod); + pub const chown = NewAsyncFSTask(Return.Chown, Arguments.Chown, NodeFS.chown); + pub const close = NewAsyncFSTask(Return.Close, Arguments.Close, NodeFS.close); + pub const copyFile = NewAsyncFSTask(Return.CopyFile, Arguments.CopyFile, NodeFS.copyFile); + pub const exists = NewAsyncFSTask(Return.Exists, Arguments.Exists, NodeFS.exists); + pub const fchmod = NewAsyncFSTask(Return.Fchmod, Arguments.FChmod, NodeFS.fchmod); + pub const fchown = NewAsyncFSTask(Return.Fchown, Arguments.Fchown, NodeFS.fchown); + pub const fdatasync = NewAsyncFSTask(Return.Fdatasync, Arguments.FdataSync, NodeFS.fdatasync); + pub const fstat = NewAsyncFSTask(Return.Fstat, Arguments.Fstat, NodeFS.fstat); + pub const fsync = NewAsyncFSTask(Return.Fsync, Arguments.Fsync, NodeFS.fsync); + pub const ftruncate = NewAsyncFSTask(Return.Ftruncate, Arguments.FTruncate, NodeFS.ftruncate); + pub const futimes = NewAsyncFSTask(Return.Futimes, Arguments.Futimes, NodeFS.futimes); + pub const lchmod = NewAsyncFSTask(Return.Lchmod, Arguments.LCHmod, NodeFS.lchmod); + pub const lchown = NewAsyncFSTask(Return.Lchown, Arguments.LChown, NodeFS.lchown); + pub const link = NewAsyncFSTask(Return.Link, Arguments.Link, NodeFS.link); + pub const lstat = NewAsyncFSTask(Return.Stat, Arguments.Stat, NodeFS.lstat); + pub const lutimes = NewAsyncFSTask(Return.Lutimes, Arguments.Lutimes, NodeFS.lutimes); + pub const mkdir = NewAsyncFSTask(Return.Mkdir, Arguments.Mkdir, NodeFS.mkdir); + pub const mkdtemp = NewAsyncFSTask(Return.Mkdtemp, Arguments.MkdirTemp, NodeFS.mkdtemp); + pub const open = NewAsyncFSTask(Return.Open, Arguments.Open, NodeFS.open); + pub const read = NewAsyncFSTask(Return.Read, Arguments.Read, NodeFS.read); + pub const readdir = NewAsyncFSTask(Return.Readdir, Arguments.Readdir, NodeFS.readdir); + pub const readFile = NewAsyncFSTask(Return.ReadFile, Arguments.ReadFile, NodeFS.readFile); + pub const readlink = NewAsyncFSTask(Return.Readlink, Arguments.Readlink, NodeFS.readlink); + pub const readv = NewAsyncFSTask(Return.Readv, Arguments.Readv, NodeFS.readv); + pub const realpath = NewAsyncFSTask(Return.Realpath, Arguments.Realpath, NodeFS.realpath); + pub const rename = NewAsyncFSTask(Return.Rename, Arguments.Rename, NodeFS.rename); + pub const rm = NewAsyncFSTask(Return.Rm, Arguments.Rm, NodeFS.rm); + pub const rmdir = NewAsyncFSTask(Return.Rmdir, Arguments.RmDir, NodeFS.rmdir); + pub const stat = NewAsyncFSTask(Return.Stat, Arguments.Stat, NodeFS.stat); + pub const symlink = NewAsyncFSTask(Return.Symlink, Arguments.Symlink, NodeFS.symlink); + pub const truncate = NewAsyncFSTask(Return.Truncate, Arguments.Truncate, NodeFS.truncate); + pub const unlink = NewAsyncFSTask(Return.Unlink, Arguments.Unlink, NodeFS.unlink); + pub const utimes = NewAsyncFSTask(Return.Utimes, Arguments.Utimes, NodeFS.utimes); + pub const write = NewAsyncFSTask(Return.Write, Arguments.Write, NodeFS.write); + pub const writeFile = NewAsyncFSTask(Return.WriteFile, Arguments.WriteFile, NodeFS.writeFile); + pub const writev = NewAsyncFSTask(Return.Writev, Arguments.Writev, NodeFS.writev); + + pub const cp = AsyncCpTask; + + fn NewAsyncFSTask(comptime ReturnType: type, comptime ArgumentType: type, comptime Function: anytype) type { + return struct { + promise: JSC.JSPromise.Strong, + args: ArgumentType, + globalObject: *JSC.JSGlobalObject, + task: JSC.WorkPoolTask = .{ .callback = &workPoolCallback }, + result: JSC.Maybe(ReturnType), + ref: JSC.PollRef = .{}, + tracker: JSC.AsyncTaskTracker, + + pub const Task = @This(); + + pub fn create( + globalObject: *JSC.JSGlobalObject, + args: ArgumentType, + vm: *JSC.VirtualMachine, + ) JSC.JSValue { + var task = bun.default_allocator.create(Task) catch @panic("out of memory"); + task.* = Task{ + .promise = JSC.JSPromise.Strong.init(globalObject), + .args = args, + .result = undefined, + .globalObject = globalObject, + .tracker = JSC.AsyncTaskTracker.init(vm), + }; + task.ref.ref(vm); + task.args.toThreadSafe(); + task.tracker.didSchedule(globalObject); + JSC.WorkPool.schedule(&task.task); -pub const AsyncReaddirTask = struct { - promise: JSC.JSPromise.Strong, - args: Arguments.Readdir, - globalObject: *JSC.JSGlobalObject, - task: JSC.WorkPoolTask = .{ .callback = &workPoolCallback }, - result: JSC.Maybe(Return.Readdir), - ref: JSC.PollRef = .{}, - arena: bun.ArenaAllocator, - tracker: JSC.AsyncTaskTracker, - - pub fn create(globalObject: *JSC.JSGlobalObject, readdir_args: Arguments.Readdir, vm: *JSC.VirtualMachine, arena: bun.ArenaAllocator) JSC.JSValue { - var task = bun.default_allocator.create(AsyncReaddirTask) catch @panic("out of memory"); - task.* = AsyncReaddirTask{ - .promise = JSC.JSPromise.Strong.init(globalObject), - .args = readdir_args, - .result = undefined, - .globalObject = globalObject, - .arena = arena, - .tracker = JSC.AsyncTaskTracker.init(vm), - }; - task.ref.ref(vm); - task.args.path.toThreadSafe(); - task.tracker.didSchedule(globalObject); - JSC.WorkPool.schedule(&task.task); - - return task.promise.value(); - } - - fn workPoolCallback(task: *JSC.WorkPoolTask) void { - var this: *AsyncReaddirTask = @fieldParentPtr(AsyncReaddirTask, "task", task); - - var node_fs = NodeFS{}; - this.result = node_fs.readdir(this.args, .promise); - - if (this.result == .err) { - this.result.err.path = bun.default_allocator.dupe(u8, this.result.err.path) catch ""; - } - - this.globalObject.bunVMConcurrently().eventLoop().enqueueTaskConcurrent(JSC.ConcurrentTask.fromCallback(this, runFromJSThread)); - } - - fn runFromJSThread(this: *AsyncReaddirTask) void { - var globalObject = this.globalObject; - - var success = @as(JSC.Maybe(Return.Readdir).Tag, this.result) == .result; - const result = switch (this.result) { - .err => |err| err.toJSC(globalObject), - .result => |res| brk: { - var exceptionref: JSC.C.JSValueRef = null; - const out = JSC.JSValue.c(JSC.To.JS.withType(Return.Readdir, res, globalObject, &exceptionref)); - const exception = JSC.JSValue.c(exceptionref); - if (exception != .zero) { - success = false; - break :brk exception; - } - - break :brk out; - }, - }; - var promise_value = this.promise.value(); - var promise = this.promise.get(); - promise_value.ensureStillAlive(); - - const tracker = this.tracker; - this.deinit(); - - tracker.willDispatch(globalObject); - defer tracker.didDispatch(globalObject); - switch (success) { - false => { - promise.reject(globalObject, result); - }, - true => { - promise.resolve(globalObject, result); - }, - } - } - - pub fn deinit(this: *AsyncReaddirTask) void { - this.ref.unref(this.globalObject.bunVM()); - this.args.deinitAndUnprotect(); - this.promise.strong.deinit(); - this.arena.deinit(); - bun.default_allocator.destroy(this); - } -}; - -pub const AsyncStatTask = struct { - promise: JSC.JSPromise.Strong, - args: Arguments.Stat, - globalObject: *JSC.JSGlobalObject, - task: JSC.WorkPoolTask = .{ .callback = &workPoolCallback }, - result: JSC.Maybe(Return.Stat), - ref: JSC.PollRef = .{}, - is_lstat: bool = false, - arena: bun.ArenaAllocator, - tracker: JSC.AsyncTaskTracker, - - pub fn create( - globalObject: *JSC.JSGlobalObject, - readdir_args: Arguments.Stat, - vm: *JSC.VirtualMachine, - is_lstat: bool, - arena: bun.ArenaAllocator, - ) JSC.JSValue { - var task = bun.default_allocator.create(AsyncStatTask) catch @panic("out of memory"); - task.* = AsyncStatTask{ - .promise = JSC.JSPromise.Strong.init(globalObject), - .args = readdir_args, - .result = undefined, - .globalObject = globalObject, - .is_lstat = is_lstat, - .tracker = JSC.AsyncTaskTracker.init(vm), - .arena = arena, - }; - task.ref.ref(vm); - task.args.path.toThreadSafe(); - task.tracker.didSchedule(globalObject); - - JSC.WorkPool.schedule(&task.task); - - return task.promise.value(); - } - - fn workPoolCallback(task: *JSC.WorkPoolTask) void { - var this: *AsyncStatTask = @fieldParentPtr(AsyncStatTask, "task", task); - - var node_fs = NodeFS{}; - this.result = if (this.is_lstat) - node_fs.lstat(this.args, .promise) - else - node_fs.stat(this.args, .promise); - - this.globalObject.bunVMConcurrently().eventLoop().enqueueTaskConcurrent(JSC.ConcurrentTask.fromCallback(this, runFromJSThread)); - } - - fn runFromJSThread(this: *AsyncStatTask) void { - var globalObject = this.globalObject; - var success = @as(JSC.Maybe(Return.Lstat).Tag, this.result) == .result; - const result = switch (this.result) { - .err => |err| err.toJSC(globalObject), - .result => |res| brk: { - var exceptionref: JSC.C.JSValueRef = null; - const out = JSC.JSValue.c(JSC.To.JS.withType(Return.Lstat, res, globalObject, &exceptionref)); - const exception = JSC.JSValue.c(exceptionref); - if (exception != .zero) { - success = false; - break :brk exception; - } - - break :brk out; - }, - }; - var promise_value = this.promise.value(); - var promise = this.promise.get(); - promise_value.ensureStillAlive(); - - const tracker = this.tracker; - tracker.willDispatch(globalObject); - defer tracker.didDispatch(globalObject); - - this.deinit(); - switch (success) { - false => { - promise.reject(globalObject, result); - }, - true => { - promise.resolve(globalObject, result); - }, - } - } - - pub fn deinit(this: *AsyncStatTask) void { - this.ref.unref(this.globalObject.bunVM()); - this.args.deinitAndUnprotect(); - this.promise.strong.deinit(); - this.arena.deinit(); - bun.default_allocator.destroy(this); - } -}; - -pub const AsyncRealpathTask = struct { - promise: JSC.JSPromise.Strong, - args: Arguments.Realpath, - globalObject: *JSC.JSGlobalObject, - task: JSC.WorkPoolTask = .{ .callback = &workPoolCallback }, - result: JSC.Maybe(Return.Realpath), - ref: JSC.PollRef = .{}, - arena: bun.ArenaAllocator, - tracker: JSC.AsyncTaskTracker, - - pub fn create( - globalObject: *JSC.JSGlobalObject, - args: Arguments.Realpath, - vm: *JSC.VirtualMachine, - arena: bun.ArenaAllocator, - ) JSC.JSValue { - var task = bun.default_allocator.create(AsyncRealpathTask) catch @panic("out of memory"); - task.* = AsyncRealpathTask{ - .promise = JSC.JSPromise.Strong.init(globalObject), - .args = args, - .result = undefined, - .globalObject = globalObject, - .arena = arena, - .tracker = JSC.AsyncTaskTracker.init(vm), - }; - task.ref.ref(vm); - task.args.path.toThreadSafe(); - task.tracker.didSchedule(globalObject); - JSC.WorkPool.schedule(&task.task); - - return task.promise.value(); - } - - fn workPoolCallback(task: *JSC.WorkPoolTask) void { - var this: *AsyncRealpathTask = @fieldParentPtr(AsyncRealpathTask, "task", task); + return task.promise.value(); + } - var node_fs = NodeFS{}; - this.result = node_fs.realpath(this.args, .promise); + fn workPoolCallback(task: *JSC.WorkPoolTask) void { + var this: *Task = @fieldParentPtr(Task, "task", task); - if (this.result == .err) { - this.result.err.path = bun.default_allocator.dupe(u8, this.result.err.path) catch ""; - } + var node_fs = NodeFS{}; + this.result = Function(&node_fs, this.args, .promise); - this.globalObject.bunVMConcurrently().eventLoop().enqueueTaskConcurrent(JSC.ConcurrentTask.fromCallback(this, runFromJSThread)); - } - - fn runFromJSThread(this: *AsyncRealpathTask) void { - var globalObject = this.globalObject; - var success = @as(JSC.Maybe(Return.Realpath).Tag, this.result) == .result; - const result = switch (this.result) { - .err => |err| err.toJSC(globalObject), - .result => |res| brk: { - var exceptionref: JSC.C.JSValueRef = null; - const out = JSC.JSValue.c(JSC.To.JS.withType(Return.Realpath, res, globalObject, &exceptionref)); - const exception = JSC.JSValue.c(exceptionref); - if (exception != .zero) { - success = false; - break :brk exception; + if (this.result == .err) { + this.result.err.path = bun.default_allocator.dupe(u8, this.result.err.path) catch ""; + std.mem.doNotOptimizeAway(&node_fs); } - break :brk out; - }, - }; - var promise_value = this.promise.value(); - var promise = this.promise.get(); - promise_value.ensureStillAlive(); - - const tracker = this.tracker; - tracker.willDispatch(globalObject); - defer tracker.didDispatch(globalObject); - - this.deinit(); - switch (success) { - false => { - promise.reject(globalObject, result); - }, - true => { - promise.resolve(globalObject, result); - }, - } - } - - pub fn deinit(this: *AsyncRealpathTask) void { - if (this.result == .err) { - bun.default_allocator.free(this.result.err.path); - } - - this.ref.unref(this.globalObject.bunVM()); - this.args.deinitAndUnprotect(); - this.promise.strong.deinit(); - this.arena.deinit(); - bun.default_allocator.destroy(this); - } -}; - -pub const AsyncReadFileTask = struct { - promise: JSC.JSPromise.Strong, - args: Arguments.ReadFile, - globalObject: *JSC.JSGlobalObject, - task: JSC.WorkPoolTask = .{ .callback = &workPoolCallback }, - result: JSC.Maybe(Return.ReadFile), - ref: JSC.PollRef = .{}, - arena: bun.ArenaAllocator, - tracker: JSC.AsyncTaskTracker, - - pub fn create( - globalObject: *JSC.JSGlobalObject, - args: Arguments.ReadFile, - vm: *JSC.VirtualMachine, - arena: bun.ArenaAllocator, - ) JSC.JSValue { - var task = bun.default_allocator.create(AsyncReadFileTask) catch @panic("out of memory"); - task.* = AsyncReadFileTask{ - .promise = JSC.JSPromise.Strong.init(globalObject), - .args = args, - .result = undefined, - .globalObject = globalObject, - .arena = arena, - .tracker = JSC.AsyncTaskTracker.init(vm), - }; - task.ref.ref(vm); - task.args.path.toThreadSafe(); - task.tracker.didSchedule(globalObject); - JSC.WorkPool.schedule(&task.task); - - return task.promise.value(); - } - - fn workPoolCallback(task: *JSC.WorkPoolTask) void { - var this: *AsyncReadFileTask = @fieldParentPtr(AsyncReadFileTask, "task", task); - - var node_fs = NodeFS{}; - this.result = node_fs.readFile(this.args, .promise); - - if (this.result == .err) { - this.result.err.path = bun.default_allocator.dupe(u8, this.result.err.path) catch ""; - } - - this.globalObject.bunVMConcurrently().eventLoop().enqueueTaskConcurrent(JSC.ConcurrentTask.fromCallback(this, runFromJSThread)); - } + this.globalObject.bunVMConcurrently().eventLoop().enqueueTaskConcurrent(JSC.ConcurrentTask.create(JSC.Task.init(this))); + } - fn runFromJSThread(this: *AsyncReadFileTask) void { - var globalObject = this.globalObject; + pub fn runFromJSThread(this: *Task) void { + var globalObject = this.globalObject; + var success = @as(JSC.Maybe(ReturnType).Tag, this.result) == .result; + const result = switch (this.result) { + .err => |err| err.toJSC(globalObject), + .result => |res| brk: { + var exceptionref: JSC.C.JSValueRef = null; + const out = JSC.JSValue.c(JSC.To.JS.withType(ReturnType, res, globalObject, &exceptionref)); + const exception = JSC.JSValue.c(exceptionref); + if (exception != .zero) { + success = false; + break :brk exception; + } - var success = @as(JSC.Maybe(Return.ReadFile).Tag, this.result) == .result; - const result = switch (this.result) { - .err => |err| err.toJSC(globalObject), - .result => |res| brk: { - var exceptionref: JSC.C.JSValueRef = null; - const out = JSC.JSValue.c(JSC.To.JS.withType(Return.ReadFile, res, globalObject, &exceptionref)); - const exception = JSC.JSValue.c(exceptionref); - if (exception != .zero) { - success = false; - break :brk exception; + break :brk out; + }, + }; + var promise_value = this.promise.value(); + var promise = this.promise.get(); + promise_value.ensureStillAlive(); + + const tracker = this.tracker; + tracker.willDispatch(globalObject); + defer tracker.didDispatch(globalObject); + + this.deinit(); + switch (success) { + false => { + promise.reject(globalObject, result); + }, + true => { + promise.resolve(globalObject, result); + }, } + } - break :brk out; - }, - }; - var promise_value = this.promise.value(); - var promise = this.promise.get(); - promise_value.ensureStillAlive(); - - const tracker = this.tracker; - tracker.willDispatch(globalObject); - defer tracker.didDispatch(globalObject); - - this.deinit(); - switch (success) { - false => { - promise.reject(globalObject, result); - }, - true => { - promise.resolve(globalObject, result); - }, - } - } - - pub fn deinit(this: *AsyncReadFileTask) void { - this.ref.unref(this.globalObject.bunVM()); - this.args.deinitAndUnprotect(); - this.promise.strong.deinit(); - this.arena.deinit(); - bun.default_allocator.destroy(this); - } -}; - -pub const AsyncCopyFileTask = struct { - promise: JSC.JSPromise.Strong, - args: Arguments.CopyFile, - globalObject: *JSC.JSGlobalObject, - task: JSC.WorkPoolTask = .{ .callback = &workPoolCallback }, - result: JSC.Maybe(Return.CopyFile), - ref: JSC.PollRef = .{}, - arena: bun.ArenaAllocator, - tracker: JSC.AsyncTaskTracker, - - pub fn create( - globalObject: *JSC.JSGlobalObject, - copyfile_args: Arguments.CopyFile, - vm: *JSC.VirtualMachine, - arena: bun.ArenaAllocator, - ) JSC.JSValue { - var task = bun.default_allocator.create(AsyncCopyFileTask) catch @panic("out of memory"); - task.* = AsyncCopyFileTask{ - .promise = JSC.JSPromise.Strong.init(globalObject), - .args = copyfile_args, - .result = undefined, - .globalObject = globalObject, - .tracker = JSC.AsyncTaskTracker.init(vm), - .arena = arena, - }; - task.ref.ref(vm); - task.args.src.toThreadSafe(); - task.args.dest.toThreadSafe(); - task.tracker.didSchedule(globalObject); - - JSC.WorkPool.schedule(&task.task); - - return task.promise.value(); - } - - fn workPoolCallback(task: *JSC.WorkPoolTask) void { - var this: *AsyncCopyFileTask = @fieldParentPtr(AsyncCopyFileTask, "task", task); - - var node_fs = NodeFS{}; - this.result = node_fs.copyFile(this.args, .promise); - - if (this.result == .err) { - this.result.err.path = bun.default_allocator.dupe(u8, this.result.err.path) catch ""; - } - - this.globalObject.bunVMConcurrently().eventLoop().enqueueTaskConcurrent(JSC.ConcurrentTask.fromCallback(this, runFromJSThread)); - } - - fn runFromJSThread(this: *AsyncCopyFileTask) void { - var globalObject = this.globalObject; - var success = @as(JSC.Maybe(Return.CopyFile).Tag, this.result) == .result; - const result = switch (this.result) { - .err => |err| err.toJSC(globalObject), - .result => |res| brk: { - var exceptionref: JSC.C.JSValueRef = null; - const out = JSC.JSValue.c(JSC.To.JS.withType(Return.CopyFile, res, globalObject, &exceptionref)); - const exception = JSC.JSValue.c(exceptionref); - if (exception != .zero) { - success = false; - break :brk exception; + pub fn deinit(this: *Task) void { + if (this.result == .err) { + bun.default_allocator.free(this.result.err.path); } - break :brk out; - }, + this.ref.unref(this.globalObject.bunVM()); + this.args.deinit(); + this.promise.strong.deinit(); + bun.default_allocator.destroy(this); + } }; - var promise_value = this.promise.value(); - var promise = this.promise.get(); - promise_value.ensureStillAlive(); - - const tracker = this.tracker; - tracker.willDispatch(globalObject); - defer tracker.didDispatch(globalObject); - - this.deinit(); - switch (success) { - false => { - promise.reject(globalObject, result); - }, - true => { - promise.resolve(globalObject, result); - }, - } - } - - pub fn deinit(this: *AsyncCopyFileTask) void { - this.ref.unref(this.globalObject.bunVM()); - this.args.deinit(); - this.promise.strong.deinit(); - this.arena.deinit(); - bun.default_allocator.destroy(this); } }; @@ -710,6 +389,16 @@ pub const Arguments = struct { this.new_path.deinit(); } + pub fn deinitAndUnprotect(this: @This()) void { + this.old_path.deinitAndUnprotect(); + this.new_path.deinitAndUnprotect(); + } + + pub fn toThreadSafe(this: *@This()) void { + this.old_path.toThreadSafe(); + this.new_path.toThreadSafe(); + } + pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?Rename { const old_path = PathLike.fromJS(ctx, arguments, exception) orelse { if (exception.* == null) { @@ -748,8 +437,16 @@ pub const Arguments = struct { this.path.deinit(); } + pub fn deinitAndUnprotect(this: *@This()) void { + this.path.deinitAndUnprotect(); + } + + pub fn toThreadSafe(this: *@This()) void { + this.path.toThreadSafe(); + } + pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?Truncate { - const path = PathOrFileDescriptor.fromJS(ctx, arguments, arguments.arena.allocator(), exception) orelse { + const path = PathOrFileDescriptor.fromJS(ctx, arguments, bun.default_allocator, exception) orelse { if (exception.* == null) { JSC.throwInvalidArguments( "path must be a string or TypedArray", @@ -783,6 +480,21 @@ pub const Arguments = struct { pub fn deinit(_: *const @This()) void {} + pub fn deinitAndUnprotect(this: *const @This()) void { + this.buffers.value.unprotect(); + this.buffers.buffers.deinit(); + } + + pub fn toThreadSafe(this: *@This()) void { + this.buffers.value.protect(); + + var clone = bun.default_allocator.dupe(std.os.iovec, this.buffers.buffers.items) catch @panic("out of memory"); + this.buffers.buffers.deinit(); + this.buffers.buffers.items = clone; + this.buffers.buffers.capacity = clone.len; + this.buffers.buffers.allocator = bun.default_allocator; + } + pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?Writev { const fd_value = arguments.nextEat() orelse { if (exception.* == null) { @@ -855,7 +567,23 @@ pub const Arguments = struct { buffers: JSC.Node.VectorArrayBuffer, position: ?u52 = 0, - pub fn deinit(_: *const @This()) void {} + pub fn deinit(this: *const @This()) void { + _ = this; + } + + pub fn deinitAndUnprotect(this: *const @This()) void { + this.buffers.value.unprotect(); + this.buffers.buffers.deinit(); + } + + pub fn toThreadSafe(this: *@This()) void { + this.buffers.value.protect(); + var clone = bun.default_allocator.dupe(std.os.iovec, this.buffers.buffers.items) catch @panic("out of memory"); + this.buffers.buffers.deinit(); + this.buffers.buffers.items = clone; + this.buffers.buffers.capacity = clone.len; + this.buffers.buffers.allocator = bun.default_allocator; + } pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?Readv { const fd_value = arguments.nextEat() orelse { @@ -932,6 +660,14 @@ pub const Arguments = struct { _ = this; } + pub fn deinitAndUnprotect(this: *@This()) void { + _ = this; + } + + pub fn toThreadSafe(this: *const @This()) void { + _ = this; + } + pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?FTruncate { const fd = JSC.Node.fileDescriptorFromJS(ctx, arguments.next() orelse { if (exception.* == null) { @@ -982,6 +718,14 @@ pub const Arguments = struct { this.path.deinit(); } + pub fn deinitAndUnprotect(this: *@This()) void { + this.path.deinitAndUnprotect(); + } + + pub fn toThreadSafe(this: *@This()) void { + this.path.toThreadSafe(); + } + pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?Chown { const path = PathLike.fromJS(ctx, arguments, exception) orelse { if (exception.* == null) { @@ -1040,6 +784,8 @@ pub const Arguments = struct { pub fn deinit(_: @This()) void {} + pub fn toThreadSafe(_: *const @This()) void {} + pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?Fchown { const fd = JSC.Node.fileDescriptorFromJS(ctx, arguments.next() orelse { if (exception.* == null) { @@ -1114,6 +860,14 @@ pub const Arguments = struct { this.path.deinit(); } + pub fn deinitAndUnprotect(this: *@This()) void { + this.path.deinitAndUnprotect(); + } + + pub fn toThreadSafe(this: *@This()) void { + this.path.toThreadSafe(); + } + pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?Lutimes { const path = PathLike.fromJS(ctx, arguments, exception) orelse { if (exception.* == null) { @@ -1189,6 +943,14 @@ pub const Arguments = struct { this.path.deinit(); } + pub fn toThreadSafe(this: *@This()) void { + this.path.toThreadSafe(); + } + + pub fn deinitAndUnprotect(this: *@This()) void { + this.path.deinitAndUnprotect(); + } + pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?Chmod { const path = PathLike.fromJS(ctx, arguments, exception) orelse { if (exception.* == null) { @@ -1234,6 +996,10 @@ pub const Arguments = struct { fd: FileDescriptor, mode: Mode = 0x777, + pub fn deinit(_: *const @This()) void {} + + pub fn toThreadSafe(_: *const @This()) void {} + pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?FChmod { const fd = JSC.Node.fileDescriptorFromJS(ctx, arguments.next() orelse { if (exception.* == null) { @@ -1303,6 +1069,10 @@ pub const Arguments = struct { this.path.deinitAndUnprotect(); } + pub fn toThreadSafe(this: *Stat) void { + this.path.toThreadSafe(); + } + pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?Stat { const path = PathLike.fromJSWithAllocator(ctx, arguments, bun.default_allocator, exception) orelse { if (exception.* == null) { @@ -1356,6 +1126,8 @@ pub const Arguments = struct { pub fn deinit(_: @This()) void {} + pub fn toThreadSafe(_: *@This()) void {} + pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?Fstat { const fd = JSC.Node.fileDescriptorFromJS(ctx, arguments.next() orelse { if (exception.* == null) { @@ -1412,6 +1184,16 @@ pub const Arguments = struct { this.new_path.deinit(); } + pub fn deinitAndUnprotect(this: *Link) void { + this.old_path.deinitAndUnprotect(); + this.new_path.deinitAndUnprotect(); + } + + pub fn toThreadSafe(this: *Link) void { + this.old_path.toThreadSafe(); + this.new_path.toThreadSafe(); + } + pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?Link { const old_path = PathLike.fromJS(ctx, arguments, exception) orelse { if (exception.* == null) { @@ -1454,6 +1236,16 @@ pub const Arguments = struct { this.new_path.deinit(); } + pub fn deinitAndUnprotect(this: Symlink) void { + this.old_path.deinitAndUnprotect(); + this.new_path.deinitAndUnprotect(); + } + + pub fn toThreadSafe(this: *@This()) void { + this.old_path.toThreadSafe(); + this.new_path.toThreadSafe(); + } + pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?Symlink { const old_path = PathLike.fromJS(ctx, arguments, exception) orelse { if (exception.* == null) { @@ -1512,6 +1304,14 @@ pub const Arguments = struct { this.path.deinit(); } + pub fn deinitAndUnprotect(this: *Readlink) void { + this.path.deinitAndUnprotect(); + } + + pub fn toThreadSafe(this: *Readlink) void { + this.path.toThreadSafe(); + } + pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?Readlink { const path = PathLike.fromJS(ctx, arguments, exception) orelse { if (exception.* == null) { @@ -1560,6 +1360,10 @@ pub const Arguments = struct { this.path.deinitAndUnprotect(); } + pub fn toThreadSafe(this: *Realpath) void { + this.path.toThreadSafe(); + } + pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?Realpath { const path = PathLike.fromJS(ctx, arguments, exception) orelse { if (exception.* == null) { @@ -1599,6 +1403,18 @@ pub const Arguments = struct { pub const Unlink = struct { path: PathLike, + pub fn deinit(this: Unlink) void { + this.path.deinit(); + } + + pub fn deinitAndUnprotect(this: *Unlink) void { + this.path.deinitAndUnprotect(); + } + + pub fn toThreadSafe(this: *Unlink) void { + this.path.toThreadSafe(); + } + pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?Unlink { const path = PathLike.fromJS(ctx, arguments, exception) orelse { if (exception.* == null) { @@ -1620,13 +1436,7 @@ pub const Arguments = struct { } }; - pub const Rm = struct { - path: PathLike, - force: bool = false, - max_retries: u32 = 0, - recursive: bool = false, - retry_delay: c_uint = 100, - }; + pub const Rm = RmDir; pub const RmDir = struct { path: PathLike, @@ -1637,6 +1447,14 @@ pub const Arguments = struct { recursive: bool = false, retry_delay: c_uint = 100, + pub fn deinitAndUnprotect(this: *RmDir) void { + this.path.deinitAndUnprotect(); + } + + pub fn toThreadSafe(this: *RmDir) void { + this.path.toThreadSafe(); + } + pub fn deinit(this: RmDir) void { this.path.deinit(); } @@ -1701,6 +1519,14 @@ pub const Arguments = struct { this.path.deinit(); } + pub fn deinitAndUnprotect(this: *Mkdir) void { + this.path.deinitAndUnprotect(); + } + + pub fn toThreadSafe(this: *Mkdir) void { + this.path.toThreadSafe(); + } + pub fn fromJS(ctx: *JSC.JSGlobalObject, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?Mkdir { const path = PathLike.fromJS(ctx, arguments, exception) orelse { if (exception.* == null) { @@ -1752,10 +1578,18 @@ pub const Arguments = struct { this.prefix.deinit(); } + pub fn deinitAndUnprotect(this: *MkdirTemp) void { + this.prefix.deinit(); + } + + pub fn toThreadSafe(this: *MkdirTemp) void { + this.prefix.toThreadSafe(); + } + pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?MkdirTemp { const prefix_value = arguments.next() orelse return MkdirTemp{}; - var prefix = JSC.Node.SliceOrBuffer.fromJS(ctx, arguments.arena.allocator(), prefix_value) orelse { + var prefix = JSC.Node.SliceOrBuffer.fromJS(ctx, bun.default_allocator, prefix_value) orelse { if (exception.* == null) { JSC.throwInvalidArguments( "prefix must be a string or TypedArray", @@ -1810,6 +1644,10 @@ pub const Arguments = struct { this.path.deinitAndUnprotect(); } + pub fn toThreadSafe(this: *Readdir) void { + this.path.toThreadSafe(); + } + pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?Readdir { const path = PathLike.fromJSWithAllocator(ctx, arguments, bun.default_allocator, exception) orelse { if (exception.* == null) { @@ -1864,6 +1702,7 @@ pub const Arguments = struct { fd: FileDescriptor, pub fn deinit(_: Close) void {} + pub fn toThreadSafe(_: Close) void {} pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?Close { const fd = JSC.Node.fileDescriptorFromJS(ctx, arguments.next() orelse { @@ -1905,6 +1744,14 @@ pub const Arguments = struct { this.path.deinit(); } + pub fn deinitAndUnprotect(this: Open) void { + this.path.deinitAndUnprotect(); + } + + pub fn toThreadSafe(this: *Open) void { + this.path.toThreadSafe(); + } + pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?Open { const path = PathLike.fromJS(ctx, arguments, exception) orelse { if (exception.* == null) { @@ -1971,6 +1818,10 @@ pub const Arguments = struct { pub fn deinit(_: Futimes) void {} + pub fn toThreadSafe(self: *const @This()) void { + _ = self; + } + pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?Futimes { const fd = JSC.Node.fileDescriptorFromJS(ctx, arguments.next() orelse { if (exception.* == null) { @@ -2052,42 +1903,6 @@ pub const Arguments = struct { } }; - pub const FSync = struct { - fd: FileDescriptor, - - pub fn deinit(_: FSync) void {} - - pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?FSync { - const fd = JSC.Node.fileDescriptorFromJS(ctx, arguments.next() orelse { - if (exception.* == null) { - JSC.throwInvalidArguments( - "File descriptor is required", - .{}, - ctx, - exception, - ); - } - return null; - }, exception) orelse { - if (exception.* == null) { - JSC.throwInvalidArguments( - "fd must be a number", - .{}, - ctx, - exception, - ); - } - return null; - }; - - if (exception.* != null) return null; - - return FSync{ - .fd = fd, - }; - } - }; - /// Write `buffer` to the file specified by `fd`. If `buffer` is a normal object, it /// must have an own `toString` function property. /// @@ -2114,7 +1929,7 @@ pub const Arguments = struct { /// pub const Write = struct { fd: FileDescriptor, - buffer: StringOrBuffer, + buffer: JSC.Node.SliceWithUnderlyingStringOrBuffer, // buffer_val: JSC.JSValue = JSC.JSValue.zero, offset: u64 = 0, length: u64 = std.math.maxInt(u64), @@ -2123,6 +1938,10 @@ pub const Arguments = struct { pub fn deinit(_: Write) void {} + pub fn toThreadSafe(self: *@This()) void { + self.buffer.toThreadSafe(); + } + pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?Write { const fd = JSC.Node.fileDescriptorFromJS(ctx, arguments.next() orelse { if (exception.* == null) { @@ -2150,7 +1969,7 @@ pub const Arguments = struct { if (exception.* != null) return null; - const buffer = StringOrBuffer.fromJS(ctx.ptr(), arguments.arena.allocator(), arguments.next() orelse { + const buffer = SliceWithUnderlyingStringOrBuffer.fromJS(ctx.ptr(), bun.default_allocator, arguments.next() orelse { if (exception.* == null) { JSC.throwInvalidArguments( "data is required", @@ -2177,7 +1996,7 @@ pub const Arguments = struct { .fd = fd, .buffer = buffer, .encoding = switch (buffer) { - .string => Encoding.utf8, + .SliceWithUnderlyingString => Encoding.utf8, .buffer => Encoding.buffer, }, }; @@ -2190,7 +2009,7 @@ pub const Arguments = struct { var current = current_; switch (buffer) { // fs.write(fd, string[, position[, encoding]], callback) - .string => { + .SliceWithUnderlyingString => { if (current.isNumber()) { args.position = current.to(i52); arguments.eat(); @@ -2239,6 +2058,14 @@ pub const Arguments = struct { pub fn deinit(_: Read) void {} + pub fn toThreadSafe(this: Read) void { + this.buffer.buffer.value.protect(); + } + + pub fn deinitAndUnprotect(this: *Read) void { + this.buffer.buffer.value.unprotect(); + } + pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?Read { const fd = JSC.Node.fileDescriptorFromJS(ctx, arguments.next() orelse { if (exception.* == null) { @@ -2377,6 +2204,10 @@ pub const Arguments = struct { self.path.deinitAndUnprotect(); } + pub fn toThreadSafe(self: *ReadFile) void { + self.path.toThreadSafe(); + } + pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?ReadFile { const path = PathOrFileDescriptor.fromJS(ctx, arguments, bun.default_allocator, exception) orelse { if (exception.* == null) { @@ -2463,8 +2294,16 @@ pub const Arguments = struct { self.file.deinit(); } + pub fn toThreadSafe(self: *WriteFile) void { + self.file.toThreadSafe(); + } + + pub fn deinitAndUnprotect(self: *WriteFile) void { + self.file.deinitAndUnprotect(); + } + pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?WriteFile { - const file = PathOrFileDescriptor.fromJS(ctx, arguments, arguments.arena.allocator(), exception) orelse { + const file = PathOrFileDescriptor.fromJS(ctx, arguments, bun.default_allocator, exception) orelse { if (exception.* == null) { JSC.throwInvalidArguments( "path must be a string or a file descriptor", @@ -2478,7 +2317,7 @@ pub const Arguments = struct { if (exception.* != null) return null; - const data = StringOrBuffer.fromJS(ctx.ptr(), arguments.arena.allocator(), arguments.next() orelse { + const data = StringOrBuffer.fromJS(ctx.ptr(), bun.default_allocator, arguments.next() orelse { if (exception.* == null) { JSC.throwInvalidArguments( "data is required", @@ -2673,6 +2512,18 @@ pub const Arguments = struct { } } + pub fn toThreadSafe(this: *Exists) void { + if (this.path) |*path| { + path.toThreadSafe(); + } + } + + pub fn deinitAndUnprotect(this: *Exists) void { + if (this.path) |*path| { + path.deinitAndUnprotect(); + } + } + pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?Exists { return Exists{ .path = PathLike.fromJS(ctx, arguments, exception), @@ -2688,6 +2539,14 @@ pub const Arguments = struct { this.path.deinit(); } + pub fn toThreadSafe(this: *Access) void { + this.path.toThreadSafe(); + } + + pub fn deinitAndUnprotect(this: *Access) void { + this.path.deinitAndUnprotect(); + } + pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?Access { const path = PathLike.fromJS(ctx, arguments, exception) orelse { if (exception.* == null) { @@ -3002,6 +2861,9 @@ pub const Arguments = struct { fd: FileDescriptor, pub fn deinit(_: FdataSync) void {} + pub fn toThreadSafe(self: *const @This()) void { + _ = self; + } pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?FdataSync { const fd = JSC.Node.fileDescriptorFromJS(ctx, arguments.next() orelse { @@ -3039,11 +2901,21 @@ pub const Arguments = struct { dest: PathLike, mode: Constants.Copyfile, - fn deinit(this: CopyFile) void { + pub fn deinit(this: CopyFile) void { this.src.deinit(); this.dest.deinit(); } + pub fn toThreadSafe(this: *CopyFile) void { + this.src.toThreadSafe(); + this.dest.toThreadSafe(); + } + + pub fn deinitAndUnprotect(this: *CopyFile) void { + this.src.deinitAndUnprotect(); + this.dest.deinitAndUnprotect(); + } + pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?CopyFile { const src = PathLike.fromJSWithAllocator(ctx, arguments, bun.default_allocator, exception) orelse { if (exception.* == null) { @@ -3196,6 +3068,9 @@ pub const Arguments = struct { pub const Fsync = struct { fd: FileDescriptor, + pub fn deinit(_: Fsync) void {} + pub fn toThreadSafe(_: *const @This()) void {} + pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?Fsync { const fd = JSC.Node.fileDescriptorFromJS(ctx, arguments.next() orelse { if (exception.* == null) { @@ -3411,69 +3286,49 @@ pub const NodeFS = struct { } pub fn appendFile(this: *NodeFS, args: Arguments.AppendFile, comptime flavor: Flavor) Maybe(Return.AppendFile) { + _ = flavor; var data = args.data.slice(); switch (args.file) { .fd => |fd| { - switch (comptime flavor) { - .sync => { - while (data.len > 0) { - const written = switch (Syscall.write(fd, data)) { - .result => |result| result, - .err => |err| return .{ .err = err }, - }; - data = data[written..]; - } - - return Maybe(Return.AppendFile).success; - }, - else => { - @compileError("Not implemented yet"); - }, + while (data.len > 0) { + const written = switch (Syscall.write(fd, data)) { + .result => |result| result, + .err => |err| return .{ .err = err }, + }; + data = data[written..]; } + + return Maybe(Return.AppendFile).success; }, .path => |path_| { const path = path_.sliceZ(&this.sync_error_buf); - switch (comptime flavor) { - .sync => { - const fd = switch (Syscall.open(path, @intFromEnum(FileSystemFlags.a), 0o000666)) { - .result => |result| result, - .err => |err| return .{ .err = err }, - }; - defer { - _ = Syscall.close(fd); - } + const fd = switch (Syscall.open(path, @intFromEnum(FileSystemFlags.a), 0o000666)) { + .result => |result| result, + .err => |err| return .{ .err = err }, + }; - while (data.len > 0) { - const written = switch (Syscall.write(fd, data)) { - .result => |result| result, - .err => |err| return .{ .err = err }, - }; - data = data[written..]; - } + defer { + _ = Syscall.close(fd); + } - return Maybe(Return.AppendFile).success; - }, - else => { - @compileError("Not implemented yet"); - }, + while (data.len > 0) { + const written = switch (Syscall.write(fd, data)) { + .result => |result| result, + .err => |err| return .{ .err = err }, + }; + data = data[written..]; } + + return Maybe(Return.AppendFile).success; }, } - - return Maybe(Return.AppendFile).todo; } pub fn close(_: *NodeFS, args: Arguments.Close, comptime flavor: Flavor) Maybe(Return.Close) { - switch (comptime flavor) { - .sync => { - return if (Syscall.close(args.fd)) |err| .{ .err = err } else Maybe(Return.Close).success; - }, - else => {}, - } - - return .{ .err = Syscall.Error.todo }; + _ = flavor; + return if (Syscall.close(args.fd)) |err| .{ .err = err } else Maybe(Return.Close).success; } // since we use a 64 KB stack buffer, we should not let this function get inlined @@ -3714,132 +3569,92 @@ pub const NodeFS = struct { } pub fn exists(this: *NodeFS, args: Arguments.Exists, comptime flavor: Flavor) Maybe(Return.Exists) { + _ = flavor; const Ret = Maybe(Return.Exists); - switch (comptime flavor) { - .sync => { - const path = args.path orelse return Ret{ .result = false }; - const slice = path.sliceZ(&this.sync_error_buf); - // access() may not work correctly on NFS file systems with UID - // mapping enabled, because UID mapping is done on the server and - // hidden from the client, which checks permissions. Similar - // problems can occur to FUSE mounts. - const rc = (system.access(slice, std.os.F_OK)); - return Ret{ .result = rc == 0 }; - }, - else => {}, - } - - return Ret.todo; + const path = args.path orelse return Ret{ .result = false }; + const slice = path.sliceZ(&this.sync_error_buf); + // access() may not work correctly on NFS file systems with UID + // mapping enabled, because UID mapping is done on the server and + // hidden from the client, which checks permissions. Similar + // problems can occur to FUSE mounts. + const rc = (system.access(slice, std.os.F_OK)); + return Ret{ .result = rc == 0 }; } pub fn chown(this: *NodeFS, args: Arguments.Chown, comptime flavor: Flavor) Maybe(Return.Chown) { + _ = flavor; if (comptime Environment.isWindows) { return Maybe(Return.Fchmod).todo; } const path = args.path.sliceZ(&this.sync_error_buf); - switch (comptime flavor) { - .sync => return Syscall.chown(path, args.uid, args.gid), - else => {}, - } - - return Maybe(Return.Chown).todo; + return Syscall.chown(path, args.uid, args.gid); } /// This should almost never be async pub fn chmod(this: *NodeFS, args: Arguments.Chmod, comptime flavor: Flavor) Maybe(Return.Chmod) { + _ = flavor; if (comptime Environment.isWindows) { return Maybe(Return.Fchmod).todo; } const path = args.path.sliceZ(&this.sync_error_buf); - switch (comptime flavor) { - .sync => { - return Maybe(Return.Chmod).errnoSysP(C.chmod(path, args.mode), .chmod, path) orelse - Maybe(Return.Chmod).success; - }, - else => {}, - } - - return Maybe(Return.Chmod).todo; + return Maybe(Return.Chmod).errnoSysP(C.chmod(path, args.mode), .chmod, path) orelse + Maybe(Return.Chmod).success; } /// This should almost never be async pub fn fchmod(_: *NodeFS, args: Arguments.FChmod, comptime flavor: Flavor) Maybe(Return.Fchmod) { + _ = flavor; if (comptime Environment.isWindows) { return Maybe(Return.Fchmod).todo; } - switch (comptime flavor) { - .sync => { - return Syscall.fchmod(args.fd, args.mode); - }, - else => {}, - } - - return Maybe(Return.Fchmod).todo; + return Syscall.fchmod(args.fd, args.mode); } pub fn fchown(_: *NodeFS, args: Arguments.Fchown, comptime flavor: Flavor) Maybe(Return.Fchown) { + _ = flavor; if (comptime Environment.isWindows) { return Maybe(Return.Fchown).todo; } - switch (comptime flavor) { - .sync => { - return Maybe(Return.Fchown).errnoSys(C.fchown(args.fd, args.uid, args.gid), .fchown) orelse - Maybe(Return.Fchown).success; - }, - else => {}, - } - - return Maybe(Return.Fchown).todo; + return Maybe(Return.Fchown).errnoSys(C.fchown(args.fd, args.uid, args.gid), .fchown) orelse + Maybe(Return.Fchown).success; } pub fn fdatasync(_: *NodeFS, args: Arguments.FdataSync, comptime flavor: Flavor) Maybe(Return.Fdatasync) { + _ = flavor; if (comptime Environment.isWindows) { return Maybe(Return.Fdatasync).todo; } - switch (comptime flavor) { - .sync => return Maybe(Return.Fdatasync).errnoSys(system.fdatasync(args.fd), .fdatasync) orelse - Maybe(Return.Fdatasync).success, - else => {}, - } - - return Maybe(Return.Fdatasync).todo; + return Maybe(Return.Fdatasync).errnoSys(system.fdatasync(args.fd), .fdatasync) orelse + Maybe(Return.Fdatasync).success; } pub fn fstat(_: *NodeFS, args: Arguments.Fstat, comptime flavor: Flavor) Maybe(Return.Fstat) { + _ = flavor; if (comptime Environment.isWindows) { return Maybe(Return.Fstat).todo; } - switch (comptime flavor) { - .sync => { - if (comptime Environment.isPosix) { - return switch (Syscall.fstat(args.fd)) { - .result => |result| Maybe(Return.Fstat){ .result = Stats.init(result, false) }, - .err => |err| Maybe(Return.Fstat){ .err = err }, - }; - } - }, - else => {}, + if (comptime Environment.isPosix) { + return switch (Syscall.fstat(args.fd)) { + .result => |result| Maybe(Return.Fstat){ .result = Stats.init(result, false) }, + .err => |err| Maybe(Return.Fstat){ .err = err }, + }; } return Maybe(Return.Fstat).todo; } pub fn fsync(_: *NodeFS, args: Arguments.Fsync, comptime flavor: Flavor) Maybe(Return.Fsync) { + _ = flavor; if (comptime Environment.isWindows) { return Maybe(Return.Fsync).todo; } - switch (comptime flavor) { - .sync => return Maybe(Return.Fsync).errnoSys(system.fsync(args.fd), .fsync) orelse - Maybe(Return.Fsync).success, - else => {}, - } - - return Maybe(Return.Fsync).todo; + return Maybe(Return.Fsync).errnoSys(system.fsync(args.fd), .fsync) orelse + Maybe(Return.Fsync).success; } pub fn ftruncateSync(args: Arguments.FTruncate) Maybe(Return.Ftruncate) { @@ -3847,14 +3662,11 @@ pub const NodeFS = struct { } pub fn ftruncate(_: *NodeFS, args: Arguments.FTruncate, comptime flavor: Flavor) Maybe(Return.Ftruncate) { - switch (comptime flavor) { - .sync => return ftruncateSync(args), - else => {}, - } - - return Maybe(Return.Ftruncate).todo; + _ = flavor; + return ftruncateSync(args); } pub fn futimes(_: *NodeFS, args: Arguments.Futimes, comptime flavor: Flavor) Maybe(Return.Futimes) { + _ = flavor; if (comptime Environment.isWindows) { return Maybe(Return.Futimes).todo; } @@ -3870,66 +3682,43 @@ pub const NodeFS = struct { }, }; - switch (comptime flavor) { - .sync => return if (Maybe(Return.Futimes).errnoSys(system.futimens(args.fd, ×), .futimens)) |err| - err - else - Maybe(Return.Futimes).success, - else => {}, - } - - return Maybe(Return.Futimes).todo; + return if (Maybe(Return.Futimes).errnoSys(system.futimens(args.fd, ×), .futimens)) |err| + err + else + Maybe(Return.Futimes).success; } pub fn lchmod(this: *NodeFS, args: Arguments.LCHmod, comptime flavor: Flavor) Maybe(Return.Lchmod) { + _ = flavor; if (comptime Environment.isWindows) { return Maybe(Return.Lchmod).todo; } const path = args.path.sliceZ(&this.sync_error_buf); - switch (comptime flavor) { - .sync => { - return Maybe(Return.Lchmod).errnoSysP(C.lchmod(path, args.mode), .lchmod, path) orelse - Maybe(Return.Lchmod).success; - }, - else => {}, - } - - return Maybe(Return.Lchmod).todo; + return Maybe(Return.Lchmod).errnoSysP(C.lchmod(path, args.mode), .lchmod, path) orelse + Maybe(Return.Lchmod).success; } pub fn lchown(this: *NodeFS, args: Arguments.LChown, comptime flavor: Flavor) Maybe(Return.Lchown) { + _ = flavor; if (comptime Environment.isWindows) { return Maybe(Return.Lchown).todo; } const path = args.path.sliceZ(&this.sync_error_buf); - switch (comptime flavor) { - .sync => { - return Maybe(Return.Lchown).errnoSysP(C.lchown(path, args.uid, args.gid), .lchown, path) orelse - Maybe(Return.Lchown).success; - }, - else => {}, - } - - return Maybe(Return.Lchown).todo; + return Maybe(Return.Lchown).errnoSysP(C.lchown(path, args.uid, args.gid), .lchown, path) orelse + Maybe(Return.Lchown).success; } pub fn link(this: *NodeFS, args: Arguments.Link, comptime flavor: Flavor) Maybe(Return.Link) { + _ = flavor; var new_path_buf: [bun.MAX_PATH_BYTES]u8 = undefined; const from = args.old_path.sliceZ(&this.sync_error_buf); const to = args.new_path.sliceZ(&new_path_buf); - switch (comptime flavor) { - .sync => { - return Maybe(Return.Link).errnoSysP(system.link(from, to, 0), .link, from) orelse - Maybe(Return.Link).success; - }, - else => {}, - } - - return Maybe(Return.Link).todo; + return Maybe(Return.Link).errnoSysP(system.link(from, to, 0), .link, from) orelse + Maybe(Return.Link).success; } pub fn lstat(this: *NodeFS, args: Arguments.Lstat, comptime flavor: Flavor) Maybe(Return.Lstat) { if (comptime Environment.isWindows) { @@ -3957,158 +3746,146 @@ pub const NodeFS = struct { } // Node doesn't absolute the path so we don't have to either fn mkdirNonRecursive(this: *NodeFS, args: Arguments.Mkdir, comptime flavor: Flavor) Maybe(Return.Mkdir) { - switch (comptime flavor) { - .sync => { - const path = args.path.sliceZ(&this.sync_error_buf); - return switch (Syscall.mkdir(path, args.mode)) { - .result => Maybe(Return.Mkdir){ .result = bun.String.empty }, - .err => |err| Maybe(Return.Mkdir){ .err = err }, - }; - }, - else => {}, - } + _ = flavor; - return Maybe(Return.Mkdir).todo; + const path = args.path.sliceZ(&this.sync_error_buf); + return switch (Syscall.mkdir(path, args.mode)) { + .result => Maybe(Return.Mkdir){ .result = bun.String.empty }, + .err => |err| Maybe(Return.Mkdir){ .err = err }, + }; } // TODO: windows // TODO: verify this works correctly with unicode codepoints pub fn mkdirRecursive(this: *NodeFS, args: Arguments.Mkdir, comptime flavor: Flavor) Maybe(Return.Mkdir) { + _ = flavor; const Option = Maybe(Return.Mkdir); if (comptime Environment.isWindows) return Option.todo; - switch (comptime flavor) { - // The sync version does no allocation except when returning the path - .sync => { - var buf: [bun.MAX_PATH_BYTES]u8 = undefined; - const path = args.path.sliceZWithForceCopy(&buf, true); - const len = @as(u16, @truncate(path.len)); - - // First, attempt to create the desired directory - // If that fails, then walk back up the path until we have a match - switch (Syscall.mkdir(path, args.mode)) { - .err => |err| { - switch (err.getErrno()) { - else => { - @memcpy(this.sync_error_buf[0..len], path[0..len]); - return .{ .err = err.withPath(this.sync_error_buf[0..len]) }; - }, + var buf: [bun.MAX_PATH_BYTES]u8 = undefined; + const path = args.path.sliceZWithForceCopy(&buf, true); + const len = @as(u16, @truncate(path.len)); - .EXIST => { - return Option{ .result = bun.String.empty }; - }, - // continue - .NOENT => {}, - } + // First, attempt to create the desired directory + // If that fails, then walk back up the path until we have a match + switch (Syscall.mkdir(path, args.mode)) { + .err => |err| { + switch (err.getErrno()) { + else => { + @memcpy(this.sync_error_buf[0..len], path[0..len]); + return .{ .err = err.withPath(this.sync_error_buf[0..len]) }; }, - .result => { - return Option{ - .result = if (args.path == .slice_with_underlying_string) - args.path.slice_with_underlying_string.underlying - else - bun.String.create(args.path.slice()), - }; + + .EXIST => { + return Option{ .result = bun.String.empty }; }, + // continue + .NOENT => {}, } + }, + .result => { + return Option{ + .result = if (args.path == .slice_with_underlying_string) + args.path.slice_with_underlying_string.underlying + else + bun.String.create(args.path.slice()), + }; + }, + } - var working_mem = &this.sync_error_buf; - @memcpy(working_mem[0..len], path[0..len]); + var working_mem = &this.sync_error_buf; + @memcpy(working_mem[0..len], path[0..len]); - var i: u16 = len - 1; + var i: u16 = len - 1; - // iterate backwards until creating the directory works successfully - while (i > 0) : (i -= 1) { - if (path[i] == std.fs.path.sep) { - working_mem[i] = 0; - var parent: [:0]u8 = working_mem[0..i :0]; + // iterate backwards until creating the directory works successfully + while (i > 0) : (i -= 1) { + if (path[i] == std.fs.path.sep) { + working_mem[i] = 0; + var parent: [:0]u8 = working_mem[0..i :0]; - switch (Syscall.mkdir(parent, args.mode)) { - .err => |err| { - working_mem[i] = std.fs.path.sep; - switch (err.getErrno()) { - .EXIST => { - // Handle race condition - break; - }, - .NOENT => { - continue; - }, - else => return .{ .err = err.withPath(parent) }, - } - }, - .result => { - // We found a parent that worked - working_mem[i] = std.fs.path.sep; + switch (Syscall.mkdir(parent, args.mode)) { + .err => |err| { + working_mem[i] = std.fs.path.sep; + switch (err.getErrno()) { + .EXIST => { + // Handle race condition break; }, - } - } - } - var first_match: u16 = i; - i += 1; - // after we find one that works, we go forward _after_ the first working directory - while (i < len) : (i += 1) { - if (path[i] == std.fs.path.sep) { - working_mem[i] = 0; - var parent: [:0]u8 = working_mem[0..i :0]; - - switch (Syscall.mkdir(parent, args.mode)) { - .err => |err| { - working_mem[i] = std.fs.path.sep; - switch (err.getErrno()) { - .EXIST => { - if (Environment.allow_assert) std.debug.assert(false); - continue; - }, - else => return .{ .err = err }, - } - }, - - .result => { - working_mem[i] = std.fs.path.sep; + .NOENT => { + continue; }, + else => return .{ .err = err.withPath(parent) }, } - } + }, + .result => { + // We found a parent that worked + working_mem[i] = std.fs.path.sep; + break; + }, } + } + } + var first_match: u16 = i; + i += 1; + // after we find one that works, we go forward _after_ the first working directory + while (i < len) : (i += 1) { + if (path[i] == std.fs.path.sep) { + working_mem[i] = 0; + var parent: [:0]u8 = working_mem[0..i :0]; - working_mem[len] = 0; - - // Our final directory will not have a trailing separator - // so we have to create it once again - switch (Syscall.mkdir(working_mem[0..len :0], args.mode)) { + switch (Syscall.mkdir(parent, args.mode)) { .err => |err| { + working_mem[i] = std.fs.path.sep; switch (err.getErrno()) { - // handle the race condition .EXIST => { - var display_path = bun.String.empty; - if (first_match != std.math.maxInt(u16)) { - display_path = bun.String.create(working_mem[0..first_match]); - } - return Option{ .result = display_path }; - }, - - // NOENT shouldn't happen here - else => return .{ - .err = err.withPath(path), + if (Environment.allow_assert) std.debug.assert(false); + continue; }, + else => return .{ .err = err }, } }, + .result => { - return Option{ - .result = if (first_match != std.math.maxInt(u16)) - bun.String.create(working_mem[0..first_match]) - else if (args.path == .slice_with_underlying_string) - args.path.slice_with_underlying_string.underlying - else - bun.String.create(args.path.slice()), - }; + working_mem[i] = std.fs.path.sep; }, } - }, - else => {}, + } } - return Maybe(Return.Mkdir).todo; + working_mem[len] = 0; + + // Our final directory will not have a trailing separator + // so we have to create it once again + switch (Syscall.mkdir(working_mem[0..len :0], args.mode)) { + .err => |err| { + switch (err.getErrno()) { + // handle the race condition + .EXIST => { + var display_path = bun.String.empty; + if (first_match != std.math.maxInt(u16)) { + display_path = bun.String.create(working_mem[0..first_match]); + } + return Option{ .result = display_path }; + }, + + // NOENT shouldn't happen here + else => return .{ + .err = err.withPath(path), + }, + } + }, + .result => { + return Option{ + .result = if (first_match != std.math.maxInt(u16)) + bun.String.create(working_mem[0..first_match]) + else if (args.path == .slice_with_underlying_string) + args.path.slice_with_underlying_string.underlying + else + bun.String.create(args.path.slice()), + }; + }, + } } pub fn mkdtemp(this: *NodeFS, args: Arguments.MkdirTemp, comptime _: Flavor) Maybe(Return.Mkdtemp) { @@ -4136,75 +3913,54 @@ pub const NodeFS = struct { return .{ .err = Syscall.Error{ .errno = @as(Syscall.Error.Int, @truncate(@intFromEnum(errno))), .syscall = .mkdtemp } }; } pub fn open(this: *NodeFS, args: Arguments.Open, comptime flavor: Flavor) Maybe(Return.Open) { - switch (comptime flavor) { - // The sync version does no allocation except when returning the path - .sync => { - const path = args.path.sliceZ(&this.sync_error_buf); - return switch (Syscall.open(path, @intFromEnum(args.flags), args.mode)) { - .err => |err| .{ - .err = err.withPath(args.path.slice()), - }, - .result => |fd| .{ .result = fd }, - }; + _ = flavor; + const path = args.path.sliceZ(&this.sync_error_buf); + return switch (Syscall.open(path, @intFromEnum(args.flags), args.mode)) { + .err => |err| .{ + .err = err.withPath(args.path.slice()), }, - else => {}, - } - - return Maybe(Return.Open).todo; + .result => |fd| .{ .result = fd }, + }; } pub fn openDir(_: *NodeFS, _: Arguments.OpenDir, comptime _: Flavor) Maybe(Return.OpenDir) { return Maybe(Return.OpenDir).todo; } fn _read(_: *NodeFS, args: Arguments.Read, comptime flavor: Flavor) Maybe(Return.Read) { + _ = flavor; if (Environment.allow_assert) std.debug.assert(args.position == null); + var buf = args.buffer.slice(); + buf = buf[@min(args.offset, buf.len)..]; + buf = buf[0..@min(buf.len, args.length)]; - switch (comptime flavor) { - // The sync version does no allocation except when returning the path - .sync => { - var buf = args.buffer.slice(); - buf = buf[@min(args.offset, buf.len)..]; - buf = buf[0..@min(buf.len, args.length)]; - - return switch (Syscall.read(args.fd, buf)) { - .err => |err| .{ - .err = err, - }, - .result => |amt| .{ - .result = .{ - .bytes_read = @as(u52, @truncate(amt)), - }, - }, - }; + return switch (Syscall.read(args.fd, buf)) { + .err => |err| .{ + .err = err, }, - else => {}, - } - - return Maybe(Return.Read).todo; + .result => |amt| .{ + .result = .{ + .bytes_read = @as(u52, @truncate(amt)), + }, + }, + }; } fn _pread(_: *NodeFS, args: Arguments.Read, comptime flavor: Flavor) Maybe(Return.Read) { - switch (comptime flavor) { - .sync => { - var buf = args.buffer.slice(); - buf = buf[@min(args.offset, buf.len)..]; - buf = buf[0..@min(buf.len, args.length)]; - - return switch (Syscall.pread(args.fd, buf, args.position.?)) { - .err => |err| .{ - .err = err, - }, - .result => |amt| .{ - .result = .{ - .bytes_read = @as(u52, @truncate(amt)), - }, - }, - }; - }, - else => {}, - } + _ = flavor; + var buf = args.buffer.slice(); + buf = buf[@min(args.offset, buf.len)..]; + buf = buf[0..@min(buf.len, args.length)]; - return Maybe(Return.Read).todo; + return switch (Syscall.pread(args.fd, buf, args.position.?)) { + .err => |err| .{ + .err = err, + }, + .result => |amt| .{ + .result = .{ + .bytes_read = @as(u52, @truncate(amt)), + }, + }, + }; } pub fn read(this: *NodeFS, args: Arguments.Read, comptime flavor: Flavor) Maybe(Return.Read) { @@ -4236,127 +3992,91 @@ pub const NodeFS = struct { return if (args.position != null) _pwrite(this, args, flavor) else _write(this, args, flavor); } fn _write(_: *NodeFS, args: Arguments.Write, comptime flavor: Flavor) Maybe(Return.Write) { - switch (comptime flavor) { - .sync => { - var buf = args.buffer.slice(); - buf = buf[@min(args.offset, buf.len)..]; - buf = buf[0..@min(buf.len, args.length)]; - - return switch (Syscall.write(args.fd, buf)) { - .err => |err| .{ - .err = err, - }, - .result => |amt| .{ - .result = .{ - .bytes_written = @as(u52, @truncate(amt)), - }, - }, - }; - }, - else => {}, - } + _ = flavor; + + var buf = args.buffer.slice(); + buf = buf[@min(args.offset, buf.len)..]; + buf = buf[0..@min(buf.len, args.length)]; - return Maybe(Return.Write).todo; + return switch (Syscall.write(args.fd, buf)) { + .err => |err| .{ + .err = err, + }, + .result => |amt| .{ + .result = .{ + .bytes_written = @as(u52, @truncate(amt)), + }, + }, + }; } fn _pwrite(_: *NodeFS, args: Arguments.Write, comptime flavor: Flavor) Maybe(Return.Write) { + _ = flavor; const position = args.position.?; - switch (comptime flavor) { - .sync => { - var buf = args.buffer.slice(); - buf = buf[@min(args.offset, buf.len)..]; - buf = buf[0..@min(args.length, buf.len)]; + var buf = args.buffer.slice(); + buf = buf[@min(args.offset, buf.len)..]; + buf = buf[0..@min(args.length, buf.len)]; - return switch (Syscall.pwrite(args.fd, buf, position)) { - .err => |err| .{ - .err = err, - }, - .result => |amt| .{ .result = .{ - .bytes_written = @as(u52, @truncate(amt)), - } }, - }; + return switch (Syscall.pwrite(args.fd, buf, position)) { + .err => |err| .{ + .err = err, }, - else => {}, - } - - return Maybe(Return.Write).todo; + .result => |amt| .{ .result = .{ + .bytes_written = @as(u52, @truncate(amt)), + } }, + }; } fn _preadv(_: *NodeFS, args: Arguments.Readv, comptime flavor: Flavor) Maybe(Return.Readv) { + _ = flavor; const position = args.position.?; - switch (comptime flavor) { - .sync => { - return switch (Syscall.preadv(args.fd, args.buffers.buffers.items, position)) { - .err => |err| .{ - .err = err, - }, - .result => |amt| .{ .result = .{ - .bytes_read = @as(u52, @truncate(amt)), - } }, - }; + return switch (Syscall.preadv(args.fd, args.buffers.buffers.items, position)) { + .err => |err| .{ + .err = err, }, - else => {}, - } - - return Maybe(Return.Write).todo; + .result => |amt| .{ .result = .{ + .bytes_read = @as(u52, @truncate(amt)), + } }, + }; } fn _readv(_: *NodeFS, args: Arguments.Readv, comptime flavor: Flavor) Maybe(Return.Readv) { - switch (comptime flavor) { - .sync => { - return switch (Syscall.readv(args.fd, args.buffers.buffers.items)) { - .err => |err| .{ - .err = err, - }, - .result => |amt| .{ .result = .{ - .bytes_read = @as(u52, @truncate(amt)), - } }, - }; + _ = flavor; + return switch (Syscall.readv(args.fd, args.buffers.buffers.items)) { + .err => |err| .{ + .err = err, }, - else => {}, - } - - return Maybe(Return.Write).todo; + .result => |amt| .{ .result = .{ + .bytes_read = @as(u52, @truncate(amt)), + } }, + }; } fn _pwritev(_: *NodeFS, args: Arguments.Writev, comptime flavor: Flavor) Maybe(Return.Write) { + _ = flavor; const position = args.position.?; - - switch (comptime flavor) { - .sync => { - return switch (Syscall.pwritev(args.fd, args.buffers.buffers.items, position)) { - .err => |err| .{ - .err = err, - }, - .result => |amt| .{ .result = .{ - .bytes_written = @as(u52, @truncate(amt)), - } }, - }; + return switch (Syscall.pwritev(args.fd, args.buffers.buffers.items, position)) { + .err => |err| .{ + .err = err, }, - else => {}, - } - - return Maybe(Return.Write).todo; + .result => |amt| .{ .result = .{ + .bytes_written = @as(u52, @truncate(amt)), + } }, + }; } fn _writev(_: *NodeFS, args: Arguments.Writev, comptime flavor: Flavor) Maybe(Return.Write) { - switch (comptime flavor) { - .sync => { - return switch (Syscall.writev(args.fd, args.buffers.buffers.items)) { - .err => |err| .{ - .err = err, - }, - .result => |amt| .{ .result = .{ - .bytes_written = @as(u52, @truncate(amt)), - } }, - }; + _ = flavor; + return switch (Syscall.writev(args.fd, args.buffers.buffers.items)) { + .err => |err| .{ + .err = err, }, - else => {}, - } - - return Maybe(Return.Write).todo; + .result => |amt| .{ .result = .{ + .bytes_written = @as(u52, @truncate(amt)), + } }, + }; } pub fn readdir(this: *NodeFS, args: Arguments.Readdir, comptime flavor: Flavor) Maybe(Return.Readdir) { @@ -4751,50 +4471,39 @@ pub const NodeFS = struct { return Maybe(Return.WriteFile).success; } - pub fn writeFile(this: *NodeFS, args: Arguments.WriteFile, comptime flavor: Flavor) Maybe(Return.WriteFile) { - switch (comptime flavor) { - .sync => return writeFileWithPathBuffer(&this.sync_error_buf, args), - else => {}, - } - - return Maybe(Return.WriteFile).todo; + pub fn writeFile(this: *NodeFS, args: Arguments.WriteFile, comptime _: Flavor) Maybe(Return.WriteFile) { + return writeFileWithPathBuffer(&this.sync_error_buf, args); } - pub fn readlink(this: *NodeFS, args: Arguments.Readlink, comptime flavor: Flavor) Maybe(Return.Readlink) { + pub fn readlink(this: *NodeFS, args: Arguments.Readlink, comptime _: Flavor) Maybe(Return.Readlink) { var outbuf: [bun.MAX_PATH_BYTES]u8 = undefined; var inbuf = &this.sync_error_buf; - switch (comptime flavor) { - .sync => { - const path = args.path.sliceZ(inbuf); - const len = switch (Syscall.readlink(path, &outbuf)) { - .err => |err| return .{ - .err = err.withPath(args.path.slice()), - }, - .result => |buf_| buf_, - }; + const path = args.path.sliceZ(inbuf); - return .{ - .result = switch (args.encoding) { - .buffer => .{ - .buffer = Buffer.fromString(outbuf[0..len], bun.default_allocator) catch unreachable, - }, - else => if (args.path == .slice_with_underlying_string and - strings.eqlLong(args.path.slice_with_underlying_string.slice(), outbuf[0..len], true)) - .{ - .BunString = args.path.slice_with_underlying_string.underlying.dupeRef(), - } - else - .{ - .BunString = bun.String.create(outbuf[0..len]), - }, - }, - }; + const len = switch (Syscall.readlink(path, &outbuf)) { + .err => |err| return .{ + .err = err.withPath(args.path.slice()), }, - else => {}, - } + .result => |buf_| buf_, + }; - return Maybe(Return.Readlink).todo; + return .{ + .result = switch (args.encoding) { + .buffer => .{ + .buffer = Buffer.fromString(outbuf[0..len], bun.default_allocator) catch unreachable, + }, + else => if (args.path == .slice_with_underlying_string and + strings.eqlLong(args.path.slice_with_underlying_string.slice(), outbuf[0..len], true)) + .{ + .BunString = args.path.slice_with_underlying_string.underlying.dupeRef(), + } + else + .{ + .BunString = bun.String.create(outbuf[0..len]), + }, + }, + }; } pub fn realpath(this: *NodeFS, args: Arguments.Realpath, comptime _: Flavor) Maybe(Return.Realpath) { var outbuf: [bun.MAX_PATH_BYTES]u8 = undefined; @@ -4857,325 +4566,309 @@ pub const NodeFS = struct { // return error.NotImplementedYet; // } pub fn rename(this: *NodeFS, args: Arguments.Rename, comptime flavor: Flavor) Maybe(Return.Rename) { + _ = flavor; var from_buf = &this.sync_error_buf; var to_buf: [bun.MAX_PATH_BYTES]u8 = undefined; - switch (comptime flavor) { - .sync => { - var from = args.old_path.sliceZ(from_buf); - var to = args.new_path.sliceZ(&to_buf); - return Syscall.rename(from, to); - }, - else => {}, - } - - return Maybe(Return.Rename).todo; + var from = args.old_path.sliceZ(from_buf); + var to = args.new_path.sliceZ(&to_buf); + return Syscall.rename(from, to); } pub fn rmdir(this: *NodeFS, args: Arguments.RmDir, comptime flavor: Flavor) Maybe(Return.Rmdir) { - switch (comptime flavor) { - .sync => { - if (comptime Environment.isMac) { - if (args.recursive) { - var dest = args.path.sliceZ(&this.sync_error_buf); - - var flags: u32 = bun.C.darwin.RemoveFileFlags.cross_mount | - bun.C.darwin.RemoveFileFlags.allow_long_paths | - bun.C.darwin.RemoveFileFlags.recursive; - - while (true) { - if (Maybe(Return.Rmdir).errnoSys(bun.C.darwin.removefileat(std.os.AT.FDCWD, dest, null, flags), .rmdir)) |errno| { - switch (@as(os.E, @enumFromInt(errno.err.errno))) { + _ = flavor; + + if (comptime Environment.isMac) { + if (args.recursive) { + var dest = args.path.sliceZ(&this.sync_error_buf); + + var flags: u32 = bun.C.darwin.RemoveFileFlags.cross_mount | + bun.C.darwin.RemoveFileFlags.allow_long_paths | + bun.C.darwin.RemoveFileFlags.recursive; + + while (true) { + if (Maybe(Return.Rmdir).errnoSys(bun.C.darwin.removefileat(std.os.AT.FDCWD, dest, null, flags), .rmdir)) |errno| { + switch (@as(os.E, @enumFromInt(errno.err.errno))) { + .AGAIN, .INTR => continue, + .NOENT => return Maybe(Return.Rmdir).success, + .MLINK => { + var copy: [bun.MAX_PATH_BYTES]u8 = undefined; + @memcpy(copy[0..dest.len], dest); + copy[dest.len] = 0; + var dest_copy = copy[0..dest.len :0]; + switch (Syscall.unlink(dest_copy).getErrno()) { .AGAIN, .INTR => continue, - .NOENT => return Maybe(Return.Rmdir).success, - .MLINK => { - var copy: [bun.MAX_PATH_BYTES]u8 = undefined; - @memcpy(copy[0..dest.len], dest); - copy[dest.len] = 0; - var dest_copy = copy[0..dest.len :0]; - switch (Syscall.unlink(dest_copy).getErrno()) { - .AGAIN, .INTR => continue, - .NOENT => return errno, - .SUCCESS => continue, - else => return errno, - } - }, - .SUCCESS => unreachable, + .NOENT => return errno, + .SUCCESS => continue, else => return errno, } - } - - return Maybe(Return.Rmdir).success; + }, + .SUCCESS => unreachable, + else => return errno, } } - return Maybe(Return.Rmdir).errnoSysP(system.rmdir(args.path.sliceZ(&this.sync_error_buf)), .rmdir, args.path.slice()) orelse - Maybe(Return.Rmdir).success; - } else if (comptime Environment.isLinux) { - if (args.recursive) { - std.fs.cwd().deleteTree(args.path.slice()) catch |err| { - const errno: std.os.E = switch (err) { - error.InvalidHandle => .BADF, - error.AccessDenied => .PERM, - error.FileTooBig => .FBIG, - error.SymLinkLoop => .LOOP, - error.ProcessFdQuotaExceeded => .NFILE, - error.NameTooLong => .NAMETOOLONG, - error.SystemFdQuotaExceeded => .MFILE, - error.SystemResources => .NOMEM, - error.ReadOnlyFileSystem => .ROFS, - error.FileSystem => .IO, - error.FileBusy => .BUSY, - error.DeviceBusy => .BUSY, - - // One of the path components was not a directory. - // This error is unreachable if `sub_path` does not contain a path separator. - error.NotDir => .NOTDIR, - // On Windows, file paths must be valid Unicode. - error.InvalidUtf8 => .INVAL, - - // On Windows, file paths cannot contain these characters: - // '/', '*', '?', '"', '<', '>', '|' - error.BadPathName => .INVAL, - - else => .FAULT, - }; - return Maybe(Return.Rm){ - .err = bun.sys.Error.fromCode(errno, .rmdir), - }; - }; + return Maybe(Return.Rmdir).success; + } + } - return Maybe(Return.Rmdir).success; - } + return Maybe(Return.Rmdir).errnoSysP(system.rmdir(args.path.sliceZ(&this.sync_error_buf)), .rmdir, args.path.slice()) orelse + Maybe(Return.Rmdir).success; + } else if (comptime Environment.isLinux) { + if (args.recursive) { + std.fs.cwd().deleteTree(args.path.slice()) catch |err| { + const errno: std.os.E = switch (err) { + error.InvalidHandle => .BADF, + error.AccessDenied => .PERM, + error.FileTooBig => .FBIG, + error.SymLinkLoop => .LOOP, + error.ProcessFdQuotaExceeded => .NFILE, + error.NameTooLong => .NAMETOOLONG, + error.SystemFdQuotaExceeded => .MFILE, + error.SystemResources => .NOMEM, + error.ReadOnlyFileSystem => .ROFS, + error.FileSystem => .IO, + error.FileBusy => .BUSY, + error.DeviceBusy => .BUSY, + + // One of the path components was not a directory. + // This error is unreachable if `sub_path` does not contain a path separator. + error.NotDir => .NOTDIR, + // On Windows, file paths must be valid Unicode. + error.InvalidUtf8 => .INVAL, + + // On Windows, file paths cannot contain these characters: + // '/', '*', '?', '"', '<', '>', '|' + error.BadPathName => .INVAL, + + else => .FAULT, + }; + return Maybe(Return.Rm){ + .err = bun.sys.Error.fromCode(errno, .rmdir), + }; + }; - return Maybe(Return.Rmdir).errnoSysP(system.rmdir(args.path.sliceZ(&this.sync_error_buf)), .rmdir, args.path.slice()) orelse - Maybe(Return.Rmdir).success; - } - }, - else => {}, - } + return Maybe(Return.Rmdir).success; + } - return Maybe(Return.Rmdir).todo; + return Maybe(Return.Rmdir).errnoSysP(system.rmdir(args.path.sliceZ(&this.sync_error_buf)), .rmdir, args.path.slice()) orelse + Maybe(Return.Rmdir).success; + } } pub fn rm(this: *NodeFS, args: Arguments.RmDir, comptime flavor: Flavor) Maybe(Return.Rm) { - switch (comptime flavor) { - .sync => { - if (comptime Environment.isMac) { - var dest = args.path.sliceZ(&this.sync_error_buf); - - while (true) { - var flags: u32 = 0; - if (args.recursive) { - flags |= bun.C.darwin.RemoveFileFlags.cross_mount; - flags |= bun.C.darwin.RemoveFileFlags.allow_long_paths; - flags |= bun.C.darwin.RemoveFileFlags.recursive; - } + _ = flavor; + + if (comptime Environment.isMac) { + var dest = args.path.sliceZ(&this.sync_error_buf); - if (Maybe(Return.Rm).errnoSys(bun.C.darwin.removefileat(std.os.AT.FDCWD, dest, null, flags), .unlink)) |errno| { - switch (@as(os.E, @enumFromInt(errno.err.errno))) { + while (true) { + var flags: u32 = 0; + if (args.recursive) { + flags |= bun.C.darwin.RemoveFileFlags.cross_mount; + flags |= bun.C.darwin.RemoveFileFlags.allow_long_paths; + flags |= bun.C.darwin.RemoveFileFlags.recursive; + } + + if (Maybe(Return.Rm).errnoSys(bun.C.darwin.removefileat(std.os.AT.FDCWD, dest, null, flags), .unlink)) |errno| { + switch (@as(os.E, @enumFromInt(errno.err.errno))) { + .AGAIN, .INTR => continue, + .NOENT => { + if (args.force) { + return Maybe(Return.Rm).success; + } + + return errno; + }, + + .MLINK => { + var copy: [bun.MAX_PATH_BYTES]u8 = undefined; + @memcpy(copy[0..dest.len], dest); + copy[dest.len] = 0; + var dest_copy = copy[0..dest.len :0]; + switch (Syscall.unlink(dest_copy).getErrno()) { .AGAIN, .INTR => continue, .NOENT => { if (args.force) { - return Maybe(Return.Rm).success; + continue; } return errno; }, - - .MLINK => { - var copy: [bun.MAX_PATH_BYTES]u8 = undefined; - @memcpy(copy[0..dest.len], dest); - copy[dest.len] = 0; - var dest_copy = copy[0..dest.len :0]; - switch (Syscall.unlink(dest_copy).getErrno()) { - .AGAIN, .INTR => continue, - .NOENT => { - if (args.force) { - continue; - } - - return errno; - }, - .SUCCESS => continue, - else => return errno, - } - }, - .SUCCESS => unreachable, + .SUCCESS => continue, else => return errno, } - } - - return Maybe(Return.Rm).success; - } - } else if (comptime Environment.isLinux or Environment.isWindows) { - if (args.recursive) { - std.fs.cwd().deleteTree(args.path.slice()) catch |err| { - const errno: E = switch (err) { - error.InvalidHandle => .BADF, - error.AccessDenied => .PERM, - error.FileTooBig => .FBIG, - error.SymLinkLoop => .LOOP, - error.ProcessFdQuotaExceeded => .NFILE, - error.NameTooLong => .NAMETOOLONG, - error.SystemFdQuotaExceeded => .MFILE, - error.SystemResources => .NOMEM, - error.ReadOnlyFileSystem => .ROFS, - error.FileSystem => .IO, - error.FileBusy => .BUSY, - error.DeviceBusy => .BUSY, - - // One of the path components was not a directory. - // This error is unreachable if `sub_path` does not contain a path separator. - error.NotDir => .NOTDIR, - // On Windows, file paths must be valid Unicode. - error.InvalidUtf8 => .INVAL, - - // On Windows, file paths cannot contain these characters: - // '/', '*', '?', '"', '<', '>', '|' - error.BadPathName => .INVAL, - - else => .FAULT, - }; - if (args.force) { - return Maybe(Return.Rm).success; - } - return Maybe(Return.Rm){ - .err = bun.sys.Error.fromCode(errno, .unlink), - }; - }; - return Maybe(Return.Rm).success; + }, + .SUCCESS => unreachable, + else => return errno, } } - if (comptime Environment.isPosix) { - var dest = args.path.osPath(&this.sync_error_buf); - std.os.unlinkZ(dest) catch |er| { - // empircally, it seems to return AccessDenied when the - // file is actually a directory on macOS. - if (args.recursive and - (er == error.IsDir or er == error.NotDir or er == error.AccessDenied)) - { - std.os.rmdirZ(dest) catch |err| { - if (args.force) { - return Maybe(Return.Rm).success; - } - - const code: E = switch (err) { - error.AccessDenied => .PERM, - error.SymLinkLoop => .LOOP, - error.NameTooLong => .NAMETOOLONG, - error.SystemResources => .NOMEM, - error.ReadOnlyFileSystem => .ROFS, - error.FileBusy => .BUSY, - error.FileNotFound => .NOENT, - error.InvalidUtf8 => .INVAL, - error.BadPathName => .INVAL, - else => .FAULT, - }; - - return .{ - .err = bun.sys.Error.fromCode( - code, - .rmdir, - ), - }; - }; - - return Maybe(Return.Rm).success; - } + return Maybe(Return.Rm).success; + } + } else if (comptime Environment.isLinux or Environment.isWindows) { + if (args.recursive) { + std.fs.cwd().deleteTree(args.path.slice()) catch |err| { + const errno: E = switch (err) { + error.InvalidHandle => .BADF, + error.AccessDenied => .PERM, + error.FileTooBig => .FBIG, + error.SymLinkLoop => .LOOP, + error.ProcessFdQuotaExceeded => .NFILE, + error.NameTooLong => .NAMETOOLONG, + error.SystemFdQuotaExceeded => .MFILE, + error.SystemResources => .NOMEM, + error.ReadOnlyFileSystem => .ROFS, + error.FileSystem => .IO, + error.FileBusy => .BUSY, + error.DeviceBusy => .BUSY, + + // One of the path components was not a directory. + // This error is unreachable if `sub_path` does not contain a path separator. + error.NotDir => .NOTDIR, + // On Windows, file paths must be valid Unicode. + error.InvalidUtf8 => .INVAL, + + // On Windows, file paths cannot contain these characters: + // '/', '*', '?', '"', '<', '>', '|' + error.BadPathName => .INVAL, + + else => .FAULT, + }; + if (args.force) { + return Maybe(Return.Rm).success; + } + return Maybe(Return.Rm){ + .err = bun.sys.Error.fromCode(errno, .unlink), + }; + }; + return Maybe(Return.Rm).success; + } + } + if (comptime Environment.isPosix) { + var dest = args.path.osPath(&this.sync_error_buf); + std.os.unlinkZ(dest) catch |er| { + // empircally, it seems to return AccessDenied when the + // file is actually a directory on macOS. + if (args.recursive and + (er == error.IsDir or er == error.NotDir or er == error.AccessDenied)) + { + std.os.rmdirZ(dest) catch |err| { if (args.force) { return Maybe(Return.Rm).success; } - { - const code: E = switch (er) { - error.AccessDenied => .PERM, - error.SymLinkLoop => .LOOP, - error.NameTooLong => .NAMETOOLONG, - error.SystemResources => .NOMEM, - error.ReadOnlyFileSystem => .ROFS, - error.FileBusy => .BUSY, - error.InvalidUtf8 => .INVAL, - error.BadPathName => .INVAL, - error.FileNotFound => .NOENT, - else => .FAULT, - }; + const code: E = switch (err) { + error.AccessDenied => .PERM, + error.SymLinkLoop => .LOOP, + error.NameTooLong => .NAMETOOLONG, + error.SystemResources => .NOMEM, + error.ReadOnlyFileSystem => .ROFS, + error.FileBusy => .BUSY, + error.FileNotFound => .NOENT, + error.InvalidUtf8 => .INVAL, + error.BadPathName => .INVAL, + else => .FAULT, + }; - return .{ - .err = bun.sys.Error.fromCode( - code, - .unlink, - ), - }; - } + return .{ + .err = bun.sys.Error.fromCode( + code, + .rmdir, + ), + }; }; return Maybe(Return.Rm).success; } - if (comptime Environment.isWindows) { - var dest = args.path.osPath(&this.sync_error_buf); - std.os.windows.DeleteFile(dest, .{ - .dir = null, - .remove_dir = brk: { - const file_attrs = std.os.windows.GetFileAttributesW(dest.ptr) catch |err| { - if (args.force) { - return Maybe(Return.Rm).success; - } + if (args.force) { + return Maybe(Return.Rm).success; + } - const code: E = switch (err) { - error.FileNotFound => .NOENT, - error.PermissionDenied => .PERM, - else => .INVAL, - }; + { + const code: E = switch (er) { + error.AccessDenied => .PERM, + error.SymLinkLoop => .LOOP, + error.NameTooLong => .NAMETOOLONG, + error.SystemResources => .NOMEM, + error.ReadOnlyFileSystem => .ROFS, + error.FileBusy => .BUSY, + error.InvalidUtf8 => .INVAL, + error.BadPathName => .INVAL, + error.FileNotFound => .NOENT, + else => .FAULT, + }; - return .{ - .err = bun.sys.Error.fromCode( - code, - .unlink, - ), - }; - }; - // TODO: check FILE_ATTRIBUTE_INVALID - break :brk (file_attrs & std.os.windows.FILE_ATTRIBUTE_DIRECTORY) != 0; - }, - }) catch |er| { - // empircally, it seems to return AccessDenied when the - // file is actually a directory on macOS. + return .{ + .err = bun.sys.Error.fromCode( + code, + .unlink, + ), + }; + } + }; + + return Maybe(Return.Rm).success; + } + if (comptime Environment.isWindows) { + var dest = args.path.osPath(&this.sync_error_buf); + std.os.windows.DeleteFile(dest, .{ + .dir = null, + .remove_dir = brk: { + const file_attrs = std.os.windows.GetFileAttributesW(dest.ptr) catch |err| { if (args.force) { return Maybe(Return.Rm).success; } - { - const code: E = switch (er) { - error.FileNotFound => .NOENT, - error.AccessDenied => .PERM, - error.NameTooLong => .INVAL, - error.FileBusy => .BUSY, - error.NotDir => .NOTDIR, - error.IsDir => .ISDIR, - error.DirNotEmpty => .INVAL, - error.NetworkNotFound => .NOENT, - else => .UNKNOWN, - }; + const code: E = switch (err) { + error.FileNotFound => .NOENT, + error.PermissionDenied => .PERM, + else => .INVAL, + }; - return .{ - .err = bun.sys.Error.fromCode( - code, - .unlink, - ), - }; - } + return .{ + .err = bun.sys.Error.fromCode( + code, + .unlink, + ), + }; }; + // TODO: check FILE_ATTRIBUTE_INVALID + break :brk (file_attrs & std.os.windows.FILE_ATTRIBUTE_DIRECTORY) != 0; + }, + }) catch |er| { + // empircally, it seems to return AccessDenied when the + // file is actually a directory on macOS. + if (args.force) { return Maybe(Return.Rm).success; } - }, - else => {}, - } - return Maybe(Return.Rm).todo; + { + const code: E = switch (er) { + error.FileNotFound => .NOENT, + error.AccessDenied => .PERM, + error.NameTooLong => .INVAL, + error.FileBusy => .BUSY, + error.NotDir => .NOTDIR, + error.IsDir => .ISDIR, + error.DirNotEmpty => .INVAL, + error.NetworkNotFound => .NOENT, + else => .UNKNOWN, + }; + + return .{ + .err = bun.sys.Error.fromCode( + code, + .unlink, + ), + }; + } + }; + + return Maybe(Return.Rm).success; + } } pub fn stat(this: *NodeFS, args: Arguments.Stat, comptime flavor: Flavor) Maybe(Return.Stat) { if (comptime Environment.isWindows) { @@ -5199,38 +4892,26 @@ pub const NodeFS = struct { } pub fn symlink(this: *NodeFS, args: Arguments.Symlink, comptime flavor: Flavor) Maybe(Return.Symlink) { + _ = flavor; if (comptime Environment.isWindows) { return Maybe(Return.Symlink).todo; } var to_buf: [bun.MAX_PATH_BYTES]u8 = undefined; - switch (comptime flavor) { - .sync => { - return Syscall.symlink( - args.old_path.sliceZ(&this.sync_error_buf), - args.new_path.sliceZ(&to_buf), - ); - }, - else => {}, - } - - return Maybe(Return.Symlink).todo; + return Syscall.symlink( + args.old_path.sliceZ(&this.sync_error_buf), + args.new_path.sliceZ(&to_buf), + ); } fn _truncate(this: *NodeFS, path: PathLike, len: JSC.WebCore.Blob.SizeType, comptime flavor: Flavor) Maybe(Return.Truncate) { + _ = flavor; if (comptime Environment.isWindows) { return Maybe(Return.Truncate).todo; } - switch (comptime flavor) { - .sync => { - return Maybe(Return.Truncate).errno(C.truncate(path.sliceZ(&this.sync_error_buf), len)) orelse - Maybe(Return.Truncate).success; - }, - else => {}, - } - - return Maybe(Return.Truncate).todo; + return Maybe(Return.Truncate).errno(C.truncate(path.sliceZ(&this.sync_error_buf), len)) orelse + Maybe(Return.Truncate).success; } pub fn truncate(this: *NodeFS, args: Arguments.Truncate, comptime flavor: Flavor) Maybe(Return.Truncate) { return switch (args.path) { @@ -5246,19 +4927,13 @@ pub const NodeFS = struct { }; } pub fn unlink(this: *NodeFS, args: Arguments.Unlink, comptime flavor: Flavor) Maybe(Return.Unlink) { + _ = flavor; if (comptime Environment.isWindows) { return Maybe(Return.Unlink).todo; } - switch (comptime flavor) { - .sync => { - return Maybe(Return.Unlink).errnoSysP(system.unlink(args.path.sliceZ(&this.sync_error_buf)), .unlink, args.path.slice()) orelse - Maybe(Return.Unlink).success; - }, - else => {}, - } - - return Maybe(Return.Unlink).todo; + return Maybe(Return.Unlink).errnoSysP(system.unlink(args.path.sliceZ(&this.sync_error_buf)), .unlink, args.path.slice()) orelse + Maybe(Return.Unlink).success; } pub fn watchFile(_: *NodeFS, args: Arguments.WatchFile, comptime flavor: Flavor) Maybe(Return.WatchFile) { std.debug.assert(flavor == .sync); @@ -5283,6 +4958,7 @@ pub const NodeFS = struct { return Maybe(Return.UnwatchFile).todo; } pub fn utimes(this: *NodeFS, args: Arguments.Utimes, comptime flavor: Flavor) Maybe(Return.Utimes) { + _ = flavor; if (comptime Environment.isWindows) { return Maybe(Return.Utimes).todo; } @@ -5300,21 +4976,13 @@ pub const NodeFS = struct { }, }; - switch (comptime flavor) { - // futimes uses the syscall version - // we use libc because here, not for a good reason - // just missing from the linux syscall interface in zig and I don't want to modify that right now - .sync => return if (Maybe(Return.Utimes).errnoSysP(std.c.utimes(args.path.sliceZ(&this.sync_error_buf), ×), .utimes, args.path.slice())) |err| - err - else - Maybe(Return.Utimes).success, - else => {}, - } - - return Maybe(Return.Utimes).todo; + return if (Maybe(Return.Utimes).errnoSysP(std.c.utimes(args.path.sliceZ(&this.sync_error_buf), ×), .utimes, args.path.slice())) |err| + err + else + Maybe(Return.Utimes).success; } - pub fn lutimes(this: *NodeFS, args: Arguments.Lutimes, comptime flavor: Flavor) Maybe(Return.Lutimes) { + pub fn lutimes(this: *NodeFS, args: Arguments.Lutimes, comptime _: Flavor) Maybe(Return.Lutimes) { if (comptime Environment.isWindows) { return Maybe(Return.Lutimes).todo; } @@ -5332,18 +5000,10 @@ pub const NodeFS = struct { }, }; - switch (comptime flavor) { - // futimes uses the syscall version - // we use libc because here, not for a good reason - // just missing from the linux syscall interface in zig and I don't want to modify that right now - .sync => return if (Maybe(Return.Lutimes).errnoSysP(C.lutimes(args.path.sliceZ(&this.sync_error_buf), ×), .lutimes, args.path.slice())) |err| - err - else - Maybe(Return.Lutimes).success, - else => {}, - } - - return Maybe(Return.Lutimes).todo; + return if (Maybe(Return.Lutimes).errnoSysP(C.lutimes(args.path.sliceZ(&this.sync_error_buf), ×), .lutimes, args.path.slice())) |err| + err + else + Maybe(Return.Lutimes).success; } pub fn watch(_: *NodeFS, args: Arguments.Watch, comptime _: Flavor) Maybe(Return.Watch) { if (comptime Environment.isWindows) { diff --git a/src/bun.js/node/node_fs_binding.zig b/src/bun.js/node/node_fs_binding.zig index b3866b557..db4d79fc9 100644 --- a/src/bun.js/node/node_fs_binding.zig +++ b/src/bun.js/node/node_fs_binding.zig @@ -67,6 +67,7 @@ fn callSync(comptime FunctionEnum: NodeFSFunctionEnum) NodeFSFunction { args, comptime Flavor.sync, ); + switch (result) { .err => |err| { globalObject.throwValue(JSC.JSValue.c(err.toJS(globalObject))); @@ -108,14 +109,6 @@ fn call(comptime FunctionEnum: NodeFSFunctionEnum) NodeFSFunction { globalObject: *JSC.JSGlobalObject, callframe: *JSC.CallFrame, ) callconv(.C) JSC.JSValue { - switch (comptime FunctionEnum) { - .readdir, .lstat, .stat, .readFile, .realpath, .copyFile, .cp => {}, - else => { - globalObject.throw("Not implemented yet", .{}); - return .zero; - }, - } - var arguments = callframe.arguments(8); var slice = ArgumentsSlice.init(globalObject.bunVM(), arguments.ptr[0..arguments.len]); @@ -142,57 +135,12 @@ fn call(comptime FunctionEnum: NodeFSFunctionEnum) NodeFSFunction { // TODO: handle globalObject.throwValue - if (comptime FunctionEnum == .readdir) { - return JSC.Node.AsyncReaddirTask.create(globalObject, args, slice.vm, slice.arena); - } - - if (comptime FunctionEnum == .readFile) { - return JSC.Node.AsyncReadFileTask.create(globalObject, args, slice.vm, slice.arena); - } - - if (comptime FunctionEnum == .realpath) { - return JSC.Node.AsyncRealpathTask.create(globalObject, args, slice.vm, slice.arena); - } - - if (comptime FunctionEnum == .stat or FunctionEnum == .lstat) { - return JSC.Node.AsyncStatTask.create(globalObject, args, slice.vm, FunctionEnum == .lstat, slice.arena); - } - - if (comptime FunctionEnum == .copyFile) { - return JSC.Node.AsyncCopyFileTask.create(globalObject, args, slice.vm, slice.arena); - } - + const Task = @field(JSC.Node.Async, @tagName(FunctionEnum)); if (comptime FunctionEnum == .cp) { - return JSC.Node.AsyncCpTask.create(globalObject, args, slice.vm, slice.arena); + return Task.create(globalObject, args, globalObject.bunVM(), slice.arena); + } else { + return Task.create(globalObject, args, globalObject.bunVM()); } - - // defer { - // for (arguments.len) |arg| { - // JSC.C.JSValueUnprotect(ctx, arg); - // } - // slice.arena.deinit(); - // } - - // const args = if (comptime Arguments != void) - // Arguments.fromJS(ctx, &slice, exception) - // else - // Arguments{}; - // if (exception.* != null) return null; - - // const result: Maybe(Result) = Function(this, comptime Flavor.sync, args); - // switch (result) { - // .err => |err| { - // exception.* = err.toJS(ctx); - // return null; - // }, - // .result => |res| { - // return switch (comptime Result) { - // void => JSC.JSValue.jsUndefined().asRef(), - // else => res.toJS(ctx), - // }; - // }, - // } - // unreachable; } }; return NodeBindingClosure.bind; diff --git a/src/bun.js/node/types.zig b/src/bun.js/node/types.zig index 35daea52c..84dc394d0 100644 --- a/src/bun.js/node/types.zig +++ b/src/bun.js/node/types.zig @@ -315,6 +315,68 @@ pub const StringOrBunStringOrBuffer = union(enum) { } }; +pub const SliceWithUnderlyingStringOrBuffer = union(enum) { + SliceWithUnderlyingString: bun.SliceWithUnderlyingString, + buffer: Buffer, + + pub fn toThreadSafe(this: *@This()) void { + switch (this.*) { + .SliceWithUnderlyingString => this.SliceWithUnderlyingString.toThreadSafe(), + else => {}, + } + } + + pub fn toJS(this: *SliceWithUnderlyingStringOrBuffer, ctx: JSC.C.JSContextRef, exception: JSC.C.ExceptionRef) JSC.C.JSValueRef { + return switch (this) { + .SliceWithUnderlyingStringOrBuffer => { + defer { + this.SliceWithUnderlyingString.deinit(); + this.SliceWithUnderlyingString.underlying = bun.String.empty; + this.SliceWithUnderlyingString.utf8 = .{}; + } + + return this.SliceWithUnderlyingString.underlying.toJS(ctx); + }, + .buffer => this.buffer.toJSObjectRef(ctx, exception), + }; + } + + pub fn slice(this: *const SliceWithUnderlyingStringOrBuffer) []const u8 { + return switch (this.*) { + .SliceWithUnderlyingString => this.SliceWithUnderlyingString.slice(), + .buffer => this.buffer.slice(), + }; + } + + pub fn fromJS(global: *JSC.JSGlobalObject, allocator: std.mem.Allocator, value: JSC.JSValue, exception: JSC.C.ExceptionRef) ?SliceWithUnderlyingStringOrBuffer { + _ = exception; + return switch (value.jsType()) { + JSC.JSValue.JSType.String, JSC.JSValue.JSType.StringObject, JSC.JSValue.JSType.DerivedStringObject, JSC.JSValue.JSType.Object => { + var str = bun.String.tryFromJS(value, global) orelse return null; + return SliceWithUnderlyingStringOrBuffer{ .SliceWithUnderlyingString = str.toSlice(allocator) }; + }, + + .ArrayBuffer, + .Int8Array, + .Uint8Array, + .Uint8ClampedArray, + .Int16Array, + .Uint16Array, + .Int32Array, + .Uint32Array, + .Float32Array, + .Float64Array, + .BigInt64Array, + .BigUint64Array, + .DataView, + => SliceWithUnderlyingStringOrBuffer{ + .buffer = Buffer.fromArrayBuffer(global, value), + }, + else => null, + }; + } +}; + /// Like StringOrBuffer but actually returns a Node.js Buffer pub const StringOrNodeBuffer = union(Tag) { string: string, @@ -401,6 +463,20 @@ pub const SliceOrBuffer = union(Tag) { } } + pub fn toThreadSafe(this: *SliceOrBuffer) void { + var buffer: ?Buffer = null; + if (this.* == .buffer) { + buffer = this.buffer; + this.buffer.buffer.value.ensureStillAlive(); + } + defer { + if (buffer) |buf| { + buf.buffer.value.unprotect(); + } + } + this.ensureCloned(bun.default_allocator) catch unreachable; + } + pub const Tag = enum { string, buffer }; pub fn slice(this: SliceOrBuffer) []const u8 { @@ -650,6 +726,10 @@ pub const PathLike = union(Tag) { if (this.* == .slice_with_underlying_string) { this.slice_with_underlying_string.toThreadSafe(); } + + if (this.* == .buffer) { + this.buffer.buffer.value.protect(); + } } pub fn deinitAndUnprotect(this: *const PathLike) void { diff --git a/src/js/node/fs.js b/src/js/node/fs.js index b4165311f..8340c7375 100644 --- a/src/js/node/fs.js +++ b/src/js/node/fs.js @@ -109,19 +109,19 @@ class StatWatcher extends EventEmitter { } var access = function access(...args) { - callbackify(fs.accessSync, args); + callbackify(fs.access, args); }, appendFile = function appendFile(...args) { - callbackify(fs.appendFileSync, args); + callbackify(fs.appendFile, args); }, close = function close(...args) { - callbackify(fs.closeSync, args); + callbackify(fs.close, args); }, rm = function rm(...args) { - callbackify(fs.rmSync, args); + callbackify(fs.rm, args); }, rmdir = function rmdir(...args) { - callbackify(fs.rmdirSync, args); + callbackify(fs.rmdir, args); }, copyFile = function copyFile(...args) { const callback = args[args.length - 1]; @@ -133,49 +133,49 @@ var access = function access(...args) { fs.copyFile(...args).then(result => callback(null, result), callback); }, exists = function exists(...args) { - callbackify(fs.existsSync, args); + callbackify(fs.exists, args); }, chown = function chown(...args) { - callbackify(fs.chownSync, args); + callbackify(fs.chown, args); }, chmod = function chmod(...args) { - callbackify(fs.chmodSync, args); + callbackify(fs.chmod, args); }, fchmod = function fchmod(...args) { - callbackify(fs.fchmodSync, args); + callbackify(fs.fchmod, args); }, fchown = function fchown(...args) { - callbackify(fs.fchownSync, args); + callbackify(fs.fchown, args); }, fstat = function fstat(...args) { - callbackify(fs.fstatSync, args); + callbackify(fs.fstat, args); }, fsync = function fsync(...args) { - callbackify(fs.fsyncSync, args); + callbackify(fs.fsync, args); }, ftruncate = function ftruncate(...args) { - callbackify(fs.ftruncateSync, args); + callbackify(fs.ftruncate, args); }, futimes = function futimes(...args) { - callbackify(fs.futimesSync, args); + callbackify(fs.futimes, args); }, lchmod = function lchmod(...args) { - callbackify(fs.lchmodSync, args); + callbackify(fs.lchmod, args); }, lchown = function lchown(...args) { - callbackify(fs.lchownSync, args); + callbackify(fs.lchown, args); }, link = function link(...args) { - callbackify(fs.linkSync, args); + callbackify(fs.link, args); }, mkdir = function mkdir(...args) { - callbackify(fs.mkdirSync, args); + callbackify(fs.mkdir, args); }, mkdtemp = function mkdtemp(...args) { - callbackify(fs.mkdtempSync, args); + callbackify(fs.mkdtemp, args); }, open = function open(...args) { - callbackify(fs.openSync, args); + callbackify(fs.open, args); }, read = function read(fd, buffer, offsetOrOptions, length, position, callback) { let offset = offsetOrOptions; @@ -210,7 +210,7 @@ var access = function access(...args) { }); }, write = function write(...args) { - callbackify(fs.writeSync, args); + callbackify(fs.write, args); }, readdir = function readdir(...args) { const callback = args[args.length - 1]; @@ -231,10 +231,10 @@ var access = function access(...args) { fs.readFile(...args).then(result => callback(null, result), callback); }, writeFile = function writeFile(...args) { - callbackify(fs.writeFileSync, args); + callbackify(fs.writeFile, args); }, readlink = function readlink(...args) { - callbackify(fs.readlinkSync, args); + callbackify(fs.readlink, args); }, realpath = function realpath(...args) { const callback = args[args.length - 1]; @@ -246,7 +246,7 @@ var access = function access(...args) { fs.realpath(...args).then(result => callback(null, result), callback); }, rename = function rename(...args) { - callbackify(fs.renameSync, args); + callbackify(fs.rename, args); }, lstat = function lstat(...args) { const callback = args[args.length - 1]; @@ -267,19 +267,19 @@ var access = function access(...args) { fs.stat(...args).then(result => callback(null, result), callback); }, symlink = function symlink(...args) { - callbackify(fs.symlinkSync, args); + callbackify(fs.symlink, args); }, truncate = function truncate(...args) { - callbackify(fs.truncateSync, args); + callbackify(fs.truncate, args); }, unlink = function unlink(...args) { - callbackify(fs.unlinkSync, args); + callbackify(fs.unlink, args); }, utimes = function utimes(...args) { - callbackify(fs.utimesSync, args); + callbackify(fs.utimes, args); }, lutimes = function lutimes(...args) { - callbackify(fs.lutimesSync, args); + callbackify(fs.lutimes, args); }, accessSync = fs.accessSync.bind(fs), appendFileSync = fs.appendFileSync.bind(fs), @@ -406,16 +406,18 @@ function unwatchFile(filename, listener) { } function callbackify(fsFunction, args) { + const callback = args[args.length - 1]; try { - const result = fsFunction.apply(fs, args.slice(0, args.length - 1)); - const callback = args[args.length - 1]; - if (typeof callback === "function") { - queueMicrotask(() => callback(null, result)); - } + var result = fsFunction.apply(fs, args.slice(0, args.length - 1)); + result.then( + (...args) => callback(null, ...args), + err => callback(err), + ); } catch (e) { - const callback = args[args.length - 1]; if (typeof callback === "function") { - queueMicrotask(() => callback(e)); + callback(e); + } else { + throw e; } } } diff --git a/src/js/node/fs.promises.ts b/src/js/node/fs.promises.ts index 8921e42d3..91566d155 100644 --- a/src/js/node/fs.promises.ts +++ b/src/js/node/fs.promises.ts @@ -9,14 +9,6 @@ var fs = Bun.fs(); // in some cases, node swaps around arguments or makes small tweaks to the return type // this is just better than nothing. const notrace = "::bunternal::"; -var promisify = { - [notrace]: fsFunction => { - return async function (...args) { - await 1; - return fsFunction.apply(fs, args); - }; - }, -}[notrace]; function watch( filename: string | Buffer | URL, @@ -139,72 +131,57 @@ async function opendir(dir: string) { } export default { - access: promisify(fs.accessSync), - appendFile: promisify(fs.appendFileSync), - close: promisify(fs.closeSync), + access: fs.access.bind(fs), + appendFile: fs.appendFile.bind(fs), + close: fs.close.bind(fs), copyFile: fs.copyFile.bind(fs), cp, - exists: promisify(fs.existsSync), - chown: promisify(fs.chownSync), - chmod: promisify(fs.chmodSync), - fchmod: promisify(fs.fchmodSync), - fchown: promisify(fs.fchownSync), - fstat: promisify(fs.fstatSync), - fsync: promisify(fs.fsyncSync), - ftruncate: promisify(fs.ftruncateSync), - futimes: promisify(fs.futimesSync), - lchmod: promisify(fs.lchmodSync), - lchown: promisify(fs.lchownSync), - link: promisify(fs.linkSync), + exists: fs.exists.bind(fs), + chown: fs.chown.bind(fs), + chmod: fs.chmod.bind(fs), + fchmod: fs.fchmod.bind(fs), + fchown: fs.fchown.bind(fs), + fstat: fs.fstat.bind(fs), + fsync: fs.fsync.bind(fs), + ftruncate: fs.ftruncate.bind(fs), + futimes: fs.futimes.bind(fs), + lchmod: fs.lchmod.bind(fs), + lchown: fs.lchown.bind(fs), + link: fs.link.bind(fs), lstat: fs.lstat.bind(fs), - mkdir: promisify(fs.mkdirSync), - mkdtemp: promisify(fs.mkdtempSync), - open: promisify(fs.openSync), - read: promisify(fs.readSync), - write: promisify(fs.writeSync), + mkdir: fs.mkdir.bind(fs), + mkdtemp: fs.mkdtemp.bind(fs), + open: fs.open.bind(fs), + read: fs.read.bind(fs), + write: fs.write.bind(fs), readdir: fs.readdir.bind(fs), readFile: fs.readFile.bind(fs), - writeFile: promisify(fs.writeFileSync), - readlink: promisify(fs.readlinkSync), + writeFile: fs.writeFile.bind(fs), + readlink: fs.readlink.bind(fs), realpath: fs.realpath.bind(fs), - rename: promisify(fs.renameSync), + rename: fs.rename.bind(fs), stat: fs.stat.bind(fs), - symlink: promisify(fs.symlinkSync), - truncate: promisify(fs.truncateSync), - unlink: promisify(fs.unlinkSync), - utimes: promisify(fs.utimesSync), - lutimes: promisify(fs.lutimesSync), - rm: promisify(fs.rmSync), - rmdir: promisify(fs.rmdirSync), - writev: (fd, buffers, position) => { - return new Promise((resolve, reject) => { - try { - var bytesWritten = fs.writevSync(fd, buffers, position); - } catch (err) { - reject(err); - return; - } - - resolve({ - bytesWritten, - buffers, - }); - }); + symlink: fs.symlink.bind(fs), + truncate: fs.truncate.bind(fs), + unlink: fs.unlink.bind(fs), + utimes: fs.utimes.bind(fs), + lutimes: fs.lutimes.bind(fs), + rm: fs.rm.bind(fs), + rmdir: fs.rmdir.bind(fs), + writev: async (fd, buffers, position) => { + var bytesWritten = await fs.writev(fd, buffers, position); + return { + bytesWritten, + buffers, + }; }, - readv: (fd, buffers, position) => { - return new Promise((resolve, reject) => { - try { - var bytesRead = fs.readvSync(fd, buffers, position); - } catch (err) { - reject(err); - return; - } + readv: async (fd, buffers, position) => { + var bytesRead = await fs.readv(fd, buffers, position); - resolve({ - bytesRead, - buffers, - }); - }); + return { + bytesRead, + buffers, + }; }, constants, watch, diff --git a/src/js/out/InternalModuleRegistryConstants.h b/src/js/out/InternalModuleRegistryConstants.h index 479b97638..9d5cfaf4d 100644 --- a/src/js/out/InternalModuleRegistryConstants.h +++ b/src/js/out/InternalModuleRegistryConstants.h @@ -82,11 +82,11 @@ static constexpr ASCIILiteral NodeEventsCode = "(function (){\"use strict\";// s // // -static constexpr ASCIILiteral NodeFSCode = "(function (){\"use strict\";// src/js/out/tmp/node/fs.ts\nvar getValidatedPath = function(p) {\n if (p instanceof URL)\n return Bun.fileURLToPath(p);\n if (typeof p !== \"string\")\n @throwTypeError(\"Path must be a string or URL.\");\n return (_pathModule \?\?= @getInternalField(@internalModuleRegistry, 28) || @createInternalModuleById(28)).resolve(p);\n}, watchFile = function(filename, options, listener) {\n if (filename = getValidatedPath(filename), typeof options === \"function\")\n listener = options, options = {};\n if (typeof listener !== \"function\")\n @throwTypeError(\"listener must be a function\");\n var stat = statWatchers.get(filename);\n if (!stat)\n stat = new StatWatcher(filename, options), statWatchers.set(filename, stat);\n return stat.addListener(\"change\", listener), stat;\n}, unwatchFile = function(filename, listener) {\n filename = getValidatedPath(filename);\n var stat = statWatchers.get(filename);\n if (!stat)\n return;\n if (listener) {\n if (stat.removeListener(\"change\", listener), stat.listenerCount(\"change\") !== 0)\n return;\n } else\n stat.removeAllListeners(\"change\");\n stat.stop(), statWatchers.delete(filename);\n}, callbackify = function(fsFunction, args) {\n try {\n const result = fsFunction.apply(fs, args.slice(0, args.length - 1)), callback = args[args.length - 1];\n if (typeof callback === \"function\")\n queueMicrotask(() => callback(null, result));\n } catch (e) {\n const callback = args[args.length - 1];\n if (typeof callback === \"function\")\n queueMicrotask(() => callback(e));\n }\n}, createReadStream = function(path, options) {\n return new ReadStream(path, options);\n}, WriteStream_handleWrite = function(er, bytes) {\n if (er)\n return WriteStream_errorOrDestroy.call(this, er);\n this.bytesWritten += bytes;\n}, WriteStream_internalClose = function(err, cb) {\n this[_writeStreamPathFastPathSymbol] = !1;\n var fd = this.fd;\n this[_fs].close(fd, (er) => {\n this.fd = null, cb(err || er);\n });\n}, WriteStream_errorOrDestroy = function(err) {\n var {\n _readableState: r = { destroyed: !1, autoDestroy: !1 },\n _writableState: w = { destroyed: !1, autoDestroy: !1 }\n } = this;\n if (w\?.destroyed || r\?.destroyed)\n return this;\n if (r\?.autoDestroy || w\?.autoDestroy)\n this.destroy(err);\n else if (err)\n this.emit(\"error\", err);\n}, createWriteStream = function(path, options) {\n return new WriteStream(path, options);\n}, cpSync = function(src, dest, options) {\n if (!options)\n return fs.cpSync(src, dest);\n if (typeof options !== \"object\")\n @throwTypeError(\"options must be an object\");\n if (options.dereference || options.filter || options.preserveTimestamps || options.verbatimSymlinks) {\n if (!lazy_cpSync)\n lazy_cpSync = @getInternalField(@internalModuleRegistry, 3) || @createInternalModuleById(3);\n return lazy_cpSync(src, dest, options);\n }\n return fs.cpSync(src, dest, options.recursive, options.errorOnExist, options.force \?\? !0, options.mode);\n}, cp = function(src, dest, options, callback) {\n if (typeof options === \"function\")\n callback = options, options = @undefined;\n promises.cp(src, dest, options).then(() => callback(), callback);\n}, _toUnixTimestamp = function(time, name = \"time\") {\n if (typeof time === \"string\" && +time == time)\n return +time;\n if (NumberIsFinite(time)) {\n if (time < 0)\n return DateNow() / 1000;\n return time;\n }\n if (isDate(time))\n return DatePrototypeGetTime(time) / 1000;\n @throwTypeError(`Expected ${name} to be a number or Date`);\n}, $, ReadStream, WriteStream, EventEmitter = @getInternalField(@internalModuleRegistry, 18) || @createInternalModuleById(18), promises = @getInternalField(@internalModuleRegistry, 20) || @createInternalModuleById(20), Stream = @getInternalField(@internalModuleRegistry, 37) || @createInternalModuleById(37), { isArrayBufferView } = @requireNativeModule(\"util/types\"), _writeStreamPathFastPathSymbol = Symbol.for(\"Bun.NodeWriteStreamFastPath\"), _fs = Symbol.for(\"#fs\"), constants = @processBindingConstants.fs, fs = Bun.fs();\n\nclass FSWatcher extends EventEmitter {\n #watcher;\n #listener;\n constructor(path, options, listener) {\n super();\n if (typeof options === \"function\")\n listener = options, options = {};\n else if (typeof options === \"string\")\n options = { encoding: options };\n if (typeof listener !== \"function\")\n listener = () => {\n };\n this.#listener = listener;\n try {\n this.#watcher = fs.watch(path, options || {}, this.#onEvent.bind(this));\n } catch (e) {\n if (!e.message\?.startsWith(\"FileNotFound\"))\n throw e;\n const notFound = new Error(`ENOENT: no such file or directory, watch '${path}'`);\n throw notFound.code = \"ENOENT\", notFound.errno = -2, notFound.path = path, notFound.syscall = \"watch\", notFound.filename = path, notFound;\n }\n }\n #onEvent(eventType, filenameOrError) {\n if (eventType === \"error\" || eventType === \"close\")\n this.emit(eventType, filenameOrError);\n else\n this.emit(\"change\", eventType, filenameOrError), this.#listener(eventType, filenameOrError);\n }\n close() {\n this.#watcher\?.close(), this.#watcher = null;\n }\n ref() {\n this.#watcher\?.ref();\n }\n unref() {\n this.#watcher\?.unref();\n }\n start() {\n }\n}\n\nclass StatWatcher extends EventEmitter {\n constructor(path, options) {\n super();\n this._handle = fs.watchFile(path, options, this.#onChange.bind(this));\n }\n #onChange(curr, prev) {\n this.emit(\"change\", curr, prev);\n }\n start() {\n }\n stop() {\n this._handle\?.close(), this._handle = null;\n }\n ref() {\n this._handle\?.ref();\n }\n unref() {\n this._handle\?.unref();\n }\n}\nvar access = function access2(...args) {\n callbackify(fs.accessSync, args);\n}, appendFile = function appendFile2(...args) {\n callbackify(fs.appendFileSync, args);\n}, close = function close2(...args) {\n callbackify(fs.closeSync, args);\n}, rm = function rm2(...args) {\n callbackify(fs.rmSync, args);\n}, rmdir = function rmdir2(...args) {\n callbackify(fs.rmdirSync, args);\n}, copyFile = function copyFile2(...args) {\n const callback = args[args.length - 1];\n if (typeof callback !== \"function\")\n @throwTypeError(\"Callback must be a function\");\n fs.copyFile(...args).then((result) => callback(null, result), callback);\n}, exists = function exists2(...args) {\n callbackify(fs.existsSync, args);\n}, chown = function chown2(...args) {\n callbackify(fs.chownSync, args);\n}, chmod = function chmod2(...args) {\n callbackify(fs.chmodSync, args);\n}, fchmod = function fchmod2(...args) {\n callbackify(fs.fchmodSync, args);\n}, fchown = function fchown2(...args) {\n callbackify(fs.fchownSync, args);\n}, fstat = function fstat2(...args) {\n callbackify(fs.fstatSync, args);\n}, fsync = function fsync2(...args) {\n callbackify(fs.fsyncSync, args);\n}, ftruncate = function ftruncate2(...args) {\n callbackify(fs.ftruncateSync, args);\n}, futimes = function futimes2(...args) {\n callbackify(fs.futimesSync, args);\n}, lchmod = function lchmod2(...args) {\n callbackify(fs.lchmodSync, args);\n}, lchown = function lchown2(...args) {\n callbackify(fs.lchownSync, args);\n}, link = function link2(...args) {\n callbackify(fs.linkSync, args);\n}, mkdir = function mkdir2(...args) {\n callbackify(fs.mkdirSync, args);\n}, mkdtemp = function mkdtemp2(...args) {\n callbackify(fs.mkdtempSync, args);\n}, open = function open2(...args) {\n callbackify(fs.openSync, args);\n}, read = function read2(fd, buffer, offsetOrOptions, length, position, callback) {\n let offset = offsetOrOptions, params = null;\n if (arguments.length <= 4) {\n if (arguments.length === 4)\n callback = length, params = offsetOrOptions;\n else if (arguments.length === 3) {\n if (!isArrayBufferView(buffer))\n params = buffer, { buffer = @Buffer.alloc(16384) } = params \?\? {};\n callback = offsetOrOptions;\n } else\n callback = buffer, buffer = @Buffer.alloc(16384);\n ({ offset = 0, length = buffer\?.byteLength - offset, position = null } = params \?\? {});\n }\n queueMicrotask(() => {\n try {\n var bytesRead = fs.readSync(fd, buffer, offset, length, position);\n } catch (e) {\n callback(e);\n }\n callback(null, bytesRead, buffer);\n });\n}, write = function write2(...args) {\n callbackify(fs.writeSync, args);\n}, readdir = function readdir2(...args) {\n const callback = args[args.length - 1];\n if (typeof callback !== \"function\")\n @throwTypeError(\"Callback must be a function\");\n fs.readdir(...args).then((result) => callback(null, result), callback);\n}, readFile = function readFile2(...args) {\n const callback = args[args.length - 1];\n if (typeof callback !== \"function\")\n @throwTypeError(\"Callback must be a function\");\n fs.readFile(...args).then((result) => callback(null, result), callback);\n}, writeFile = function writeFile2(...args) {\n callbackify(fs.writeFileSync, args);\n}, readlink = function readlink2(...args) {\n callbackify(fs.readlinkSync, args);\n}, realpath = function realpath2(...args) {\n const callback = args[args.length - 1];\n if (typeof callback !== \"function\")\n @throwTypeError(\"Callback must be a function\");\n fs.realpath(...args).then((result) => callback(null, result), callback);\n}, rename = function rename2(...args) {\n callbackify(fs.renameSync, args);\n}, lstat = function lstat2(...args) {\n const callback = args[args.length - 1];\n if (typeof callback !== \"function\")\n @throwTypeError(\"Callback must be a function\");\n fs.lstat(...args).then((result) => callback(null, result), callback);\n}, stat = function stat2(...args) {\n const callback = args[args.length - 1];\n if (typeof callback !== \"function\")\n @throwTypeError(\"Callback must be a function\");\n fs.stat(...args).then((result) => callback(null, result), callback);\n}, symlink = function symlink2(...args) {\n callbackify(fs.symlinkSync, args);\n}, truncate = function truncate2(...args) {\n callbackify(fs.truncateSync, args);\n}, unlink = function unlink2(...args) {\n callbackify(fs.unlinkSync, args);\n}, utimes = function utimes2(...args) {\n callbackify(fs.utimesSync, args);\n}, lutimes = function lutimes2(...args) {\n callbackify(fs.lutimesSync, args);\n}, accessSync = fs.accessSync.bind(fs), appendFileSync = fs.appendFileSync.bind(fs), closeSync = fs.closeSync.bind(fs), copyFileSync = fs.copyFileSync.bind(fs), existsSync = fs.existsSync.bind(fs), chownSync = fs.chownSync.bind(fs), chmodSync = fs.chmodSync.bind(fs), fchmodSync = fs.fchmodSync.bind(fs), fchownSync = fs.fchownSync.bind(fs), fstatSync = fs.fstatSync.bind(fs), fsyncSync = fs.fsyncSync.bind(fs), ftruncateSync = fs.ftruncateSync.bind(fs), futimesSync = fs.futimesSync.bind(fs), lchmodSync = fs.lchmodSync.bind(fs), lchownSync = fs.lchownSync.bind(fs), linkSync = fs.linkSync.bind(fs), lstatSync = fs.lstatSync.bind(fs), mkdirSync = fs.mkdirSync.bind(fs), mkdtempSync = fs.mkdtempSync.bind(fs), openSync = fs.openSync.bind(fs), readSync = fs.readSync.bind(fs), writeSync = fs.writeSync.bind(fs), readdirSync = fs.readdirSync.bind(fs), readFileSync = fs.readFileSync.bind(fs), writeFileSync = fs.writeFileSync.bind(fs), readlinkSync = fs.readlinkSync.bind(fs), realpathSync = fs.realpathSync.bind(fs), renameSync = fs.renameSync.bind(fs), statSync = fs.statSync.bind(fs), symlinkSync = fs.symlinkSync.bind(fs), truncateSync = fs.truncateSync.bind(fs), unlinkSync = fs.unlinkSync.bind(fs), utimesSync = fs.utimesSync.bind(fs), lutimesSync = fs.lutimesSync.bind(fs), rmSync = fs.rmSync.bind(fs), rmdirSync = fs.rmdirSync.bind(fs), writev = (fd, buffers, position, callback) => {\n if (typeof position === \"function\")\n callback = position, position = null;\n queueMicrotask(() => {\n try {\n var written = fs.writevSync(fd, buffers, position);\n } catch (e) {\n callback(e);\n }\n callback(null, written, buffers);\n });\n}, writevSync = fs.writevSync.bind(fs), readv = (fd, buffers, position, callback) => {\n if (typeof position === \"function\")\n callback = position, position = null;\n queueMicrotask(() => {\n try {\n var written = fs.readvSync(fd, buffers, position);\n } catch (e) {\n callback(e);\n }\n callback(null, written, buffers);\n });\n}, readvSync = fs.readvSync.bind(fs), Dirent = fs.Dirent, Stats = fs.Stats, watch = function watch2(path, options, listener) {\n return new FSWatcher(path, options, listener);\n}, statWatchers = new Map, _pathModule, readStreamPathFastPathSymbol = Symbol.for(\"Bun.Node.readStreamPathFastPath\"), readStreamSymbol = Symbol.for(\"Bun.NodeReadStream\"), readStreamPathOrFdSymbol = Symbol.for(\"Bun.NodeReadStreamPathOrFd\"), writeStreamSymbol = Symbol.for(\"Bun.NodeWriteStream\"), writeStreamPathFastPathSymbol = Symbol.for(\"Bun.NodeWriteStreamFastPath\"), writeStreamPathFastPathCallSymbol = Symbol.for(\"Bun.NodeWriteStreamFastPathCall\"), kIoDone = Symbol.for(\"kIoDone\"), defaultReadStreamOptions = {\n file: @undefined,\n fd: null,\n flags: \"r\",\n encoding: @undefined,\n mode: 438,\n autoClose: !0,\n emitClose: !0,\n start: 0,\n end: @Infinity,\n highWaterMark: 65536,\n fs: {\n read,\n open: (path, flags, mode, cb) => {\n var fd;\n try {\n fd = openSync(path, flags, mode);\n } catch (e) {\n cb(e);\n return;\n }\n cb(null, fd);\n },\n openSync,\n close\n },\n autoDestroy: !0\n}, ReadStreamClass;\nReadStream = function(InternalReadStream) {\n ReadStreamClass = InternalReadStream, Object.defineProperty(ReadStreamClass.prototype, Symbol.toStringTag, {\n value: \"ReadStream\",\n enumerable: !1\n });\n function ReadStream3(path, options) {\n return new InternalReadStream(path, options);\n }\n return ReadStream3.prototype = InternalReadStream.prototype, Object.defineProperty(ReadStream3, Symbol.hasInstance, {\n value(instance) {\n return instance instanceof InternalReadStream;\n }\n });\n}(class ReadStream2 extends Stream._getNativeReadableStreamPrototype(2, Stream.Readable) {\n constructor(pathOrFd, options = defaultReadStreamOptions) {\n if (typeof options !== \"object\" || !options)\n @throwTypeError(\"Expected options to be an object\");\n var {\n flags = defaultReadStreamOptions.flags,\n encoding = defaultReadStreamOptions.encoding,\n mode = defaultReadStreamOptions.mode,\n autoClose = defaultReadStreamOptions.autoClose,\n emitClose = defaultReadStreamOptions.emitClose,\n start = defaultReadStreamOptions.start,\n end = defaultReadStreamOptions.end,\n autoDestroy = defaultReadStreamOptions.autoClose,\n fs: fs2 = defaultReadStreamOptions.fs,\n highWaterMark = defaultReadStreamOptions.highWaterMark,\n fd = defaultReadStreamOptions.fd\n } = options;\n if (pathOrFd\?.constructor\?.name === \"URL\")\n pathOrFd = Bun.fileURLToPath(pathOrFd);\n var tempThis = {};\n if (fd != null) {\n if (typeof fd !== \"number\")\n @throwTypeError(\"Expected options.fd to be a number\");\n tempThis.fd = tempThis[readStreamPathOrFdSymbol] = fd, tempThis.autoClose = !1;\n } else if (typeof pathOrFd === \"string\") {\n if (pathOrFd.startsWith(\"file://\"))\n pathOrFd = Bun.fileURLToPath(pathOrFd);\n if (pathOrFd.length === 0)\n @throwTypeError(\"Expected path to be a non-empty string\");\n tempThis.path = tempThis.file = tempThis[readStreamPathOrFdSymbol] = pathOrFd;\n } else if (typeof pathOrFd === \"number\") {\n if (pathOrFd |= 0, pathOrFd < 0)\n @throwTypeError(\"Expected fd to be a positive integer\");\n tempThis.fd = tempThis[readStreamPathOrFdSymbol] = pathOrFd, tempThis.autoClose = !1;\n } else\n @throwTypeError(\"Expected a path or file descriptor\");\n if (tempThis.fd === @undefined)\n tempThis.fd = fs2.openSync(pathOrFd, flags, mode);\n var fileRef = Bun.file(tempThis.fd), stream = fileRef.stream(), native = @direct(stream);\n if (!native)\n throw new Error(\"no native readable stream\");\n var { stream: ptr } = native;\n super(ptr, {\n ...options,\n encoding,\n autoDestroy,\n autoClose,\n emitClose,\n highWaterMark\n });\n if (Object.assign(this, tempThis), this.#fileRef = fileRef, this.end = end, this._read = this.#internalRead, this.start = start, this.flags = flags, this.mode = mode, this.emitClose = emitClose, this[readStreamPathFastPathSymbol] = start === 0 && end === @Infinity && autoClose && fs2 === defaultReadStreamOptions.fs && (encoding === \"buffer\" || encoding === \"binary\" || encoding == null || encoding === \"utf-8\" || encoding === \"utf8\"), this._readableState.autoClose = autoDestroy = autoClose, this._readableState.highWaterMark = highWaterMark, start !== @undefined)\n this.pos = start;\n }\n #fileRef;\n #fs;\n file;\n path;\n fd = null;\n flags;\n mode;\n start;\n end;\n pos;\n bytesRead = 0;\n #fileSize = -1;\n _read;\n [readStreamSymbol] = !0;\n [readStreamPathOrFdSymbol];\n [readStreamPathFastPathSymbol];\n _construct(callback) {\n if (super._construct)\n super._construct(callback);\n else\n callback();\n this.emit(\"open\", this.fd), this.emit(\"ready\");\n }\n _destroy(err, cb) {\n super._destroy(err, cb);\n try {\n var fd = this.fd;\n if (this[readStreamPathFastPathSymbol] = !1, !fd)\n cb(err);\n else\n this.#fs.close(fd, (er) => {\n cb(er || err);\n }), this.fd = null;\n } catch (e) {\n throw e;\n }\n }\n close(cb) {\n if (typeof cb === \"function\")\n Stream.eos(this, cb);\n this.destroy();\n }\n push(chunk) {\n var bytesRead = chunk\?.length \?\? 0;\n if (bytesRead > 0) {\n this.bytesRead += bytesRead;\n var currPos = this.pos;\n if (currPos !== @undefined) {\n if (this.bytesRead < currPos)\n return !0;\n if (currPos === this.start) {\n var n = this.bytesRead - currPos;\n chunk = chunk.slice(-n);\n var [_, ...rest] = arguments;\n if (this.pos = this.bytesRead, this.end !== @undefined && this.bytesRead > this.end)\n chunk = chunk.slice(0, this.end - this.start + 1);\n return super.push(chunk, ...rest);\n }\n var end = this.end;\n if (end !== @undefined && this.bytesRead > end) {\n chunk = chunk.slice(0, end - currPos + 1);\n var [_, ...rest] = arguments;\n return this.pos = this.bytesRead, super.push(chunk, ...rest);\n }\n this.pos = this.bytesRead;\n }\n }\n return super.push(...arguments);\n }\n #internalRead(n) {\n var { pos, end, bytesRead, fd, encoding } = this;\n if (n = pos !== @undefined \? Math.min(end - pos + 1, n) : Math.min(end - bytesRead + 1, n), n <= 0) {\n this.push(null);\n return;\n }\n if (this.#fileSize === -1 && bytesRead === 0 && pos === @undefined) {\n var stat3 = fstatSync(fd);\n if (this.#fileSize = stat3.size, this.#fileSize > 0 && n > this.#fileSize)\n n = this.#fileSize + 1;\n }\n this[kIoDone] = !1;\n var res = super._read(n);\n if (@isPromise(res)) {\n var then = res\?.then;\n if (then && @isCallable(then))\n res.then(() => {\n if (this[kIoDone] = !0, this.destroyed)\n this.emit(kIoDone);\n }, (er) => {\n this[kIoDone] = !0, this.#errorOrDestroy(er);\n });\n } else if (this[kIoDone] = !0, this.destroyed)\n this.emit(kIoDone), this.#errorOrDestroy(new Error(\"ERR_STREAM_PREMATURE_CLOSE\"));\n }\n #errorOrDestroy(err, sync = null) {\n var {\n _readableState: r = { destroyed: !1, autoDestroy: !1 },\n _writableState: w = { destroyed: !1, autoDestroy: !1 }\n } = this;\n if (w\?.destroyed || r\?.destroyed)\n return this;\n if (r\?.autoDestroy || w\?.autoDestroy)\n this.destroy(err);\n else if (err)\n this.emit(\"error\", err);\n }\n pause() {\n return this[readStreamPathFastPathSymbol] = !1, super.pause();\n }\n resume() {\n return this[readStreamPathFastPathSymbol] = !1, super.resume();\n }\n unshift(...args) {\n return this[readStreamPathFastPathSymbol] = !1, super.unshift(...args);\n }\n pipe(dest, pipeOpts) {\n if (this[readStreamPathFastPathSymbol] && (pipeOpts\?.end \?\? !0) && this._readableState\?.pipes\?.length === 0) {\n if ((writeStreamPathFastPathSymbol in dest) && dest[writeStreamPathFastPathSymbol]) {\n if (dest[writeStreamPathFastPathCallSymbol](this, pipeOpts))\n return this;\n }\n }\n return this[readStreamPathFastPathSymbol] = !1, super.pipe(dest, pipeOpts);\n }\n});\nvar defaultWriteStreamOptions = {\n fd: null,\n start: @undefined,\n pos: @undefined,\n encoding: @undefined,\n flags: \"w\",\n mode: 438,\n fs: {\n write,\n close,\n open,\n openSync\n }\n}, WriteStreamClass = WriteStream = function WriteStream2(path, options = defaultWriteStreamOptions) {\n if (!(this instanceof WriteStream2))\n return new WriteStream2(path, options);\n if (!options)\n @throwTypeError(\"Expected options to be an object\");\n var {\n fs: fs2 = defaultWriteStreamOptions.fs,\n start = defaultWriteStreamOptions.start,\n flags = defaultWriteStreamOptions.flags,\n mode = defaultWriteStreamOptions.mode,\n autoClose = !0,\n emitClose = !1,\n autoDestroy = autoClose,\n encoding = defaultWriteStreamOptions.encoding,\n fd = defaultWriteStreamOptions.fd,\n pos = defaultWriteStreamOptions.pos\n } = options, tempThis = {};\n if (fd != null) {\n if (typeof fd !== \"number\")\n throw new Error(\"Expected options.fd to be a number\");\n tempThis.fd = fd, tempThis[_writeStreamPathFastPathSymbol] = !1;\n } else if (typeof path === \"string\") {\n if (path.length === 0)\n @throwTypeError(\"Expected a non-empty path\");\n if (path.startsWith(\"file:\"))\n path = Bun.fileURLToPath(path);\n tempThis.path = path, tempThis.fd = null, tempThis[_writeStreamPathFastPathSymbol] = autoClose && (start === @undefined || start === 0) && fs2.write === defaultWriteStreamOptions.fs.write && fs2.close === defaultWriteStreamOptions.fs.close;\n }\n if (tempThis.fd == null)\n tempThis.fd = fs2.openSync(path, flags, mode);\n if (NativeWritable.call(this, tempThis.fd, {\n ...options,\n decodeStrings: !1,\n autoDestroy,\n emitClose,\n fd: tempThis\n }), Object.assign(this, tempThis), typeof fs2\?.write !== \"function\")\n @throwTypeError(\"Expected fs.write to be a function\");\n if (typeof fs2\?.close !== \"function\")\n @throwTypeError(\"Expected fs.close to be a function\");\n if (typeof fs2\?.open !== \"function\")\n @throwTypeError(\"Expected fs.open to be a function\");\n if (typeof path === \"object\" && path) {\n if (path instanceof URL)\n path = Bun.fileURLToPath(path);\n }\n if (typeof path !== \"string\" && typeof fd !== \"number\")\n @throwTypeError(\"Expected a path or file descriptor\");\n if (this.start = start, this[_fs] = fs2, this.flags = flags, this.mode = mode, this.bytesWritten = 0, this[writeStreamSymbol] = !0, this[kIoDone] = !1, this.start !== @undefined)\n this.pos = this.start;\n if (encoding !== defaultWriteStreamOptions.encoding) {\n if (this.setDefaultEncoding(encoding), encoding !== \"buffer\" && encoding !== \"utf8\" && encoding !== \"utf-8\" && encoding !== \"binary\")\n this[_writeStreamPathFastPathSymbol] = !1;\n }\n return this;\n}, NativeWritable = Stream.NativeWritable, WriteStreamPrototype = WriteStream.prototype = Object.create(NativeWritable.prototype);\nObject.defineProperties(WriteStreamPrototype, {\n autoClose: {\n get() {\n return this._writableState.autoDestroy;\n },\n set(val) {\n this._writableState.autoDestroy = val;\n }\n },\n pending: {\n get() {\n return this.fd === null;\n }\n }\n});\nWriteStreamPrototype.destroySoon = WriteStreamPrototype.end;\nWriteStreamPrototype.open = function open3() {\n};\nWriteStreamPrototype[writeStreamPathFastPathCallSymbol] = function WriteStreamPathFastPathCallSymbol(readStream, pipeOpts) {\n if (!this[_writeStreamPathFastPathSymbol])\n return !1;\n if (this.fd !== null)\n return this[_writeStreamPathFastPathSymbol] = !1, !1;\n return this[kIoDone] = !1, readStream[kIoDone] = !1, Bun.write(this[_writeStreamPathFastPathSymbol], readStream[readStreamPathOrFdSymbol]).then((bytesWritten) => {\n readStream[kIoDone] = this[kIoDone] = !0, this.bytesWritten += bytesWritten, readStream.bytesRead += bytesWritten, this.end(), readStream.close();\n }, (err) => {\n readStream[kIoDone] = this[kIoDone] = !0, WriteStream_errorOrDestroy.call(this, err), readStream.emit(\"error\", err);\n });\n};\nWriteStreamPrototype.isBunFastPathEnabled = function isBunFastPathEnabled() {\n return this[_writeStreamPathFastPathSymbol];\n};\nWriteStreamPrototype.disableBunFastPath = function disableBunFastPath() {\n this[_writeStreamPathFastPathSymbol] = !1;\n};\nWriteStreamPrototype._construct = function _construct(callback) {\n if (typeof this.fd === \"number\") {\n callback();\n return;\n }\n callback(), this.emit(\"open\", this.fd), this.emit(\"ready\");\n};\nWriteStreamPrototype._destroy = function _destroy(err, cb) {\n if (this.fd === null)\n return cb(err);\n if (this[kIoDone]) {\n this.once(kIoDone, () => WriteStream_internalClose.call(this, err, cb));\n return;\n }\n WriteStream_internalClose.call(this, err, cb);\n};\nWriteStreamPrototype.close = function close3(cb) {\n if (cb) {\n if (this.closed) {\n process.nextTick(cb);\n return;\n }\n this.on(\"close\", cb);\n }\n if (!this.autoClose)\n this.on(\"finish\", this.destroy);\n this.end();\n};\nWriteStreamPrototype.write = function write3(chunk, encoding, cb) {\n if (encoding \?\?= this._writableState\?.defaultEncoding, this[_writeStreamPathFastPathSymbol] = !1, typeof chunk === \"string\")\n chunk = @Buffer.from(chunk, encoding);\n var native = this.pos === @undefined;\n const callback = native \? (err, bytes) => {\n if (this[kIoDone] = !1, WriteStream_handleWrite.call(this, err, bytes), this.emit(kIoDone), cb)\n !err \? cb() : cb(err);\n } : () => {\n };\n if (this[kIoDone] = !0, this._write)\n return this._write(chunk, encoding, callback);\n else\n return NativeWritable.prototype.write.call(this, chunk, encoding, callback, native);\n};\nWriteStreamPrototype._write = @undefined;\nWriteStreamPrototype._writev = @undefined;\nWriteStreamPrototype.end = function end(chunk, encoding, cb) {\n var native = this.pos === @undefined;\n return NativeWritable.prototype.end.call(this, chunk, encoding, cb, native);\n};\nWriteStreamPrototype._destroy = function _destroy2(err, cb) {\n this.close(err, cb);\n};\nObject.defineProperties(fs, {\n createReadStream: {\n value: createReadStream\n },\n createWriteStream: {\n value: createWriteStream\n },\n ReadStream: {\n value: ReadStream\n },\n WriteStream: {\n value: WriteStream\n }\n});\nrealpath.native = realpath;\nrealpathSync.native = realpathSync;\nvar lazy_cpSync = null;\n$ = {\n Dirent,\n FSWatcher,\n ReadStream,\n Stats,\n WriteStream,\n _toUnixTimestamp,\n access,\n accessSync,\n appendFile,\n appendFileSync,\n chmod,\n chmodSync,\n chown,\n chownSync,\n close,\n closeSync,\n constants,\n copyFile,\n copyFileSync,\n cp,\n cpSync,\n createReadStream,\n createWriteStream,\n exists,\n existsSync,\n fchmod,\n fchmodSync,\n fchown,\n fchownSync,\n fstat,\n fstatSync,\n fsync,\n fsyncSync,\n ftruncate,\n ftruncateSync,\n futimes,\n futimesSync,\n lchmod,\n lchmodSync,\n lchown,\n lchownSync,\n link,\n linkSync,\n lstat,\n lstatSync,\n lutimes,\n lutimesSync,\n mkdir,\n mkdirSync,\n mkdtemp,\n mkdtempSync,\n open,\n openSync,\n promises,\n read,\n readFile,\n readFileSync,\n readSync,\n readdir,\n readdirSync,\n readlink,\n readlinkSync,\n readv,\n readvSync,\n realpath,\n realpathSync,\n rename,\n renameSync,\n rm,\n rmSync,\n rmdir,\n rmdirSync,\n stat,\n statSync,\n symlink,\n symlinkSync,\n truncate,\n truncateSync,\n unlink,\n unlinkSync,\n unwatchFile,\n utimes,\n utimesSync,\n watch,\n watchFile,\n write,\n writeFile,\n writeFileSync,\n writeSync,\n writev,\n writevSync,\n [Symbol.for(\"::bunternal::\")]: {\n ReadStreamClass,\n WriteStreamClass\n }\n};\nreturn $})\n"_s; +static constexpr ASCIILiteral NodeFSCode = "(function (){\"use strict\";// src/js/out/tmp/node/fs.ts\nvar getValidatedPath = function(p) {\n if (p instanceof URL)\n return Bun.fileURLToPath(p);\n if (typeof p !== \"string\")\n @throwTypeError(\"Path must be a string or URL.\");\n return (_pathModule \?\?= @getInternalField(@internalModuleRegistry, 28) || @createInternalModuleById(28)).resolve(p);\n}, watchFile = function(filename, options, listener) {\n if (filename = getValidatedPath(filename), typeof options === \"function\")\n listener = options, options = {};\n if (typeof listener !== \"function\")\n @throwTypeError(\"listener must be a function\");\n var stat = statWatchers.get(filename);\n if (!stat)\n stat = new StatWatcher(filename, options), statWatchers.set(filename, stat);\n return stat.addListener(\"change\", listener), stat;\n}, unwatchFile = function(filename, listener) {\n filename = getValidatedPath(filename);\n var stat = statWatchers.get(filename);\n if (!stat)\n return;\n if (listener) {\n if (stat.removeListener(\"change\", listener), stat.listenerCount(\"change\") !== 0)\n return;\n } else\n stat.removeAllListeners(\"change\");\n stat.stop(), statWatchers.delete(filename);\n}, callbackify = function(fsFunction, args) {\n const callback = args[args.length - 1];\n try {\n var result = fsFunction.apply(fs, args.slice(0, args.length - 1));\n result.then((...args2) => callback(null, ...args2), (err) => callback(err));\n } catch (e) {\n if (typeof callback === \"function\")\n callback(e);\n else\n throw e;\n }\n}, createReadStream = function(path, options) {\n return new ReadStream(path, options);\n}, WriteStream_handleWrite = function(er, bytes) {\n if (er)\n return WriteStream_errorOrDestroy.call(this, er);\n this.bytesWritten += bytes;\n}, WriteStream_internalClose = function(err, cb) {\n this[_writeStreamPathFastPathSymbol] = !1;\n var fd = this.fd;\n this[_fs].close(fd, (er) => {\n this.fd = null, cb(err || er);\n });\n}, WriteStream_errorOrDestroy = function(err) {\n var {\n _readableState: r = { destroyed: !1, autoDestroy: !1 },\n _writableState: w = { destroyed: !1, autoDestroy: !1 }\n } = this;\n if (w\?.destroyed || r\?.destroyed)\n return this;\n if (r\?.autoDestroy || w\?.autoDestroy)\n this.destroy(err);\n else if (err)\n this.emit(\"error\", err);\n}, createWriteStream = function(path, options) {\n return new WriteStream(path, options);\n}, cpSync = function(src, dest, options) {\n if (!options)\n return fs.cpSync(src, dest);\n if (typeof options !== \"object\")\n @throwTypeError(\"options must be an object\");\n if (options.dereference || options.filter || options.preserveTimestamps || options.verbatimSymlinks) {\n if (!lazy_cpSync)\n lazy_cpSync = @getInternalField(@internalModuleRegistry, 3) || @createInternalModuleById(3);\n return lazy_cpSync(src, dest, options);\n }\n return fs.cpSync(src, dest, options.recursive, options.errorOnExist, options.force \?\? !0, options.mode);\n}, cp = function(src, dest, options, callback) {\n if (typeof options === \"function\")\n callback = options, options = @undefined;\n promises.cp(src, dest, options).then(() => callback(), callback);\n}, _toUnixTimestamp = function(time, name = \"time\") {\n if (typeof time === \"string\" && +time == time)\n return +time;\n if (NumberIsFinite(time)) {\n if (time < 0)\n return DateNow() / 1000;\n return time;\n }\n if (isDate(time))\n return DatePrototypeGetTime(time) / 1000;\n @throwTypeError(`Expected ${name} to be a number or Date`);\n}, $, ReadStream, WriteStream, EventEmitter = @getInternalField(@internalModuleRegistry, 18) || @createInternalModuleById(18), promises = @getInternalField(@internalModuleRegistry, 20) || @createInternalModuleById(20), Stream = @getInternalField(@internalModuleRegistry, 37) || @createInternalModuleById(37), { isArrayBufferView } = @requireNativeModule(\"util/types\"), _writeStreamPathFastPathSymbol = Symbol.for(\"Bun.NodeWriteStreamFastPath\"), _fs = Symbol.for(\"#fs\"), constants = @processBindingConstants.fs, fs = Bun.fs();\n\nclass FSWatcher extends EventEmitter {\n #watcher;\n #listener;\n constructor(path, options, listener) {\n super();\n if (typeof options === \"function\")\n listener = options, options = {};\n else if (typeof options === \"string\")\n options = { encoding: options };\n if (typeof listener !== \"function\")\n listener = () => {\n };\n this.#listener = listener;\n try {\n this.#watcher = fs.watch(path, options || {}, this.#onEvent.bind(this));\n } catch (e) {\n if (!e.message\?.startsWith(\"FileNotFound\"))\n throw e;\n const notFound = new Error(`ENOENT: no such file or directory, watch '${path}'`);\n throw notFound.code = \"ENOENT\", notFound.errno = -2, notFound.path = path, notFound.syscall = \"watch\", notFound.filename = path, notFound;\n }\n }\n #onEvent(eventType, filenameOrError) {\n if (eventType === \"error\" || eventType === \"close\")\n this.emit(eventType, filenameOrError);\n else\n this.emit(\"change\", eventType, filenameOrError), this.#listener(eventType, filenameOrError);\n }\n close() {\n this.#watcher\?.close(), this.#watcher = null;\n }\n ref() {\n this.#watcher\?.ref();\n }\n unref() {\n this.#watcher\?.unref();\n }\n start() {\n }\n}\n\nclass StatWatcher extends EventEmitter {\n constructor(path, options) {\n super();\n this._handle = fs.watchFile(path, options, this.#onChange.bind(this));\n }\n #onChange(curr, prev) {\n this.emit(\"change\", curr, prev);\n }\n start() {\n }\n stop() {\n this._handle\?.close(), this._handle = null;\n }\n ref() {\n this._handle\?.ref();\n }\n unref() {\n this._handle\?.unref();\n }\n}\nvar access = function access2(...args) {\n callbackify(fs.access, args);\n}, appendFile = function appendFile2(...args) {\n callbackify(fs.appendFile, args);\n}, close = function close2(...args) {\n callbackify(fs.close, args);\n}, rm = function rm2(...args) {\n callbackify(fs.rm, args);\n}, rmdir = function rmdir2(...args) {\n callbackify(fs.rmdir, args);\n}, copyFile = function copyFile2(...args) {\n const callback = args[args.length - 1];\n if (typeof callback !== \"function\")\n @throwTypeError(\"Callback must be a function\");\n fs.copyFile(...args).then((result) => callback(null, result), callback);\n}, exists = function exists2(...args) {\n callbackify(fs.exists, args);\n}, chown = function chown2(...args) {\n callbackify(fs.chown, args);\n}, chmod = function chmod2(...args) {\n callbackify(fs.chmod, args);\n}, fchmod = function fchmod2(...args) {\n callbackify(fs.fchmod, args);\n}, fchown = function fchown2(...args) {\n callbackify(fs.fchown, args);\n}, fstat = function fstat2(...args) {\n callbackify(fs.fstat, args);\n}, fsync = function fsync2(...args) {\n callbackify(fs.fsync, args);\n}, ftruncate = function ftruncate2(...args) {\n callbackify(fs.ftruncate, args);\n}, futimes = function futimes2(...args) {\n callbackify(fs.futimes, args);\n}, lchmod = function lchmod2(...args) {\n callbackify(fs.lchmod, args);\n}, lchown = function lchown2(...args) {\n callbackify(fs.lchown, args);\n}, link = function link2(...args) {\n callbackify(fs.link, args);\n}, mkdir = function mkdir2(...args) {\n callbackify(fs.mkdir, args);\n}, mkdtemp = function mkdtemp2(...args) {\n callbackify(fs.mkdtemp, args);\n}, open = function open2(...args) {\n callbackify(fs.open, args);\n}, read = function read2(fd, buffer, offsetOrOptions, length, position, callback) {\n let offset = offsetOrOptions, params = null;\n if (arguments.length <= 4) {\n if (arguments.length === 4)\n callback = length, params = offsetOrOptions;\n else if (arguments.length === 3) {\n if (!isArrayBufferView(buffer))\n params = buffer, { buffer = @Buffer.alloc(16384) } = params \?\? {};\n callback = offsetOrOptions;\n } else\n callback = buffer, buffer = @Buffer.alloc(16384);\n ({ offset = 0, length = buffer\?.byteLength - offset, position = null } = params \?\? {});\n }\n queueMicrotask(() => {\n try {\n var bytesRead = fs.readSync(fd, buffer, offset, length, position);\n } catch (e) {\n callback(e);\n }\n callback(null, bytesRead, buffer);\n });\n}, write = function write2(...args) {\n callbackify(fs.write, args);\n}, readdir = function readdir2(...args) {\n const callback = args[args.length - 1];\n if (typeof callback !== \"function\")\n @throwTypeError(\"Callback must be a function\");\n fs.readdir(...args).then((result) => callback(null, result), callback);\n}, readFile = function readFile2(...args) {\n const callback = args[args.length - 1];\n if (typeof callback !== \"function\")\n @throwTypeError(\"Callback must be a function\");\n fs.readFile(...args).then((result) => callback(null, result), callback);\n}, writeFile = function writeFile2(...args) {\n callbackify(fs.writeFile, args);\n}, readlink = function readlink2(...args) {\n callbackify(fs.readlink, args);\n}, realpath = function realpath2(...args) {\n const callback = args[args.length - 1];\n if (typeof callback !== \"function\")\n @throwTypeError(\"Callback must be a function\");\n fs.realpath(...args).then((result) => callback(null, result), callback);\n}, rename = function rename2(...args) {\n callbackify(fs.rename, args);\n}, lstat = function lstat2(...args) {\n const callback = args[args.length - 1];\n if (typeof callback !== \"function\")\n @throwTypeError(\"Callback must be a function\");\n fs.lstat(...args).then((result) => callback(null, result), callback);\n}, stat = function stat2(...args) {\n const callback = args[args.length - 1];\n if (typeof callback !== \"function\")\n @throwTypeError(\"Callback must be a function\");\n fs.stat(...args).then((result) => callback(null, result), callback);\n}, symlink = function symlink2(...args) {\n callbackify(fs.symlink, args);\n}, truncate = function truncate2(...args) {\n callbackify(fs.truncate, args);\n}, unlink = function unlink2(...args) {\n callbackify(fs.unlink, args);\n}, utimes = function utimes2(...args) {\n callbackify(fs.utimes, args);\n}, lutimes = function lutimes2(...args) {\n callbackify(fs.lutimes, args);\n}, accessSync = fs.accessSync.bind(fs), appendFileSync = fs.appendFileSync.bind(fs), closeSync = fs.closeSync.bind(fs), copyFileSync = fs.copyFileSync.bind(fs), existsSync = fs.existsSync.bind(fs), chownSync = fs.chownSync.bind(fs), chmodSync = fs.chmodSync.bind(fs), fchmodSync = fs.fchmodSync.bind(fs), fchownSync = fs.fchownSync.bind(fs), fstatSync = fs.fstatSync.bind(fs), fsyncSync = fs.fsyncSync.bind(fs), ftruncateSync = fs.ftruncateSync.bind(fs), futimesSync = fs.futimesSync.bind(fs), lchmodSync = fs.lchmodSync.bind(fs), lchownSync = fs.lchownSync.bind(fs), linkSync = fs.linkSync.bind(fs), lstatSync = fs.lstatSync.bind(fs), mkdirSync = fs.mkdirSync.bind(fs), mkdtempSync = fs.mkdtempSync.bind(fs), openSync = fs.openSync.bind(fs), readSync = fs.readSync.bind(fs), writeSync = fs.writeSync.bind(fs), readdirSync = fs.readdirSync.bind(fs), readFileSync = fs.readFileSync.bind(fs), writeFileSync = fs.writeFileSync.bind(fs), readlinkSync = fs.readlinkSync.bind(fs), realpathSync = fs.realpathSync.bind(fs), renameSync = fs.renameSync.bind(fs), statSync = fs.statSync.bind(fs), symlinkSync = fs.symlinkSync.bind(fs), truncateSync = fs.truncateSync.bind(fs), unlinkSync = fs.unlinkSync.bind(fs), utimesSync = fs.utimesSync.bind(fs), lutimesSync = fs.lutimesSync.bind(fs), rmSync = fs.rmSync.bind(fs), rmdirSync = fs.rmdirSync.bind(fs), writev = (fd, buffers, position, callback) => {\n if (typeof position === \"function\")\n callback = position, position = null;\n queueMicrotask(() => {\n try {\n var written = fs.writevSync(fd, buffers, position);\n } catch (e) {\n callback(e);\n }\n callback(null, written, buffers);\n });\n}, writevSync = fs.writevSync.bind(fs), readv = (fd, buffers, position, callback) => {\n if (typeof position === \"function\")\n callback = position, position = null;\n queueMicrotask(() => {\n try {\n var written = fs.readvSync(fd, buffers, position);\n } catch (e) {\n callback(e);\n }\n callback(null, written, buffers);\n });\n}, readvSync = fs.readvSync.bind(fs), Dirent = fs.Dirent, Stats = fs.Stats, watch = function watch2(path, options, listener) {\n return new FSWatcher(path, options, listener);\n}, statWatchers = new Map, _pathModule, readStreamPathFastPathSymbol = Symbol.for(\"Bun.Node.readStreamPathFastPath\"), readStreamSymbol = Symbol.for(\"Bun.NodeReadStream\"), readStreamPathOrFdSymbol = Symbol.for(\"Bun.NodeReadStreamPathOrFd\"), writeStreamSymbol = Symbol.for(\"Bun.NodeWriteStream\"), writeStreamPathFastPathSymbol = Symbol.for(\"Bun.NodeWriteStreamFastPath\"), writeStreamPathFastPathCallSymbol = Symbol.for(\"Bun.NodeWriteStreamFastPathCall\"), kIoDone = Symbol.for(\"kIoDone\"), defaultReadStreamOptions = {\n file: @undefined,\n fd: null,\n flags: \"r\",\n encoding: @undefined,\n mode: 438,\n autoClose: !0,\n emitClose: !0,\n start: 0,\n end: @Infinity,\n highWaterMark: 65536,\n fs: {\n read,\n open: (path, flags, mode, cb) => {\n var fd;\n try {\n fd = openSync(path, flags, mode);\n } catch (e) {\n cb(e);\n return;\n }\n cb(null, fd);\n },\n openSync,\n close\n },\n autoDestroy: !0\n}, ReadStreamClass;\nReadStream = function(InternalReadStream) {\n ReadStreamClass = InternalReadStream, Object.defineProperty(ReadStreamClass.prototype, Symbol.toStringTag, {\n value: \"ReadStream\",\n enumerable: !1\n });\n function ReadStream3(path, options) {\n return new InternalReadStream(path, options);\n }\n return ReadStream3.prototype = InternalReadStream.prototype, Object.defineProperty(ReadStream3, Symbol.hasInstance, {\n value(instance) {\n return instance instanceof InternalReadStream;\n }\n });\n}(class ReadStream2 extends Stream._getNativeReadableStreamPrototype(2, Stream.Readable) {\n constructor(pathOrFd, options = defaultReadStreamOptions) {\n if (typeof options !== \"object\" || !options)\n @throwTypeError(\"Expected options to be an object\");\n var {\n flags = defaultReadStreamOptions.flags,\n encoding = defaultReadStreamOptions.encoding,\n mode = defaultReadStreamOptions.mode,\n autoClose = defaultReadStreamOptions.autoClose,\n emitClose = defaultReadStreamOptions.emitClose,\n start = defaultReadStreamOptions.start,\n end = defaultReadStreamOptions.end,\n autoDestroy = defaultReadStreamOptions.autoClose,\n fs: fs2 = defaultReadStreamOptions.fs,\n highWaterMark = defaultReadStreamOptions.highWaterMark,\n fd = defaultReadStreamOptions.fd\n } = options;\n if (pathOrFd\?.constructor\?.name === \"URL\")\n pathOrFd = Bun.fileURLToPath(pathOrFd);\n var tempThis = {};\n if (fd != null) {\n if (typeof fd !== \"number\")\n @throwTypeError(\"Expected options.fd to be a number\");\n tempThis.fd = tempThis[readStreamPathOrFdSymbol] = fd, tempThis.autoClose = !1;\n } else if (typeof pathOrFd === \"string\") {\n if (pathOrFd.startsWith(\"file://\"))\n pathOrFd = Bun.fileURLToPath(pathOrFd);\n if (pathOrFd.length === 0)\n @throwTypeError(\"Expected path to be a non-empty string\");\n tempThis.path = tempThis.file = tempThis[readStreamPathOrFdSymbol] = pathOrFd;\n } else if (typeof pathOrFd === \"number\") {\n if (pathOrFd |= 0, pathOrFd < 0)\n @throwTypeError(\"Expected fd to be a positive integer\");\n tempThis.fd = tempThis[readStreamPathOrFdSymbol] = pathOrFd, tempThis.autoClose = !1;\n } else\n @throwTypeError(\"Expected a path or file descriptor\");\n if (tempThis.fd === @undefined)\n tempThis.fd = fs2.openSync(pathOrFd, flags, mode);\n var fileRef = Bun.file(tempThis.fd), stream = fileRef.stream(), native = @direct(stream);\n if (!native)\n throw new Error(\"no native readable stream\");\n var { stream: ptr } = native;\n super(ptr, {\n ...options,\n encoding,\n autoDestroy,\n autoClose,\n emitClose,\n highWaterMark\n });\n if (Object.assign(this, tempThis), this.#fileRef = fileRef, this.end = end, this._read = this.#internalRead, this.start = start, this.flags = flags, this.mode = mode, this.emitClose = emitClose, this[readStreamPathFastPathSymbol] = start === 0 && end === @Infinity && autoClose && fs2 === defaultReadStreamOptions.fs && (encoding === \"buffer\" || encoding === \"binary\" || encoding == null || encoding === \"utf-8\" || encoding === \"utf8\"), this._readableState.autoClose = autoDestroy = autoClose, this._readableState.highWaterMark = highWaterMark, start !== @undefined)\n this.pos = start;\n }\n #fileRef;\n #fs;\n file;\n path;\n fd = null;\n flags;\n mode;\n start;\n end;\n pos;\n bytesRead = 0;\n #fileSize = -1;\n _read;\n [readStreamSymbol] = !0;\n [readStreamPathOrFdSymbol];\n [readStreamPathFastPathSymbol];\n _construct(callback) {\n if (super._construct)\n super._construct(callback);\n else\n callback();\n this.emit(\"open\", this.fd), this.emit(\"ready\");\n }\n _destroy(err, cb) {\n super._destroy(err, cb);\n try {\n var fd = this.fd;\n if (this[readStreamPathFastPathSymbol] = !1, !fd)\n cb(err);\n else\n this.#fs.close(fd, (er) => {\n cb(er || err);\n }), this.fd = null;\n } catch (e) {\n throw e;\n }\n }\n close(cb) {\n if (typeof cb === \"function\")\n Stream.eos(this, cb);\n this.destroy();\n }\n push(chunk) {\n var bytesRead = chunk\?.length \?\? 0;\n if (bytesRead > 0) {\n this.bytesRead += bytesRead;\n var currPos = this.pos;\n if (currPos !== @undefined) {\n if (this.bytesRead < currPos)\n return !0;\n if (currPos === this.start) {\n var n = this.bytesRead - currPos;\n chunk = chunk.slice(-n);\n var [_, ...rest] = arguments;\n if (this.pos = this.bytesRead, this.end !== @undefined && this.bytesRead > this.end)\n chunk = chunk.slice(0, this.end - this.start + 1);\n return super.push(chunk, ...rest);\n }\n var end = this.end;\n if (end !== @undefined && this.bytesRead > end) {\n chunk = chunk.slice(0, end - currPos + 1);\n var [_, ...rest] = arguments;\n return this.pos = this.bytesRead, super.push(chunk, ...rest);\n }\n this.pos = this.bytesRead;\n }\n }\n return super.push(...arguments);\n }\n #internalRead(n) {\n var { pos, end, bytesRead, fd, encoding } = this;\n if (n = pos !== @undefined \? Math.min(end - pos + 1, n) : Math.min(end - bytesRead + 1, n), n <= 0) {\n this.push(null);\n return;\n }\n if (this.#fileSize === -1 && bytesRead === 0 && pos === @undefined) {\n var stat3 = fstatSync(fd);\n if (this.#fileSize = stat3.size, this.#fileSize > 0 && n > this.#fileSize)\n n = this.#fileSize + 1;\n }\n this[kIoDone] = !1;\n var res = super._read(n);\n if (@isPromise(res)) {\n var then = res\?.then;\n if (then && @isCallable(then))\n res.then(() => {\n if (this[kIoDone] = !0, this.destroyed)\n this.emit(kIoDone);\n }, (er) => {\n this[kIoDone] = !0, this.#errorOrDestroy(er);\n });\n } else if (this[kIoDone] = !0, this.destroyed)\n this.emit(kIoDone), this.#errorOrDestroy(new Error(\"ERR_STREAM_PREMATURE_CLOSE\"));\n }\n #errorOrDestroy(err, sync = null) {\n var {\n _readableState: r = { destroyed: !1, autoDestroy: !1 },\n _writableState: w = { destroyed: !1, autoDestroy: !1 }\n } = this;\n if (w\?.destroyed || r\?.destroyed)\n return this;\n if (r\?.autoDestroy || w\?.autoDestroy)\n this.destroy(err);\n else if (err)\n this.emit(\"error\", err);\n }\n pause() {\n return this[readStreamPathFastPathSymbol] = !1, super.pause();\n }\n resume() {\n return this[readStreamPathFastPathSymbol] = !1, super.resume();\n }\n unshift(...args) {\n return this[readStreamPathFastPathSymbol] = !1, super.unshift(...args);\n }\n pipe(dest, pipeOpts) {\n if (this[readStreamPathFastPathSymbol] && (pipeOpts\?.end \?\? !0) && this._readableState\?.pipes\?.length === 0) {\n if ((writeStreamPathFastPathSymbol in dest) && dest[writeStreamPathFastPathSymbol]) {\n if (dest[writeStreamPathFastPathCallSymbol](this, pipeOpts))\n return this;\n }\n }\n return this[readStreamPathFastPathSymbol] = !1, super.pipe(dest, pipeOpts);\n }\n});\nvar defaultWriteStreamOptions = {\n fd: null,\n start: @undefined,\n pos: @undefined,\n encoding: @undefined,\n flags: \"w\",\n mode: 438,\n fs: {\n write,\n close,\n open,\n openSync\n }\n}, WriteStreamClass = WriteStream = function WriteStream2(path, options = defaultWriteStreamOptions) {\n if (!(this instanceof WriteStream2))\n return new WriteStream2(path, options);\n if (!options)\n @throwTypeError(\"Expected options to be an object\");\n var {\n fs: fs2 = defaultWriteStreamOptions.fs,\n start = defaultWriteStreamOptions.start,\n flags = defaultWriteStreamOptions.flags,\n mode = defaultWriteStreamOptions.mode,\n autoClose = !0,\n emitClose = !1,\n autoDestroy = autoClose,\n encoding = defaultWriteStreamOptions.encoding,\n fd = defaultWriteStreamOptions.fd,\n pos = defaultWriteStreamOptions.pos\n } = options, tempThis = {};\n if (fd != null) {\n if (typeof fd !== \"number\")\n throw new Error(\"Expected options.fd to be a number\");\n tempThis.fd = fd, tempThis[_writeStreamPathFastPathSymbol] = !1;\n } else if (typeof path === \"string\") {\n if (path.length === 0)\n @throwTypeError(\"Expected a non-empty path\");\n if (path.startsWith(\"file:\"))\n path = Bun.fileURLToPath(path);\n tempThis.path = path, tempThis.fd = null, tempThis[_writeStreamPathFastPathSymbol] = autoClose && (start === @undefined || start === 0) && fs2.write === defaultWriteStreamOptions.fs.write && fs2.close === defaultWriteStreamOptions.fs.close;\n }\n if (tempThis.fd == null)\n tempThis.fd = fs2.openSync(path, flags, mode);\n if (NativeWritable.call(this, tempThis.fd, {\n ...options,\n decodeStrings: !1,\n autoDestroy,\n emitClose,\n fd: tempThis\n }), Object.assign(this, tempThis), typeof fs2\?.write !== \"function\")\n @throwTypeError(\"Expected fs.write to be a function\");\n if (typeof fs2\?.close !== \"function\")\n @throwTypeError(\"Expected fs.close to be a function\");\n if (typeof fs2\?.open !== \"function\")\n @throwTypeError(\"Expected fs.open to be a function\");\n if (typeof path === \"object\" && path) {\n if (path instanceof URL)\n path = Bun.fileURLToPath(path);\n }\n if (typeof path !== \"string\" && typeof fd !== \"number\")\n @throwTypeError(\"Expected a path or file descriptor\");\n if (this.start = start, this[_fs] = fs2, this.flags = flags, this.mode = mode, this.bytesWritten = 0, this[writeStreamSymbol] = !0, this[kIoDone] = !1, this.start !== @undefined)\n this.pos = this.start;\n if (encoding !== defaultWriteStreamOptions.encoding) {\n if (this.setDefaultEncoding(encoding), encoding !== \"buffer\" && encoding !== \"utf8\" && encoding !== \"utf-8\" && encoding !== \"binary\")\n this[_writeStreamPathFastPathSymbol] = !1;\n }\n return this;\n}, NativeWritable = Stream.NativeWritable, WriteStreamPrototype = WriteStream.prototype = Object.create(NativeWritable.prototype);\nObject.defineProperties(WriteStreamPrototype, {\n autoClose: {\n get() {\n return this._writableState.autoDestroy;\n },\n set(val) {\n this._writableState.autoDestroy = val;\n }\n },\n pending: {\n get() {\n return this.fd === null;\n }\n }\n});\nWriteStreamPrototype.destroySoon = WriteStreamPrototype.end;\nWriteStreamPrototype.open = function open3() {\n};\nWriteStreamPrototype[writeStreamPathFastPathCallSymbol] = function WriteStreamPathFastPathCallSymbol(readStream, pipeOpts) {\n if (!this[_writeStreamPathFastPathSymbol])\n return !1;\n if (this.fd !== null)\n return this[_writeStreamPathFastPathSymbol] = !1, !1;\n return this[kIoDone] = !1, readStream[kIoDone] = !1, Bun.write(this[_writeStreamPathFastPathSymbol], readStream[readStreamPathOrFdSymbol]).then((bytesWritten) => {\n readStream[kIoDone] = this[kIoDone] = !0, this.bytesWritten += bytesWritten, readStream.bytesRead += bytesWritten, this.end(), readStream.close();\n }, (err) => {\n readStream[kIoDone] = this[kIoDone] = !0, WriteStream_errorOrDestroy.call(this, err), readStream.emit(\"error\", err);\n });\n};\nWriteStreamPrototype.isBunFastPathEnabled = function isBunFastPathEnabled() {\n return this[_writeStreamPathFastPathSymbol];\n};\nWriteStreamPrototype.disableBunFastPath = function disableBunFastPath() {\n this[_writeStreamPathFastPathSymbol] = !1;\n};\nWriteStreamPrototype._construct = function _construct(callback) {\n if (typeof this.fd === \"number\") {\n callback();\n return;\n }\n callback(), this.emit(\"open\", this.fd), this.emit(\"ready\");\n};\nWriteStreamPrototype._destroy = function _destroy(err, cb) {\n if (this.fd === null)\n return cb(err);\n if (this[kIoDone]) {\n this.once(kIoDone, () => WriteStream_internalClose.call(this, err, cb));\n return;\n }\n WriteStream_internalClose.call(this, err, cb);\n};\nWriteStreamPrototype.close = function close3(cb) {\n if (cb) {\n if (this.closed) {\n process.nextTick(cb);\n return;\n }\n this.on(\"close\", cb);\n }\n if (!this.autoClose)\n this.on(\"finish\", this.destroy);\n this.end();\n};\nWriteStreamPrototype.write = function write3(chunk, encoding, cb) {\n if (encoding \?\?= this._writableState\?.defaultEncoding, this[_writeStreamPathFastPathSymbol] = !1, typeof chunk === \"string\")\n chunk = @Buffer.from(chunk, encoding);\n var native = this.pos === @undefined;\n const callback = native \? (err, bytes) => {\n if (this[kIoDone] = !1, WriteStream_handleWrite.call(this, err, bytes), this.emit(kIoDone), cb)\n !err \? cb() : cb(err);\n } : () => {\n };\n if (this[kIoDone] = !0, this._write)\n return this._write(chunk, encoding, callback);\n else\n return NativeWritable.prototype.write.call(this, chunk, encoding, callback, native);\n};\nWriteStreamPrototype._write = @undefined;\nWriteStreamPrototype._writev = @undefined;\nWriteStreamPrototype.end = function end(chunk, encoding, cb) {\n var native = this.pos === @undefined;\n return NativeWritable.prototype.end.call(this, chunk, encoding, cb, native);\n};\nWriteStreamPrototype._destroy = function _destroy2(err, cb) {\n this.close(err, cb);\n};\nObject.defineProperties(fs, {\n createReadStream: {\n value: createReadStream\n },\n createWriteStream: {\n value: createWriteStream\n },\n ReadStream: {\n value: ReadStream\n },\n WriteStream: {\n value: WriteStream\n }\n});\nrealpath.native = realpath;\nrealpathSync.native = realpathSync;\nvar lazy_cpSync = null;\n$ = {\n Dirent,\n FSWatcher,\n ReadStream,\n Stats,\n WriteStream,\n _toUnixTimestamp,\n access,\n accessSync,\n appendFile,\n appendFileSync,\n chmod,\n chmodSync,\n chown,\n chownSync,\n close,\n closeSync,\n constants,\n copyFile,\n copyFileSync,\n cp,\n cpSync,\n createReadStream,\n createWriteStream,\n exists,\n existsSync,\n fchmod,\n fchmodSync,\n fchown,\n fchownSync,\n fstat,\n fstatSync,\n fsync,\n fsyncSync,\n ftruncate,\n ftruncateSync,\n futimes,\n futimesSync,\n lchmod,\n lchmodSync,\n lchown,\n lchownSync,\n link,\n linkSync,\n lstat,\n lstatSync,\n lutimes,\n lutimesSync,\n mkdir,\n mkdirSync,\n mkdtemp,\n mkdtempSync,\n open,\n openSync,\n promises,\n read,\n readFile,\n readFileSync,\n readSync,\n readdir,\n readdirSync,\n readlink,\n readlinkSync,\n readv,\n readvSync,\n realpath,\n realpathSync,\n rename,\n renameSync,\n rm,\n rmSync,\n rmdir,\n rmdirSync,\n stat,\n statSync,\n symlink,\n symlinkSync,\n truncate,\n truncateSync,\n unlink,\n unlinkSync,\n unwatchFile,\n utimes,\n utimesSync,\n watch,\n watchFile,\n write,\n writeFile,\n writeFileSync,\n writeSync,\n writev,\n writevSync,\n [Symbol.for(\"::bunternal::\")]: {\n ReadStreamClass,\n WriteStreamClass\n }\n};\nreturn $})\n"_s; // // -static constexpr ASCIILiteral NodeFSPromisesCode = "(function (){\"use strict\";// src/js/out/tmp/node/fs.promises.ts\nvar watch = function(filename, options = {}) {\n if (filename instanceof URL)\n @throwTypeError(\"Watch URLs are not supported yet\");\n else if (@Buffer.isBuffer(filename))\n filename = filename.toString();\n else if (typeof filename !== \"string\")\n @throwTypeError(\"Expected path to be a string or Buffer\");\n let nextEventResolve = null;\n if (typeof options === \"string\")\n options = { encoding: options };\n const queue = @createFIFO(), watcher = fs.watch(filename, options || {}, (eventType, filename2) => {\n if (queue.push({ eventType, filename: filename2 }), nextEventResolve) {\n const resolve = nextEventResolve;\n nextEventResolve = null, resolve();\n }\n });\n return {\n [Symbol.asyncIterator]() {\n let closed = !1;\n return {\n async next() {\n while (!closed) {\n let event;\n while (event = queue.shift()) {\n if (event.eventType === \"close\")\n return closed = !0, { value: @undefined, done: !0 };\n if (event.eventType === \"error\")\n throw closed = !0, event.filename;\n return { value: event, done: !1 };\n }\n const { promise, resolve } = @Promise.withResolvers();\n nextEventResolve = resolve, await promise;\n }\n return { value: @undefined, done: !0 };\n },\n return() {\n if (!closed) {\n if (watcher.close(), closed = !0, nextEventResolve) {\n const resolve = nextEventResolve;\n nextEventResolve = null, resolve();\n }\n }\n return { value: @undefined, done: !0 };\n }\n };\n }\n };\n}, cp = function(src, dest, options) {\n if (!options)\n return fs.cp(src, dest);\n if (typeof options !== \"object\")\n @throwTypeError(\"options must be an object\");\n if (options.dereference || options.filter || options.preserveTimestamps || options.verbatimSymlinks) {\n if (!lazy_cp)\n lazy_cp = @getInternalField(@internalModuleRegistry, 3) || @createInternalModuleById(3);\n return lazy_cp(src, dest, options);\n }\n return fs.cp(src, dest, options.recursive, options.errorOnExist, options.force \?\? !0, options.mode);\n};\nasync function opendir(dir) {\n const entries = await fs.readdir(dir, { withFileTypes: !0 });\n return new Dir(entries);\n}\nvar $, constants = @processBindingConstants.fs, fs = Bun.fs(), notrace = \"::bunternal::\", promisify = {\n [notrace]: (fsFunction) => {\n return async function(...args) {\n return await 1, fsFunction.apply(fs, args);\n };\n }\n}[notrace], lazy_cp = null;\n\nclass Dir {\n #entries;\n constructor(e) {\n this.#entries = e;\n }\n readSync() {\n return this.#entries.shift() \?\? null;\n }\n read(c) {\n if (c)\n process.nextTick(c, null, this.readSync());\n return @Promise.resolve(this.readSync());\n }\n closeSync() {\n }\n close(c) {\n if (c)\n process.nextTick(c);\n return @Promise.resolve();\n }\n *[Symbol.asyncIterator]() {\n var next;\n while (next = this.readSync())\n yield next;\n }\n}\n$ = {\n access: promisify(fs.accessSync),\n appendFile: promisify(fs.appendFileSync),\n close: promisify(fs.closeSync),\n copyFile: fs.copyFile.bind(fs),\n cp,\n exists: promisify(fs.existsSync),\n chown: promisify(fs.chownSync),\n chmod: promisify(fs.chmodSync),\n fchmod: promisify(fs.fchmodSync),\n fchown: promisify(fs.fchownSync),\n fstat: promisify(fs.fstatSync),\n fsync: promisify(fs.fsyncSync),\n ftruncate: promisify(fs.ftruncateSync),\n futimes: promisify(fs.futimesSync),\n lchmod: promisify(fs.lchmodSync),\n lchown: promisify(fs.lchownSync),\n link: promisify(fs.linkSync),\n lstat: fs.lstat.bind(fs),\n mkdir: promisify(fs.mkdirSync),\n mkdtemp: promisify(fs.mkdtempSync),\n open: promisify(fs.openSync),\n read: promisify(fs.readSync),\n write: promisify(fs.writeSync),\n readdir: fs.readdir.bind(fs),\n readFile: fs.readFile.bind(fs),\n writeFile: promisify(fs.writeFileSync),\n readlink: promisify(fs.readlinkSync),\n realpath: fs.realpath.bind(fs),\n rename: promisify(fs.renameSync),\n stat: fs.stat.bind(fs),\n symlink: promisify(fs.symlinkSync),\n truncate: promisify(fs.truncateSync),\n unlink: promisify(fs.unlinkSync),\n utimes: promisify(fs.utimesSync),\n lutimes: promisify(fs.lutimesSync),\n rm: promisify(fs.rmSync),\n rmdir: promisify(fs.rmdirSync),\n writev: (fd, buffers, position) => {\n return new @Promise((resolve, reject) => {\n try {\n var bytesWritten = fs.writevSync(fd, buffers, position);\n } catch (err) {\n reject(err);\n return;\n }\n resolve({\n bytesWritten,\n buffers\n });\n });\n },\n readv: (fd, buffers, position) => {\n return new @Promise((resolve, reject) => {\n try {\n var bytesRead = fs.readvSync(fd, buffers, position);\n } catch (err) {\n reject(err);\n return;\n }\n resolve({\n bytesRead,\n buffers\n });\n });\n },\n constants,\n watch,\n opendir\n};\nreturn $})\n"_s; +static constexpr ASCIILiteral NodeFSPromisesCode = "(function (){\"use strict\";// src/js/out/tmp/node/fs.promises.ts\nvar watch = function(filename, options = {}) {\n if (filename instanceof URL)\n @throwTypeError(\"Watch URLs are not supported yet\");\n else if (@Buffer.isBuffer(filename))\n filename = filename.toString();\n else if (typeof filename !== \"string\")\n @throwTypeError(\"Expected path to be a string or Buffer\");\n let nextEventResolve = null;\n if (typeof options === \"string\")\n options = { encoding: options };\n const queue = @createFIFO(), watcher = fs.watch(filename, options || {}, (eventType, filename2) => {\n if (queue.push({ eventType, filename: filename2 }), nextEventResolve) {\n const resolve = nextEventResolve;\n nextEventResolve = null, resolve();\n }\n });\n return {\n [Symbol.asyncIterator]() {\n let closed = !1;\n return {\n async next() {\n while (!closed) {\n let event;\n while (event = queue.shift()) {\n if (event.eventType === \"close\")\n return closed = !0, { value: @undefined, done: !0 };\n if (event.eventType === \"error\")\n throw closed = !0, event.filename;\n return { value: event, done: !1 };\n }\n const { promise, resolve } = @Promise.withResolvers();\n nextEventResolve = resolve, await promise;\n }\n return { value: @undefined, done: !0 };\n },\n return() {\n if (!closed) {\n if (watcher.close(), closed = !0, nextEventResolve) {\n const resolve = nextEventResolve;\n nextEventResolve = null, resolve();\n }\n }\n return { value: @undefined, done: !0 };\n }\n };\n }\n };\n}, cp = function(src, dest, options) {\n if (!options)\n return fs.cp(src, dest);\n if (typeof options !== \"object\")\n @throwTypeError(\"options must be an object\");\n if (options.dereference || options.filter || options.preserveTimestamps || options.verbatimSymlinks) {\n if (!lazy_cp)\n lazy_cp = @getInternalField(@internalModuleRegistry, 3) || @createInternalModuleById(3);\n return lazy_cp(src, dest, options);\n }\n return fs.cp(src, dest, options.recursive, options.errorOnExist, options.force \?\? !0, options.mode);\n};\nasync function opendir(dir) {\n const entries = await fs.readdir(dir, { withFileTypes: !0 });\n return new Dir(entries);\n}\nvar $, constants = @processBindingConstants.fs, fs = Bun.fs();\nvar lazy_cp = null;\n\nclass Dir {\n #entries;\n constructor(e) {\n this.#entries = e;\n }\n readSync() {\n return this.#entries.shift() \?\? null;\n }\n read(c) {\n if (c)\n process.nextTick(c, null, this.readSync());\n return @Promise.resolve(this.readSync());\n }\n closeSync() {\n }\n close(c) {\n if (c)\n process.nextTick(c);\n return @Promise.resolve();\n }\n *[Symbol.asyncIterator]() {\n var next;\n while (next = this.readSync())\n yield next;\n }\n}\n$ = {\n access: fs.access.bind(fs),\n appendFile: fs.appendFile.bind(fs),\n close: fs.close.bind(fs),\n copyFile: fs.copyFile.bind(fs),\n cp,\n exists: fs.exists.bind(fs),\n chown: fs.chown.bind(fs),\n chmod: fs.chmod.bind(fs),\n fchmod: fs.fchmod.bind(fs),\n fchown: fs.fchown.bind(fs),\n fstat: fs.fstat.bind(fs),\n fsync: fs.fsync.bind(fs),\n ftruncate: fs.ftruncate.bind(fs),\n futimes: fs.futimes.bind(fs),\n lchmod: fs.lchmod.bind(fs),\n lchown: fs.lchown.bind(fs),\n link: fs.link.bind(fs),\n lstat: fs.lstat.bind(fs),\n mkdir: fs.mkdir.bind(fs),\n mkdtemp: fs.mkdtemp.bind(fs),\n open: fs.open.bind(fs),\n read: fs.read.bind(fs),\n write: fs.write.bind(fs),\n readdir: fs.readdir.bind(fs),\n readFile: fs.readFile.bind(fs),\n writeFile: fs.writeFile.bind(fs),\n readlink: fs.readlink.bind(fs),\n realpath: fs.realpath.bind(fs),\n rename: fs.rename.bind(fs),\n stat: fs.stat.bind(fs),\n symlink: fs.symlink.bind(fs),\n truncate: fs.truncate.bind(fs),\n unlink: fs.unlink.bind(fs),\n utimes: fs.utimes.bind(fs),\n lutimes: fs.lutimes.bind(fs),\n rm: fs.rm.bind(fs),\n rmdir: fs.rmdir.bind(fs),\n writev: async (fd, buffers, position) => {\n var bytesWritten = await fs.writev(fd, buffers, position);\n return {\n bytesWritten,\n buffers\n };\n },\n readv: async (fd, buffers, position) => {\n var bytesRead = await fs.readv(fd, buffers, position);\n return {\n bytesRead,\n buffers\n };\n },\n constants,\n watch,\n opendir\n};\nreturn $})\n"_s; // // @@ -323,11 +323,11 @@ static constexpr ASCIILiteral NodeEventsCode = "(function (){\"use strict\";// s // // -static constexpr ASCIILiteral NodeFSCode = "(function (){\"use strict\";// src/js/out/tmp/node/fs.ts\nvar getValidatedPath = function(p) {\n if (p instanceof URL)\n return Bun.fileURLToPath(p);\n if (typeof p !== \"string\")\n @throwTypeError(\"Path must be a string or URL.\");\n return (_pathModule \?\?= @getInternalField(@internalModuleRegistry, 28) || @createInternalModuleById(28)).resolve(p);\n}, watchFile = function(filename, options, listener) {\n if (filename = getValidatedPath(filename), typeof options === \"function\")\n listener = options, options = {};\n if (typeof listener !== \"function\")\n @throwTypeError(\"listener must be a function\");\n var stat = statWatchers.get(filename);\n if (!stat)\n stat = new StatWatcher(filename, options), statWatchers.set(filename, stat);\n return stat.addListener(\"change\", listener), stat;\n}, unwatchFile = function(filename, listener) {\n filename = getValidatedPath(filename);\n var stat = statWatchers.get(filename);\n if (!stat)\n return;\n if (listener) {\n if (stat.removeListener(\"change\", listener), stat.listenerCount(\"change\") !== 0)\n return;\n } else\n stat.removeAllListeners(\"change\");\n stat.stop(), statWatchers.delete(filename);\n}, callbackify = function(fsFunction, args) {\n try {\n const result = fsFunction.apply(fs, args.slice(0, args.length - 1)), callback = args[args.length - 1];\n if (typeof callback === \"function\")\n queueMicrotask(() => callback(null, result));\n } catch (e) {\n const callback = args[args.length - 1];\n if (typeof callback === \"function\")\n queueMicrotask(() => callback(e));\n }\n}, createReadStream = function(path, options) {\n return new ReadStream(path, options);\n}, WriteStream_handleWrite = function(er, bytes) {\n if (er)\n return WriteStream_errorOrDestroy.call(this, er);\n this.bytesWritten += bytes;\n}, WriteStream_internalClose = function(err, cb) {\n this[_writeStreamPathFastPathSymbol] = !1;\n var fd = this.fd;\n this[_fs].close(fd, (er) => {\n this.fd = null, cb(err || er);\n });\n}, WriteStream_errorOrDestroy = function(err) {\n var {\n _readableState: r = { destroyed: !1, autoDestroy: !1 },\n _writableState: w = { destroyed: !1, autoDestroy: !1 }\n } = this;\n if (w\?.destroyed || r\?.destroyed)\n return this;\n if (r\?.autoDestroy || w\?.autoDestroy)\n this.destroy(err);\n else if (err)\n this.emit(\"error\", err);\n}, createWriteStream = function(path, options) {\n return new WriteStream(path, options);\n}, cpSync = function(src, dest, options) {\n if (!options)\n return fs.cpSync(src, dest);\n if (typeof options !== \"object\")\n @throwTypeError(\"options must be an object\");\n if (options.dereference || options.filter || options.preserveTimestamps || options.verbatimSymlinks) {\n if (!lazy_cpSync)\n lazy_cpSync = @getInternalField(@internalModuleRegistry, 3) || @createInternalModuleById(3);\n return lazy_cpSync(src, dest, options);\n }\n return fs.cpSync(src, dest, options.recursive, options.errorOnExist, options.force \?\? !0, options.mode);\n}, cp = function(src, dest, options, callback) {\n if (typeof options === \"function\")\n callback = options, options = @undefined;\n promises.cp(src, dest, options).then(() => callback(), callback);\n}, _toUnixTimestamp = function(time, name = \"time\") {\n if (typeof time === \"string\" && +time == time)\n return +time;\n if (NumberIsFinite(time)) {\n if (time < 0)\n return DateNow() / 1000;\n return time;\n }\n if (isDate(time))\n return DatePrototypeGetTime(time) / 1000;\n @throwTypeError(`Expected ${name} to be a number or Date`);\n}, $, ReadStream, WriteStream, EventEmitter = @getInternalField(@internalModuleRegistry, 18) || @createInternalModuleById(18), promises = @getInternalField(@internalModuleRegistry, 20) || @createInternalModuleById(20), Stream = @getInternalField(@internalModuleRegistry, 37) || @createInternalModuleById(37), { isArrayBufferView } = @requireNativeModule(\"util/types\"), _writeStreamPathFastPathSymbol = Symbol.for(\"Bun.NodeWriteStreamFastPath\"), _fs = Symbol.for(\"#fs\"), constants = @processBindingConstants.fs, fs = Bun.fs();\n\nclass FSWatcher extends EventEmitter {\n #watcher;\n #listener;\n constructor(path, options, listener) {\n super();\n if (typeof options === \"function\")\n listener = options, options = {};\n else if (typeof options === \"string\")\n options = { encoding: options };\n if (typeof listener !== \"function\")\n listener = () => {\n };\n this.#listener = listener;\n try {\n this.#watcher = fs.watch(path, options || {}, this.#onEvent.bind(this));\n } catch (e) {\n if (!e.message\?.startsWith(\"FileNotFound\"))\n throw e;\n const notFound = new Error(`ENOENT: no such file or directory, watch '${path}'`);\n throw notFound.code = \"ENOENT\", notFound.errno = -2, notFound.path = path, notFound.syscall = \"watch\", notFound.filename = path, notFound;\n }\n }\n #onEvent(eventType, filenameOrError) {\n if (eventType === \"error\" || eventType === \"close\")\n this.emit(eventType, filenameOrError);\n else\n this.emit(\"change\", eventType, filenameOrError), this.#listener(eventType, filenameOrError);\n }\n close() {\n this.#watcher\?.close(), this.#watcher = null;\n }\n ref() {\n this.#watcher\?.ref();\n }\n unref() {\n this.#watcher\?.unref();\n }\n start() {\n }\n}\n\nclass StatWatcher extends EventEmitter {\n constructor(path, options) {\n super();\n this._handle = fs.watchFile(path, options, this.#onChange.bind(this));\n }\n #onChange(curr, prev) {\n this.emit(\"change\", curr, prev);\n }\n start() {\n }\n stop() {\n this._handle\?.close(), this._handle = null;\n }\n ref() {\n this._handle\?.ref();\n }\n unref() {\n this._handle\?.unref();\n }\n}\nvar access = function access2(...args) {\n callbackify(fs.accessSync, args);\n}, appendFile = function appendFile2(...args) {\n callbackify(fs.appendFileSync, args);\n}, close = function close2(...args) {\n callbackify(fs.closeSync, args);\n}, rm = function rm2(...args) {\n callbackify(fs.rmSync, args);\n}, rmdir = function rmdir2(...args) {\n callbackify(fs.rmdirSync, args);\n}, copyFile = function copyFile2(...args) {\n const callback = args[args.length - 1];\n if (typeof callback !== \"function\")\n @throwTypeError(\"Callback must be a function\");\n fs.copyFile(...args).then((result) => callback(null, result), callback);\n}, exists = function exists2(...args) {\n callbackify(fs.existsSync, args);\n}, chown = function chown2(...args) {\n callbackify(fs.chownSync, args);\n}, chmod = function chmod2(...args) {\n callbackify(fs.chmodSync, args);\n}, fchmod = function fchmod2(...args) {\n callbackify(fs.fchmodSync, args);\n}, fchown = function fchown2(...args) {\n callbackify(fs.fchownSync, args);\n}, fstat = function fstat2(...args) {\n callbackify(fs.fstatSync, args);\n}, fsync = function fsync2(...args) {\n callbackify(fs.fsyncSync, args);\n}, ftruncate = function ftruncate2(...args) {\n callbackify(fs.ftruncateSync, args);\n}, futimes = function futimes2(...args) {\n callbackify(fs.futimesSync, args);\n}, lchmod = function lchmod2(...args) {\n callbackify(fs.lchmodSync, args);\n}, lchown = function lchown2(...args) {\n callbackify(fs.lchownSync, args);\n}, link = function link2(...args) {\n callbackify(fs.linkSync, args);\n}, mkdir = function mkdir2(...args) {\n callbackify(fs.mkdirSync, args);\n}, mkdtemp = function mkdtemp2(...args) {\n callbackify(fs.mkdtempSync, args);\n}, open = function open2(...args) {\n callbackify(fs.openSync, args);\n}, read = function read2(fd, buffer, offsetOrOptions, length, position, callback) {\n let offset = offsetOrOptions, params = null;\n if (arguments.length <= 4) {\n if (arguments.length === 4)\n callback = length, params = offsetOrOptions;\n else if (arguments.length === 3) {\n if (!isArrayBufferView(buffer))\n params = buffer, { buffer = @Buffer.alloc(16384) } = params \?\? {};\n callback = offsetOrOptions;\n } else\n callback = buffer, buffer = @Buffer.alloc(16384);\n ({ offset = 0, length = buffer\?.byteLength - offset, position = null } = params \?\? {});\n }\n queueMicrotask(() => {\n try {\n var bytesRead = fs.readSync(fd, buffer, offset, length, position);\n } catch (e) {\n callback(e);\n }\n callback(null, bytesRead, buffer);\n });\n}, write = function write2(...args) {\n callbackify(fs.writeSync, args);\n}, readdir = function readdir2(...args) {\n const callback = args[args.length - 1];\n if (typeof callback !== \"function\")\n @throwTypeError(\"Callback must be a function\");\n fs.readdir(...args).then((result) => callback(null, result), callback);\n}, readFile = function readFile2(...args) {\n const callback = args[args.length - 1];\n if (typeof callback !== \"function\")\n @throwTypeError(\"Callback must be a function\");\n fs.readFile(...args).then((result) => callback(null, result), callback);\n}, writeFile = function writeFile2(...args) {\n callbackify(fs.writeFileSync, args);\n}, readlink = function readlink2(...args) {\n callbackify(fs.readlinkSync, args);\n}, realpath = function realpath2(...args) {\n const callback = args[args.length - 1];\n if (typeof callback !== \"function\")\n @throwTypeError(\"Callback must be a function\");\n fs.realpath(...args).then((result) => callback(null, result), callback);\n}, rename = function rename2(...args) {\n callbackify(fs.renameSync, args);\n}, lstat = function lstat2(...args) {\n const callback = args[args.length - 1];\n if (typeof callback !== \"function\")\n @throwTypeError(\"Callback must be a function\");\n fs.lstat(...args).then((result) => callback(null, result), callback);\n}, stat = function stat2(...args) {\n const callback = args[args.length - 1];\n if (typeof callback !== \"function\")\n @throwTypeError(\"Callback must be a function\");\n fs.stat(...args).then((result) => callback(null, result), callback);\n}, symlink = function symlink2(...args) {\n callbackify(fs.symlinkSync, args);\n}, truncate = function truncate2(...args) {\n callbackify(fs.truncateSync, args);\n}, unlink = function unlink2(...args) {\n callbackify(fs.unlinkSync, args);\n}, utimes = function utimes2(...args) {\n callbackify(fs.utimesSync, args);\n}, lutimes = function lutimes2(...args) {\n callbackify(fs.lutimesSync, args);\n}, accessSync = fs.accessSync.bind(fs), appendFileSync = fs.appendFileSync.bind(fs), closeSync = fs.closeSync.bind(fs), copyFileSync = fs.copyFileSync.bind(fs), existsSync = fs.existsSync.bind(fs), chownSync = fs.chownSync.bind(fs), chmodSync = fs.chmodSync.bind(fs), fchmodSync = fs.fchmodSync.bind(fs), fchownSync = fs.fchownSync.bind(fs), fstatSync = fs.fstatSync.bind(fs), fsyncSync = fs.fsyncSync.bind(fs), ftruncateSync = fs.ftruncateSync.bind(fs), futimesSync = fs.futimesSync.bind(fs), lchmodSync = fs.lchmodSync.bind(fs), lchownSync = fs.lchownSync.bind(fs), linkSync = fs.linkSync.bind(fs), lstatSync = fs.lstatSync.bind(fs), mkdirSync = fs.mkdirSync.bind(fs), mkdtempSync = fs.mkdtempSync.bind(fs), openSync = fs.openSync.bind(fs), readSync = fs.readSync.bind(fs), writeSync = fs.writeSync.bind(fs), readdirSync = fs.readdirSync.bind(fs), readFileSync = fs.readFileSync.bind(fs), writeFileSync = fs.writeFileSync.bind(fs), readlinkSync = fs.readlinkSync.bind(fs), realpathSync = fs.realpathSync.bind(fs), renameSync = fs.renameSync.bind(fs), statSync = fs.statSync.bind(fs), symlinkSync = fs.symlinkSync.bind(fs), truncateSync = fs.truncateSync.bind(fs), unlinkSync = fs.unlinkSync.bind(fs), utimesSync = fs.utimesSync.bind(fs), lutimesSync = fs.lutimesSync.bind(fs), rmSync = fs.rmSync.bind(fs), rmdirSync = fs.rmdirSync.bind(fs), writev = (fd, buffers, position, callback) => {\n if (typeof position === \"function\")\n callback = position, position = null;\n queueMicrotask(() => {\n try {\n var written = fs.writevSync(fd, buffers, position);\n } catch (e) {\n callback(e);\n }\n callback(null, written, buffers);\n });\n}, writevSync = fs.writevSync.bind(fs), readv = (fd, buffers, position, callback) => {\n if (typeof position === \"function\")\n callback = position, position = null;\n queueMicrotask(() => {\n try {\n var written = fs.readvSync(fd, buffers, position);\n } catch (e) {\n callback(e);\n }\n callback(null, written, buffers);\n });\n}, readvSync = fs.readvSync.bind(fs), Dirent = fs.Dirent, Stats = fs.Stats, watch = function watch2(path, options, listener) {\n return new FSWatcher(path, options, listener);\n}, statWatchers = new Map, _pathModule, readStreamPathFastPathSymbol = Symbol.for(\"Bun.Node.readStreamPathFastPath\"), readStreamSymbol = Symbol.for(\"Bun.NodeReadStream\"), readStreamPathOrFdSymbol = Symbol.for(\"Bun.NodeReadStreamPathOrFd\"), writeStreamSymbol = Symbol.for(\"Bun.NodeWriteStream\"), writeStreamPathFastPathSymbol = Symbol.for(\"Bun.NodeWriteStreamFastPath\"), writeStreamPathFastPathCallSymbol = Symbol.for(\"Bun.NodeWriteStreamFastPathCall\"), kIoDone = Symbol.for(\"kIoDone\"), defaultReadStreamOptions = {\n file: @undefined,\n fd: null,\n flags: \"r\",\n encoding: @undefined,\n mode: 438,\n autoClose: !0,\n emitClose: !0,\n start: 0,\n end: @Infinity,\n highWaterMark: 65536,\n fs: {\n read,\n open: (path, flags, mode, cb) => {\n var fd;\n try {\n fd = openSync(path, flags, mode);\n } catch (e) {\n cb(e);\n return;\n }\n cb(null, fd);\n },\n openSync,\n close\n },\n autoDestroy: !0\n}, ReadStreamClass;\nReadStream = function(InternalReadStream) {\n ReadStreamClass = InternalReadStream, Object.defineProperty(ReadStreamClass.prototype, Symbol.toStringTag, {\n value: \"ReadStream\",\n enumerable: !1\n });\n function ReadStream3(path, options) {\n return new InternalReadStream(path, options);\n }\n return ReadStream3.prototype = InternalReadStream.prototype, Object.defineProperty(ReadStream3, Symbol.hasInstance, {\n value(instance) {\n return instance instanceof InternalReadStream;\n }\n });\n}(class ReadStream2 extends Stream._getNativeReadableStreamPrototype(2, Stream.Readable) {\n constructor(pathOrFd, options = defaultReadStreamOptions) {\n if (typeof options !== \"object\" || !options)\n @throwTypeError(\"Expected options to be an object\");\n var {\n flags = defaultReadStreamOptions.flags,\n encoding = defaultReadStreamOptions.encoding,\n mode = defaultReadStreamOptions.mode,\n autoClose = defaultReadStreamOptions.autoClose,\n emitClose = defaultReadStreamOptions.emitClose,\n start = defaultReadStreamOptions.start,\n end = defaultReadStreamOptions.end,\n autoDestroy = defaultReadStreamOptions.autoClose,\n fs: fs2 = defaultReadStreamOptions.fs,\n highWaterMark = defaultReadStreamOptions.highWaterMark,\n fd = defaultReadStreamOptions.fd\n } = options;\n if (pathOrFd\?.constructor\?.name === \"URL\")\n pathOrFd = Bun.fileURLToPath(pathOrFd);\n var tempThis = {};\n if (fd != null) {\n if (typeof fd !== \"number\")\n @throwTypeError(\"Expected options.fd to be a number\");\n tempThis.fd = tempThis[readStreamPathOrFdSymbol] = fd, tempThis.autoClose = !1;\n } else if (typeof pathOrFd === \"string\") {\n if (pathOrFd.startsWith(\"file://\"))\n pathOrFd = Bun.fileURLToPath(pathOrFd);\n if (pathOrFd.length === 0)\n @throwTypeError(\"Expected path to be a non-empty string\");\n tempThis.path = tempThis.file = tempThis[readStreamPathOrFdSymbol] = pathOrFd;\n } else if (typeof pathOrFd === \"number\") {\n if (pathOrFd |= 0, pathOrFd < 0)\n @throwTypeError(\"Expected fd to be a positive integer\");\n tempThis.fd = tempThis[readStreamPathOrFdSymbol] = pathOrFd, tempThis.autoClose = !1;\n } else\n @throwTypeError(\"Expected a path or file descriptor\");\n if (tempThis.fd === @undefined)\n tempThis.fd = fs2.openSync(pathOrFd, flags, mode);\n var fileRef = Bun.file(tempThis.fd), stream = fileRef.stream(), native = @direct(stream);\n if (!native)\n throw new Error(\"no native readable stream\");\n var { stream: ptr } = native;\n super(ptr, {\n ...options,\n encoding,\n autoDestroy,\n autoClose,\n emitClose,\n highWaterMark\n });\n if (Object.assign(this, tempThis), this.#fileRef = fileRef, this.end = end, this._read = this.#internalRead, this.start = start, this.flags = flags, this.mode = mode, this.emitClose = emitClose, this[readStreamPathFastPathSymbol] = start === 0 && end === @Infinity && autoClose && fs2 === defaultReadStreamOptions.fs && (encoding === \"buffer\" || encoding === \"binary\" || encoding == null || encoding === \"utf-8\" || encoding === \"utf8\"), this._readableState.autoClose = autoDestroy = autoClose, this._readableState.highWaterMark = highWaterMark, start !== @undefined)\n this.pos = start;\n }\n #fileRef;\n #fs;\n file;\n path;\n fd = null;\n flags;\n mode;\n start;\n end;\n pos;\n bytesRead = 0;\n #fileSize = -1;\n _read;\n [readStreamSymbol] = !0;\n [readStreamPathOrFdSymbol];\n [readStreamPathFastPathSymbol];\n _construct(callback) {\n if (super._construct)\n super._construct(callback);\n else\n callback();\n this.emit(\"open\", this.fd), this.emit(\"ready\");\n }\n _destroy(err, cb) {\n super._destroy(err, cb);\n try {\n var fd = this.fd;\n if (this[readStreamPathFastPathSymbol] = !1, !fd)\n cb(err);\n else\n this.#fs.close(fd, (er) => {\n cb(er || err);\n }), this.fd = null;\n } catch (e) {\n throw e;\n }\n }\n close(cb) {\n if (typeof cb === \"function\")\n Stream.eos(this, cb);\n this.destroy();\n }\n push(chunk) {\n var bytesRead = chunk\?.length \?\? 0;\n if (bytesRead > 0) {\n this.bytesRead += bytesRead;\n var currPos = this.pos;\n if (currPos !== @undefined) {\n if (this.bytesRead < currPos)\n return !0;\n if (currPos === this.start) {\n var n = this.bytesRead - currPos;\n chunk = chunk.slice(-n);\n var [_, ...rest] = arguments;\n if (this.pos = this.bytesRead, this.end !== @undefined && this.bytesRead > this.end)\n chunk = chunk.slice(0, this.end - this.start + 1);\n return super.push(chunk, ...rest);\n }\n var end = this.end;\n if (end !== @undefined && this.bytesRead > end) {\n chunk = chunk.slice(0, end - currPos + 1);\n var [_, ...rest] = arguments;\n return this.pos = this.bytesRead, super.push(chunk, ...rest);\n }\n this.pos = this.bytesRead;\n }\n }\n return super.push(...arguments);\n }\n #internalRead(n) {\n var { pos, end, bytesRead, fd, encoding } = this;\n if (n = pos !== @undefined \? Math.min(end - pos + 1, n) : Math.min(end - bytesRead + 1, n), n <= 0) {\n this.push(null);\n return;\n }\n if (this.#fileSize === -1 && bytesRead === 0 && pos === @undefined) {\n var stat3 = fstatSync(fd);\n if (this.#fileSize = stat3.size, this.#fileSize > 0 && n > this.#fileSize)\n n = this.#fileSize + 1;\n }\n this[kIoDone] = !1;\n var res = super._read(n);\n if (@isPromise(res)) {\n var then = res\?.then;\n if (then && @isCallable(then))\n res.then(() => {\n if (this[kIoDone] = !0, this.destroyed)\n this.emit(kIoDone);\n }, (er) => {\n this[kIoDone] = !0, this.#errorOrDestroy(er);\n });\n } else if (this[kIoDone] = !0, this.destroyed)\n this.emit(kIoDone), this.#errorOrDestroy(new Error(\"ERR_STREAM_PREMATURE_CLOSE\"));\n }\n #errorOrDestroy(err, sync = null) {\n var {\n _readableState: r = { destroyed: !1, autoDestroy: !1 },\n _writableState: w = { destroyed: !1, autoDestroy: !1 }\n } = this;\n if (w\?.destroyed || r\?.destroyed)\n return this;\n if (r\?.autoDestroy || w\?.autoDestroy)\n this.destroy(err);\n else if (err)\n this.emit(\"error\", err);\n }\n pause() {\n return this[readStreamPathFastPathSymbol] = !1, super.pause();\n }\n resume() {\n return this[readStreamPathFastPathSymbol] = !1, super.resume();\n }\n unshift(...args) {\n return this[readStreamPathFastPathSymbol] = !1, super.unshift(...args);\n }\n pipe(dest, pipeOpts) {\n if (this[readStreamPathFastPathSymbol] && (pipeOpts\?.end \?\? !0) && this._readableState\?.pipes\?.length === 0) {\n if ((writeStreamPathFastPathSymbol in dest) && dest[writeStreamPathFastPathSymbol]) {\n if (dest[writeStreamPathFastPathCallSymbol](this, pipeOpts))\n return this;\n }\n }\n return this[readStreamPathFastPathSymbol] = !1, super.pipe(dest, pipeOpts);\n }\n});\nvar defaultWriteStreamOptions = {\n fd: null,\n start: @undefined,\n pos: @undefined,\n encoding: @undefined,\n flags: \"w\",\n mode: 438,\n fs: {\n write,\n close,\n open,\n openSync\n }\n}, WriteStreamClass = WriteStream = function WriteStream2(path, options = defaultWriteStreamOptions) {\n if (!(this instanceof WriteStream2))\n return new WriteStream2(path, options);\n if (!options)\n @throwTypeError(\"Expected options to be an object\");\n var {\n fs: fs2 = defaultWriteStreamOptions.fs,\n start = defaultWriteStreamOptions.start,\n flags = defaultWriteStreamOptions.flags,\n mode = defaultWriteStreamOptions.mode,\n autoClose = !0,\n emitClose = !1,\n autoDestroy = autoClose,\n encoding = defaultWriteStreamOptions.encoding,\n fd = defaultWriteStreamOptions.fd,\n pos = defaultWriteStreamOptions.pos\n } = options, tempThis = {};\n if (fd != null) {\n if (typeof fd !== \"number\")\n throw new Error(\"Expected options.fd to be a number\");\n tempThis.fd = fd, tempThis[_writeStreamPathFastPathSymbol] = !1;\n } else if (typeof path === \"string\") {\n if (path.length === 0)\n @throwTypeError(\"Expected a non-empty path\");\n if (path.startsWith(\"file:\"))\n path = Bun.fileURLToPath(path);\n tempThis.path = path, tempThis.fd = null, tempThis[_writeStreamPathFastPathSymbol] = autoClose && (start === @undefined || start === 0) && fs2.write === defaultWriteStreamOptions.fs.write && fs2.close === defaultWriteStreamOptions.fs.close;\n }\n if (tempThis.fd == null)\n tempThis.fd = fs2.openSync(path, flags, mode);\n if (NativeWritable.call(this, tempThis.fd, {\n ...options,\n decodeStrings: !1,\n autoDestroy,\n emitClose,\n fd: tempThis\n }), Object.assign(this, tempThis), typeof fs2\?.write !== \"function\")\n @throwTypeError(\"Expected fs.write to be a function\");\n if (typeof fs2\?.close !== \"function\")\n @throwTypeError(\"Expected fs.close to be a function\");\n if (typeof fs2\?.open !== \"function\")\n @throwTypeError(\"Expected fs.open to be a function\");\n if (typeof path === \"object\" && path) {\n if (path instanceof URL)\n path = Bun.fileURLToPath(path);\n }\n if (typeof path !== \"string\" && typeof fd !== \"number\")\n @throwTypeError(\"Expected a path or file descriptor\");\n if (this.start = start, this[_fs] = fs2, this.flags = flags, this.mode = mode, this.bytesWritten = 0, this[writeStreamSymbol] = !0, this[kIoDone] = !1, this.start !== @undefined)\n this.pos = this.start;\n if (encoding !== defaultWriteStreamOptions.encoding) {\n if (this.setDefaultEncoding(encoding), encoding !== \"buffer\" && encoding !== \"utf8\" && encoding !== \"utf-8\" && encoding !== \"binary\")\n this[_writeStreamPathFastPathSymbol] = !1;\n }\n return this;\n}, NativeWritable = Stream.NativeWritable, WriteStreamPrototype = WriteStream.prototype = Object.create(NativeWritable.prototype);\nObject.defineProperties(WriteStreamPrototype, {\n autoClose: {\n get() {\n return this._writableState.autoDestroy;\n },\n set(val) {\n this._writableState.autoDestroy = val;\n }\n },\n pending: {\n get() {\n return this.fd === null;\n }\n }\n});\nWriteStreamPrototype.destroySoon = WriteStreamPrototype.end;\nWriteStreamPrototype.open = function open3() {\n};\nWriteStreamPrototype[writeStreamPathFastPathCallSymbol] = function WriteStreamPathFastPathCallSymbol(readStream, pipeOpts) {\n if (!this[_writeStreamPathFastPathSymbol])\n return !1;\n if (this.fd !== null)\n return this[_writeStreamPathFastPathSymbol] = !1, !1;\n return this[kIoDone] = !1, readStream[kIoDone] = !1, Bun.write(this[_writeStreamPathFastPathSymbol], readStream[readStreamPathOrFdSymbol]).then((bytesWritten) => {\n readStream[kIoDone] = this[kIoDone] = !0, this.bytesWritten += bytesWritten, readStream.bytesRead += bytesWritten, this.end(), readStream.close();\n }, (err) => {\n readStream[kIoDone] = this[kIoDone] = !0, WriteStream_errorOrDestroy.call(this, err), readStream.emit(\"error\", err);\n });\n};\nWriteStreamPrototype.isBunFastPathEnabled = function isBunFastPathEnabled() {\n return this[_writeStreamPathFastPathSymbol];\n};\nWriteStreamPrototype.disableBunFastPath = function disableBunFastPath() {\n this[_writeStreamPathFastPathSymbol] = !1;\n};\nWriteStreamPrototype._construct = function _construct(callback) {\n if (typeof this.fd === \"number\") {\n callback();\n return;\n }\n callback(), this.emit(\"open\", this.fd), this.emit(\"ready\");\n};\nWriteStreamPrototype._destroy = function _destroy(err, cb) {\n if (this.fd === null)\n return cb(err);\n if (this[kIoDone]) {\n this.once(kIoDone, () => WriteStream_internalClose.call(this, err, cb));\n return;\n }\n WriteStream_internalClose.call(this, err, cb);\n};\nWriteStreamPrototype.close = function close3(cb) {\n if (cb) {\n if (this.closed) {\n process.nextTick(cb);\n return;\n }\n this.on(\"close\", cb);\n }\n if (!this.autoClose)\n this.on(\"finish\", this.destroy);\n this.end();\n};\nWriteStreamPrototype.write = function write3(chunk, encoding, cb) {\n if (encoding \?\?= this._writableState\?.defaultEncoding, this[_writeStreamPathFastPathSymbol] = !1, typeof chunk === \"string\")\n chunk = @Buffer.from(chunk, encoding);\n var native = this.pos === @undefined;\n const callback = native \? (err, bytes) => {\n if (this[kIoDone] = !1, WriteStream_handleWrite.call(this, err, bytes), this.emit(kIoDone), cb)\n !err \? cb() : cb(err);\n } : () => {\n };\n if (this[kIoDone] = !0, this._write)\n return this._write(chunk, encoding, callback);\n else\n return NativeWritable.prototype.write.call(this, chunk, encoding, callback, native);\n};\nWriteStreamPrototype._write = @undefined;\nWriteStreamPrototype._writev = @undefined;\nWriteStreamPrototype.end = function end(chunk, encoding, cb) {\n var native = this.pos === @undefined;\n return NativeWritable.prototype.end.call(this, chunk, encoding, cb, native);\n};\nWriteStreamPrototype._destroy = function _destroy2(err, cb) {\n this.close(err, cb);\n};\nObject.defineProperties(fs, {\n createReadStream: {\n value: createReadStream\n },\n createWriteStream: {\n value: createWriteStream\n },\n ReadStream: {\n value: ReadStream\n },\n WriteStream: {\n value: WriteStream\n }\n});\nrealpath.native = realpath;\nrealpathSync.native = realpathSync;\nvar lazy_cpSync = null;\n$ = {\n Dirent,\n FSWatcher,\n ReadStream,\n Stats,\n WriteStream,\n _toUnixTimestamp,\n access,\n accessSync,\n appendFile,\n appendFileSync,\n chmod,\n chmodSync,\n chown,\n chownSync,\n close,\n closeSync,\n constants,\n copyFile,\n copyFileSync,\n cp,\n cpSync,\n createReadStream,\n createWriteStream,\n exists,\n existsSync,\n fchmod,\n fchmodSync,\n fchown,\n fchownSync,\n fstat,\n fstatSync,\n fsync,\n fsyncSync,\n ftruncate,\n ftruncateSync,\n futimes,\n futimesSync,\n lchmod,\n lchmodSync,\n lchown,\n lchownSync,\n link,\n linkSync,\n lstat,\n lstatSync,\n lutimes,\n lutimesSync,\n mkdir,\n mkdirSync,\n mkdtemp,\n mkdtempSync,\n open,\n openSync,\n promises,\n read,\n readFile,\n readFileSync,\n readSync,\n readdir,\n readdirSync,\n readlink,\n readlinkSync,\n readv,\n readvSync,\n realpath,\n realpathSync,\n rename,\n renameSync,\n rm,\n rmSync,\n rmdir,\n rmdirSync,\n stat,\n statSync,\n symlink,\n symlinkSync,\n truncate,\n truncateSync,\n unlink,\n unlinkSync,\n unwatchFile,\n utimes,\n utimesSync,\n watch,\n watchFile,\n write,\n writeFile,\n writeFileSync,\n writeSync,\n writev,\n writevSync,\n [Symbol.for(\"::bunternal::\")]: {\n ReadStreamClass,\n WriteStreamClass\n }\n};\nreturn $})\n"_s; +static constexpr ASCIILiteral NodeFSCode = "(function (){\"use strict\";// src/js/out/tmp/node/fs.ts\nvar getValidatedPath = function(p) {\n if (p instanceof URL)\n return Bun.fileURLToPath(p);\n if (typeof p !== \"string\")\n @throwTypeError(\"Path must be a string or URL.\");\n return (_pathModule \?\?= @getInternalField(@internalModuleRegistry, 28) || @createInternalModuleById(28)).resolve(p);\n}, watchFile = function(filename, options, listener) {\n if (filename = getValidatedPath(filename), typeof options === \"function\")\n listener = options, options = {};\n if (typeof listener !== \"function\")\n @throwTypeError(\"listener must be a function\");\n var stat = statWatchers.get(filename);\n if (!stat)\n stat = new StatWatcher(filename, options), statWatchers.set(filename, stat);\n return stat.addListener(\"change\", listener), stat;\n}, unwatchFile = function(filename, listener) {\n filename = getValidatedPath(filename);\n var stat = statWatchers.get(filename);\n if (!stat)\n return;\n if (listener) {\n if (stat.removeListener(\"change\", listener), stat.listenerCount(\"change\") !== 0)\n return;\n } else\n stat.removeAllListeners(\"change\");\n stat.stop(), statWatchers.delete(filename);\n}, callbackify = function(fsFunction, args) {\n const callback = args[args.length - 1];\n try {\n var result = fsFunction.apply(fs, args.slice(0, args.length - 1));\n result.then((...args2) => callback(null, ...args2), (err) => callback(err));\n } catch (e) {\n if (typeof callback === \"function\")\n callback(e);\n else\n throw e;\n }\n}, createReadStream = function(path, options) {\n return new ReadStream(path, options);\n}, WriteStream_handleWrite = function(er, bytes) {\n if (er)\n return WriteStream_errorOrDestroy.call(this, er);\n this.bytesWritten += bytes;\n}, WriteStream_internalClose = function(err, cb) {\n this[_writeStreamPathFastPathSymbol] = !1;\n var fd = this.fd;\n this[_fs].close(fd, (er) => {\n this.fd = null, cb(err || er);\n });\n}, WriteStream_errorOrDestroy = function(err) {\n var {\n _readableState: r = { destroyed: !1, autoDestroy: !1 },\n _writableState: w = { destroyed: !1, autoDestroy: !1 }\n } = this;\n if (w\?.destroyed || r\?.destroyed)\n return this;\n if (r\?.autoDestroy || w\?.autoDestroy)\n this.destroy(err);\n else if (err)\n this.emit(\"error\", err);\n}, createWriteStream = function(path, options) {\n return new WriteStream(path, options);\n}, cpSync = function(src, dest, options) {\n if (!options)\n return fs.cpSync(src, dest);\n if (typeof options !== \"object\")\n @throwTypeError(\"options must be an object\");\n if (options.dereference || options.filter || options.preserveTimestamps || options.verbatimSymlinks) {\n if (!lazy_cpSync)\n lazy_cpSync = @getInternalField(@internalModuleRegistry, 3) || @createInternalModuleById(3);\n return lazy_cpSync(src, dest, options);\n }\n return fs.cpSync(src, dest, options.recursive, options.errorOnExist, options.force \?\? !0, options.mode);\n}, cp = function(src, dest, options, callback) {\n if (typeof options === \"function\")\n callback = options, options = @undefined;\n promises.cp(src, dest, options).then(() => callback(), callback);\n}, _toUnixTimestamp = function(time, name = \"time\") {\n if (typeof time === \"string\" && +time == time)\n return +time;\n if (NumberIsFinite(time)) {\n if (time < 0)\n return DateNow() / 1000;\n return time;\n }\n if (isDate(time))\n return DatePrototypeGetTime(time) / 1000;\n @throwTypeError(`Expected ${name} to be a number or Date`);\n}, $, ReadStream, WriteStream, EventEmitter = @getInternalField(@internalModuleRegistry, 18) || @createInternalModuleById(18), promises = @getInternalField(@internalModuleRegistry, 20) || @createInternalModuleById(20), Stream = @getInternalField(@internalModuleRegistry, 37) || @createInternalModuleById(37), { isArrayBufferView } = @requireNativeModule(\"util/types\"), _writeStreamPathFastPathSymbol = Symbol.for(\"Bun.NodeWriteStreamFastPath\"), _fs = Symbol.for(\"#fs\"), constants = @processBindingConstants.fs, fs = Bun.fs();\n\nclass FSWatcher extends EventEmitter {\n #watcher;\n #listener;\n constructor(path, options, listener) {\n super();\n if (typeof options === \"function\")\n listener = options, options = {};\n else if (typeof options === \"string\")\n options = { encoding: options };\n if (typeof listener !== \"function\")\n listener = () => {\n };\n this.#listener = listener;\n try {\n this.#watcher = fs.watch(path, options || {}, this.#onEvent.bind(this));\n } catch (e) {\n if (!e.message\?.startsWith(\"FileNotFound\"))\n throw e;\n const notFound = new Error(`ENOENT: no such file or directory, watch '${path}'`);\n throw notFound.code = \"ENOENT\", notFound.errno = -2, notFound.path = path, notFound.syscall = \"watch\", notFound.filename = path, notFound;\n }\n }\n #onEvent(eventType, filenameOrError) {\n if (eventType === \"error\" || eventType === \"close\")\n this.emit(eventType, filenameOrError);\n else\n this.emit(\"change\", eventType, filenameOrError), this.#listener(eventType, filenameOrError);\n }\n close() {\n this.#watcher\?.close(), this.#watcher = null;\n }\n ref() {\n this.#watcher\?.ref();\n }\n unref() {\n this.#watcher\?.unref();\n }\n start() {\n }\n}\n\nclass StatWatcher extends EventEmitter {\n constructor(path, options) {\n super();\n this._handle = fs.watchFile(path, options, this.#onChange.bind(this));\n }\n #onChange(curr, prev) {\n this.emit(\"change\", curr, prev);\n }\n start() {\n }\n stop() {\n this._handle\?.close(), this._handle = null;\n }\n ref() {\n this._handle\?.ref();\n }\n unref() {\n this._handle\?.unref();\n }\n}\nvar access = function access2(...args) {\n callbackify(fs.access, args);\n}, appendFile = function appendFile2(...args) {\n callbackify(fs.appendFile, args);\n}, close = function close2(...args) {\n callbackify(fs.close, args);\n}, rm = function rm2(...args) {\n callbackify(fs.rm, args);\n}, rmdir = function rmdir2(...args) {\n callbackify(fs.rmdir, args);\n}, copyFile = function copyFile2(...args) {\n const callback = args[args.length - 1];\n if (typeof callback !== \"function\")\n @throwTypeError(\"Callback must be a function\");\n fs.copyFile(...args).then((result) => callback(null, result), callback);\n}, exists = function exists2(...args) {\n callbackify(fs.exists, args);\n}, chown = function chown2(...args) {\n callbackify(fs.chown, args);\n}, chmod = function chmod2(...args) {\n callbackify(fs.chmod, args);\n}, fchmod = function fchmod2(...args) {\n callbackify(fs.fchmod, args);\n}, fchown = function fchown2(...args) {\n callbackify(fs.fchown, args);\n}, fstat = function fstat2(...args) {\n callbackify(fs.fstat, args);\n}, fsync = function fsync2(...args) {\n callbackify(fs.fsync, args);\n}, ftruncate = function ftruncate2(...args) {\n callbackify(fs.ftruncate, args);\n}, futimes = function futimes2(...args) {\n callbackify(fs.futimes, args);\n}, lchmod = function lchmod2(...args) {\n callbackify(fs.lchmod, args);\n}, lchown = function lchown2(...args) {\n callbackify(fs.lchown, args);\n}, link = function link2(...args) {\n callbackify(fs.link, args);\n}, mkdir = function mkdir2(...args) {\n callbackify(fs.mkdir, args);\n}, mkdtemp = function mkdtemp2(...args) {\n callbackify(fs.mkdtemp, args);\n}, open = function open2(...args) {\n callbackify(fs.open, args);\n}, read = function read2(fd, buffer, offsetOrOptions, length, position, callback) {\n let offset = offsetOrOptions, params = null;\n if (arguments.length <= 4) {\n if (arguments.length === 4)\n callback = length, params = offsetOrOptions;\n else if (arguments.length === 3) {\n if (!isArrayBufferView(buffer))\n params = buffer, { buffer = @Buffer.alloc(16384) } = params \?\? {};\n callback = offsetOrOptions;\n } else\n callback = buffer, buffer = @Buffer.alloc(16384);\n ({ offset = 0, length = buffer\?.byteLength - offset, position = null } = params \?\? {});\n }\n queueMicrotask(() => {\n try {\n var bytesRead = fs.readSync(fd, buffer, offset, length, position);\n } catch (e) {\n callback(e);\n }\n callback(null, bytesRead, buffer);\n });\n}, write = function write2(...args) {\n callbackify(fs.write, args);\n}, readdir = function readdir2(...args) {\n const callback = args[args.length - 1];\n if (typeof callback !== \"function\")\n @throwTypeError(\"Callback must be a function\");\n fs.readdir(...args).then((result) => callback(null, result), callback);\n}, readFile = function readFile2(...args) {\n const callback = args[args.length - 1];\n if (typeof callback !== \"function\")\n @throwTypeError(\"Callback must be a function\");\n fs.readFile(...args).then((result) => callback(null, result), callback);\n}, writeFile = function writeFile2(...args) {\n callbackify(fs.writeFile, args);\n}, readlink = function readlink2(...args) {\n callbackify(fs.readlink, args);\n}, realpath = function realpath2(...args) {\n const callback = args[args.length - 1];\n if (typeof callback !== \"function\")\n @throwTypeError(\"Callback must be a function\");\n fs.realpath(...args).then((result) => callback(null, result), callback);\n}, rename = function rename2(...args) {\n callbackify(fs.rename, args);\n}, lstat = function lstat2(...args) {\n const callback = args[args.length - 1];\n if (typeof callback !== \"function\")\n @throwTypeError(\"Callback must be a function\");\n fs.lstat(...args).then((result) => callback(null, result), callback);\n}, stat = function stat2(...args) {\n const callback = args[args.length - 1];\n if (typeof callback !== \"function\")\n @throwTypeError(\"Callback must be a function\");\n fs.stat(...args).then((result) => callback(null, result), callback);\n}, symlink = function symlink2(...args) {\n callbackify(fs.symlink, args);\n}, truncate = function truncate2(...args) {\n callbackify(fs.truncate, args);\n}, unlink = function unlink2(...args) {\n callbackify(fs.unlink, args);\n}, utimes = function utimes2(...args) {\n callbackify(fs.utimes, args);\n}, lutimes = function lutimes2(...args) {\n callbackify(fs.lutimes, args);\n}, accessSync = fs.accessSync.bind(fs), appendFileSync = fs.appendFileSync.bind(fs), closeSync = fs.closeSync.bind(fs), copyFileSync = fs.copyFileSync.bind(fs), existsSync = fs.existsSync.bind(fs), chownSync = fs.chownSync.bind(fs), chmodSync = fs.chmodSync.bind(fs), fchmodSync = fs.fchmodSync.bind(fs), fchownSync = fs.fchownSync.bind(fs), fstatSync = fs.fstatSync.bind(fs), fsyncSync = fs.fsyncSync.bind(fs), ftruncateSync = fs.ftruncateSync.bind(fs), futimesSync = fs.futimesSync.bind(fs), lchmodSync = fs.lchmodSync.bind(fs), lchownSync = fs.lchownSync.bind(fs), linkSync = fs.linkSync.bind(fs), lstatSync = fs.lstatSync.bind(fs), mkdirSync = fs.mkdirSync.bind(fs), mkdtempSync = fs.mkdtempSync.bind(fs), openSync = fs.openSync.bind(fs), readSync = fs.readSync.bind(fs), writeSync = fs.writeSync.bind(fs), readdirSync = fs.readdirSync.bind(fs), readFileSync = fs.readFileSync.bind(fs), writeFileSync = fs.writeFileSync.bind(fs), readlinkSync = fs.readlinkSync.bind(fs), realpathSync = fs.realpathSync.bind(fs), renameSync = fs.renameSync.bind(fs), statSync = fs.statSync.bind(fs), symlinkSync = fs.symlinkSync.bind(fs), truncateSync = fs.truncateSync.bind(fs), unlinkSync = fs.unlinkSync.bind(fs), utimesSync = fs.utimesSync.bind(fs), lutimesSync = fs.lutimesSync.bind(fs), rmSync = fs.rmSync.bind(fs), rmdirSync = fs.rmdirSync.bind(fs), writev = (fd, buffers, position, callback) => {\n if (typeof position === \"function\")\n callback = position, position = null;\n queueMicrotask(() => {\n try {\n var written = fs.writevSync(fd, buffers, position);\n } catch (e) {\n callback(e);\n }\n callback(null, written, buffers);\n });\n}, writevSync = fs.writevSync.bind(fs), readv = (fd, buffers, position, callback) => {\n if (typeof position === \"function\")\n callback = position, position = null;\n queueMicrotask(() => {\n try {\n var written = fs.readvSync(fd, buffers, position);\n } catch (e) {\n callback(e);\n }\n callback(null, written, buffers);\n });\n}, readvSync = fs.readvSync.bind(fs), Dirent = fs.Dirent, Stats = fs.Stats, watch = function watch2(path, options, listener) {\n return new FSWatcher(path, options, listener);\n}, statWatchers = new Map, _pathModule, readStreamPathFastPathSymbol = Symbol.for(\"Bun.Node.readStreamPathFastPath\"), readStreamSymbol = Symbol.for(\"Bun.NodeReadStream\"), readStreamPathOrFdSymbol = Symbol.for(\"Bun.NodeReadStreamPathOrFd\"), writeStreamSymbol = Symbol.for(\"Bun.NodeWriteStream\"), writeStreamPathFastPathSymbol = Symbol.for(\"Bun.NodeWriteStreamFastPath\"), writeStreamPathFastPathCallSymbol = Symbol.for(\"Bun.NodeWriteStreamFastPathCall\"), kIoDone = Symbol.for(\"kIoDone\"), defaultReadStreamOptions = {\n file: @undefined,\n fd: null,\n flags: \"r\",\n encoding: @undefined,\n mode: 438,\n autoClose: !0,\n emitClose: !0,\n start: 0,\n end: @Infinity,\n highWaterMark: 65536,\n fs: {\n read,\n open: (path, flags, mode, cb) => {\n var fd;\n try {\n fd = openSync(path, flags, mode);\n } catch (e) {\n cb(e);\n return;\n }\n cb(null, fd);\n },\n openSync,\n close\n },\n autoDestroy: !0\n}, ReadStreamClass;\nReadStream = function(InternalReadStream) {\n ReadStreamClass = InternalReadStream, Object.defineProperty(ReadStreamClass.prototype, Symbol.toStringTag, {\n value: \"ReadStream\",\n enumerable: !1\n });\n function ReadStream3(path, options) {\n return new InternalReadStream(path, options);\n }\n return ReadStream3.prototype = InternalReadStream.prototype, Object.defineProperty(ReadStream3, Symbol.hasInstance, {\n value(instance) {\n return instance instanceof InternalReadStream;\n }\n });\n}(class ReadStream2 extends Stream._getNativeReadableStreamPrototype(2, Stream.Readable) {\n constructor(pathOrFd, options = defaultReadStreamOptions) {\n if (typeof options !== \"object\" || !options)\n @throwTypeError(\"Expected options to be an object\");\n var {\n flags = defaultReadStreamOptions.flags,\n encoding = defaultReadStreamOptions.encoding,\n mode = defaultReadStreamOptions.mode,\n autoClose = defaultReadStreamOptions.autoClose,\n emitClose = defaultReadStreamOptions.emitClose,\n start = defaultReadStreamOptions.start,\n end = defaultReadStreamOptions.end,\n autoDestroy = defaultReadStreamOptions.autoClose,\n fs: fs2 = defaultReadStreamOptions.fs,\n highWaterMark = defaultReadStreamOptions.highWaterMark,\n fd = defaultReadStreamOptions.fd\n } = options;\n if (pathOrFd\?.constructor\?.name === \"URL\")\n pathOrFd = Bun.fileURLToPath(pathOrFd);\n var tempThis = {};\n if (fd != null) {\n if (typeof fd !== \"number\")\n @throwTypeError(\"Expected options.fd to be a number\");\n tempThis.fd = tempThis[readStreamPathOrFdSymbol] = fd, tempThis.autoClose = !1;\n } else if (typeof pathOrFd === \"string\") {\n if (pathOrFd.startsWith(\"file://\"))\n pathOrFd = Bun.fileURLToPath(pathOrFd);\n if (pathOrFd.length === 0)\n @throwTypeError(\"Expected path to be a non-empty string\");\n tempThis.path = tempThis.file = tempThis[readStreamPathOrFdSymbol] = pathOrFd;\n } else if (typeof pathOrFd === \"number\") {\n if (pathOrFd |= 0, pathOrFd < 0)\n @throwTypeError(\"Expected fd to be a positive integer\");\n tempThis.fd = tempThis[readStreamPathOrFdSymbol] = pathOrFd, tempThis.autoClose = !1;\n } else\n @throwTypeError(\"Expected a path or file descriptor\");\n if (tempThis.fd === @undefined)\n tempThis.fd = fs2.openSync(pathOrFd, flags, mode);\n var fileRef = Bun.file(tempThis.fd), stream = fileRef.stream(), native = @direct(stream);\n if (!native)\n throw new Error(\"no native readable stream\");\n var { stream: ptr } = native;\n super(ptr, {\n ...options,\n encoding,\n autoDestroy,\n autoClose,\n emitClose,\n highWaterMark\n });\n if (Object.assign(this, tempThis), this.#fileRef = fileRef, this.end = end, this._read = this.#internalRead, this.start = start, this.flags = flags, this.mode = mode, this.emitClose = emitClose, this[readStreamPathFastPathSymbol] = start === 0 && end === @Infinity && autoClose && fs2 === defaultReadStreamOptions.fs && (encoding === \"buffer\" || encoding === \"binary\" || encoding == null || encoding === \"utf-8\" || encoding === \"utf8\"), this._readableState.autoClose = autoDestroy = autoClose, this._readableState.highWaterMark = highWaterMark, start !== @undefined)\n this.pos = start;\n }\n #fileRef;\n #fs;\n file;\n path;\n fd = null;\n flags;\n mode;\n start;\n end;\n pos;\n bytesRead = 0;\n #fileSize = -1;\n _read;\n [readStreamSymbol] = !0;\n [readStreamPathOrFdSymbol];\n [readStreamPathFastPathSymbol];\n _construct(callback) {\n if (super._construct)\n super._construct(callback);\n else\n callback();\n this.emit(\"open\", this.fd), this.emit(\"ready\");\n }\n _destroy(err, cb) {\n super._destroy(err, cb);\n try {\n var fd = this.fd;\n if (this[readStreamPathFastPathSymbol] = !1, !fd)\n cb(err);\n else\n this.#fs.close(fd, (er) => {\n cb(er || err);\n }), this.fd = null;\n } catch (e) {\n throw e;\n }\n }\n close(cb) {\n if (typeof cb === \"function\")\n Stream.eos(this, cb);\n this.destroy();\n }\n push(chunk) {\n var bytesRead = chunk\?.length \?\? 0;\n if (bytesRead > 0) {\n this.bytesRead += bytesRead;\n var currPos = this.pos;\n if (currPos !== @undefined) {\n if (this.bytesRead < currPos)\n return !0;\n if (currPos === this.start) {\n var n = this.bytesRead - currPos;\n chunk = chunk.slice(-n);\n var [_, ...rest] = arguments;\n if (this.pos = this.bytesRead, this.end !== @undefined && this.bytesRead > this.end)\n chunk = chunk.slice(0, this.end - this.start + 1);\n return super.push(chunk, ...rest);\n }\n var end = this.end;\n if (end !== @undefined && this.bytesRead > end) {\n chunk = chunk.slice(0, end - currPos + 1);\n var [_, ...rest] = arguments;\n return this.pos = this.bytesRead, super.push(chunk, ...rest);\n }\n this.pos = this.bytesRead;\n }\n }\n return super.push(...arguments);\n }\n #internalRead(n) {\n var { pos, end, bytesRead, fd, encoding } = this;\n if (n = pos !== @undefined \? Math.min(end - pos + 1, n) : Math.min(end - bytesRead + 1, n), n <= 0) {\n this.push(null);\n return;\n }\n if (this.#fileSize === -1 && bytesRead === 0 && pos === @undefined) {\n var stat3 = fstatSync(fd);\n if (this.#fileSize = stat3.size, this.#fileSize > 0 && n > this.#fileSize)\n n = this.#fileSize + 1;\n }\n this[kIoDone] = !1;\n var res = super._read(n);\n if (@isPromise(res)) {\n var then = res\?.then;\n if (then && @isCallable(then))\n res.then(() => {\n if (this[kIoDone] = !0, this.destroyed)\n this.emit(kIoDone);\n }, (er) => {\n this[kIoDone] = !0, this.#errorOrDestroy(er);\n });\n } else if (this[kIoDone] = !0, this.destroyed)\n this.emit(kIoDone), this.#errorOrDestroy(new Error(\"ERR_STREAM_PREMATURE_CLOSE\"));\n }\n #errorOrDestroy(err, sync = null) {\n var {\n _readableState: r = { destroyed: !1, autoDestroy: !1 },\n _writableState: w = { destroyed: !1, autoDestroy: !1 }\n } = this;\n if (w\?.destroyed || r\?.destroyed)\n return this;\n if (r\?.autoDestroy || w\?.autoDestroy)\n this.destroy(err);\n else if (err)\n this.emit(\"error\", err);\n }\n pause() {\n return this[readStreamPathFastPathSymbol] = !1, super.pause();\n }\n resume() {\n return this[readStreamPathFastPathSymbol] = !1, super.resume();\n }\n unshift(...args) {\n return this[readStreamPathFastPathSymbol] = !1, super.unshift(...args);\n }\n pipe(dest, pipeOpts) {\n if (this[readStreamPathFastPathSymbol] && (pipeOpts\?.end \?\? !0) && this._readableState\?.pipes\?.length === 0) {\n if ((writeStreamPathFastPathSymbol in dest) && dest[writeStreamPathFastPathSymbol]) {\n if (dest[writeStreamPathFastPathCallSymbol](this, pipeOpts))\n return this;\n }\n }\n return this[readStreamPathFastPathSymbol] = !1, super.pipe(dest, pipeOpts);\n }\n});\nvar defaultWriteStreamOptions = {\n fd: null,\n start: @undefined,\n pos: @undefined,\n encoding: @undefined,\n flags: \"w\",\n mode: 438,\n fs: {\n write,\n close,\n open,\n openSync\n }\n}, WriteStreamClass = WriteStream = function WriteStream2(path, options = defaultWriteStreamOptions) {\n if (!(this instanceof WriteStream2))\n return new WriteStream2(path, options);\n if (!options)\n @throwTypeError(\"Expected options to be an object\");\n var {\n fs: fs2 = defaultWriteStreamOptions.fs,\n start = defaultWriteStreamOptions.start,\n flags = defaultWriteStreamOptions.flags,\n mode = defaultWriteStreamOptions.mode,\n autoClose = !0,\n emitClose = !1,\n autoDestroy = autoClose,\n encoding = defaultWriteStreamOptions.encoding,\n fd = defaultWriteStreamOptions.fd,\n pos = defaultWriteStreamOptions.pos\n } = options, tempThis = {};\n if (fd != null) {\n if (typeof fd !== \"number\")\n throw new Error(\"Expected options.fd to be a number\");\n tempThis.fd = fd, tempThis[_writeStreamPathFastPathSymbol] = !1;\n } else if (typeof path === \"string\") {\n if (path.length === 0)\n @throwTypeError(\"Expected a non-empty path\");\n if (path.startsWith(\"file:\"))\n path = Bun.fileURLToPath(path);\n tempThis.path = path, tempThis.fd = null, tempThis[_writeStreamPathFastPathSymbol] = autoClose && (start === @undefined || start === 0) && fs2.write === defaultWriteStreamOptions.fs.write && fs2.close === defaultWriteStreamOptions.fs.close;\n }\n if (tempThis.fd == null)\n tempThis.fd = fs2.openSync(path, flags, mode);\n if (NativeWritable.call(this, tempThis.fd, {\n ...options,\n decodeStrings: !1,\n autoDestroy,\n emitClose,\n fd: tempThis\n }), Object.assign(this, tempThis), typeof fs2\?.write !== \"function\")\n @throwTypeError(\"Expected fs.write to be a function\");\n if (typeof fs2\?.close !== \"function\")\n @throwTypeError(\"Expected fs.close to be a function\");\n if (typeof fs2\?.open !== \"function\")\n @throwTypeError(\"Expected fs.open to be a function\");\n if (typeof path === \"object\" && path) {\n if (path instanceof URL)\n path = Bun.fileURLToPath(path);\n }\n if (typeof path !== \"string\" && typeof fd !== \"number\")\n @throwTypeError(\"Expected a path or file descriptor\");\n if (this.start = start, this[_fs] = fs2, this.flags = flags, this.mode = mode, this.bytesWritten = 0, this[writeStreamSymbol] = !0, this[kIoDone] = !1, this.start !== @undefined)\n this.pos = this.start;\n if (encoding !== defaultWriteStreamOptions.encoding) {\n if (this.setDefaultEncoding(encoding), encoding !== \"buffer\" && encoding !== \"utf8\" && encoding !== \"utf-8\" && encoding !== \"binary\")\n this[_writeStreamPathFastPathSymbol] = !1;\n }\n return this;\n}, NativeWritable = Stream.NativeWritable, WriteStreamPrototype = WriteStream.prototype = Object.create(NativeWritable.prototype);\nObject.defineProperties(WriteStreamPrototype, {\n autoClose: {\n get() {\n return this._writableState.autoDestroy;\n },\n set(val) {\n this._writableState.autoDestroy = val;\n }\n },\n pending: {\n get() {\n return this.fd === null;\n }\n }\n});\nWriteStreamPrototype.destroySoon = WriteStreamPrototype.end;\nWriteStreamPrototype.open = function open3() {\n};\nWriteStreamPrototype[writeStreamPathFastPathCallSymbol] = function WriteStreamPathFastPathCallSymbol(readStream, pipeOpts) {\n if (!this[_writeStreamPathFastPathSymbol])\n return !1;\n if (this.fd !== null)\n return this[_writeStreamPathFastPathSymbol] = !1, !1;\n return this[kIoDone] = !1, readStream[kIoDone] = !1, Bun.write(this[_writeStreamPathFastPathSymbol], readStream[readStreamPathOrFdSymbol]).then((bytesWritten) => {\n readStream[kIoDone] = this[kIoDone] = !0, this.bytesWritten += bytesWritten, readStream.bytesRead += bytesWritten, this.end(), readStream.close();\n }, (err) => {\n readStream[kIoDone] = this[kIoDone] = !0, WriteStream_errorOrDestroy.call(this, err), readStream.emit(\"error\", err);\n });\n};\nWriteStreamPrototype.isBunFastPathEnabled = function isBunFastPathEnabled() {\n return this[_writeStreamPathFastPathSymbol];\n};\nWriteStreamPrototype.disableBunFastPath = function disableBunFastPath() {\n this[_writeStreamPathFastPathSymbol] = !1;\n};\nWriteStreamPrototype._construct = function _construct(callback) {\n if (typeof this.fd === \"number\") {\n callback();\n return;\n }\n callback(), this.emit(\"open\", this.fd), this.emit(\"ready\");\n};\nWriteStreamPrototype._destroy = function _destroy(err, cb) {\n if (this.fd === null)\n return cb(err);\n if (this[kIoDone]) {\n this.once(kIoDone, () => WriteStream_internalClose.call(this, err, cb));\n return;\n }\n WriteStream_internalClose.call(this, err, cb);\n};\nWriteStreamPrototype.close = function close3(cb) {\n if (cb) {\n if (this.closed) {\n process.nextTick(cb);\n return;\n }\n this.on(\"close\", cb);\n }\n if (!this.autoClose)\n this.on(\"finish\", this.destroy);\n this.end();\n};\nWriteStreamPrototype.write = function write3(chunk, encoding, cb) {\n if (encoding \?\?= this._writableState\?.defaultEncoding, this[_writeStreamPathFastPathSymbol] = !1, typeof chunk === \"string\")\n chunk = @Buffer.from(chunk, encoding);\n var native = this.pos === @undefined;\n const callback = native \? (err, bytes) => {\n if (this[kIoDone] = !1, WriteStream_handleWrite.call(this, err, bytes), this.emit(kIoDone), cb)\n !err \? cb() : cb(err);\n } : () => {\n };\n if (this[kIoDone] = !0, this._write)\n return this._write(chunk, encoding, callback);\n else\n return NativeWritable.prototype.write.call(this, chunk, encoding, callback, native);\n};\nWriteStreamPrototype._write = @undefined;\nWriteStreamPrototype._writev = @undefined;\nWriteStreamPrototype.end = function end(chunk, encoding, cb) {\n var native = this.pos === @undefined;\n return NativeWritable.prototype.end.call(this, chunk, encoding, cb, native);\n};\nWriteStreamPrototype._destroy = function _destroy2(err, cb) {\n this.close(err, cb);\n};\nObject.defineProperties(fs, {\n createReadStream: {\n value: createReadStream\n },\n createWriteStream: {\n value: createWriteStream\n },\n ReadStream: {\n value: ReadStream\n },\n WriteStream: {\n value: WriteStream\n }\n});\nrealpath.native = realpath;\nrealpathSync.native = realpathSync;\nvar lazy_cpSync = null;\n$ = {\n Dirent,\n FSWatcher,\n ReadStream,\n Stats,\n WriteStream,\n _toUnixTimestamp,\n access,\n accessSync,\n appendFile,\n appendFileSync,\n chmod,\n chmodSync,\n chown,\n chownSync,\n close,\n closeSync,\n constants,\n copyFile,\n copyFileSync,\n cp,\n cpSync,\n createReadStream,\n createWriteStream,\n exists,\n existsSync,\n fchmod,\n fchmodSync,\n fchown,\n fchownSync,\n fstat,\n fstatSync,\n fsync,\n fsyncSync,\n ftruncate,\n ftruncateSync,\n futimes,\n futimesSync,\n lchmod,\n lchmodSync,\n lchown,\n lchownSync,\n link,\n linkSync,\n lstat,\n lstatSync,\n lutimes,\n lutimesSync,\n mkdir,\n mkdirSync,\n mkdtemp,\n mkdtempSync,\n open,\n openSync,\n promises,\n read,\n readFile,\n readFileSync,\n readSync,\n readdir,\n readdirSync,\n readlink,\n readlinkSync,\n readv,\n readvSync,\n realpath,\n realpathSync,\n rename,\n renameSync,\n rm,\n rmSync,\n rmdir,\n rmdirSync,\n stat,\n statSync,\n symlink,\n symlinkSync,\n truncate,\n truncateSync,\n unlink,\n unlinkSync,\n unwatchFile,\n utimes,\n utimesSync,\n watch,\n watchFile,\n write,\n writeFile,\n writeFileSync,\n writeSync,\n writev,\n writevSync,\n [Symbol.for(\"::bunternal::\")]: {\n ReadStreamClass,\n WriteStreamClass\n }\n};\nreturn $})\n"_s; // // -static constexpr ASCIILiteral NodeFSPromisesCode = "(function (){\"use strict\";// src/js/out/tmp/node/fs.promises.ts\nvar watch = function(filename, options = {}) {\n if (filename instanceof URL)\n @throwTypeError(\"Watch URLs are not supported yet\");\n else if (@Buffer.isBuffer(filename))\n filename = filename.toString();\n else if (typeof filename !== \"string\")\n @throwTypeError(\"Expected path to be a string or Buffer\");\n let nextEventResolve = null;\n if (typeof options === \"string\")\n options = { encoding: options };\n const queue = @createFIFO(), watcher = fs.watch(filename, options || {}, (eventType, filename2) => {\n if (queue.push({ eventType, filename: filename2 }), nextEventResolve) {\n const resolve = nextEventResolve;\n nextEventResolve = null, resolve();\n }\n });\n return {\n [Symbol.asyncIterator]() {\n let closed = !1;\n return {\n async next() {\n while (!closed) {\n let event;\n while (event = queue.shift()) {\n if (event.eventType === \"close\")\n return closed = !0, { value: @undefined, done: !0 };\n if (event.eventType === \"error\")\n throw closed = !0, event.filename;\n return { value: event, done: !1 };\n }\n const { promise, resolve } = @Promise.withResolvers();\n nextEventResolve = resolve, await promise;\n }\n return { value: @undefined, done: !0 };\n },\n return() {\n if (!closed) {\n if (watcher.close(), closed = !0, nextEventResolve) {\n const resolve = nextEventResolve;\n nextEventResolve = null, resolve();\n }\n }\n return { value: @undefined, done: !0 };\n }\n };\n }\n };\n}, cp = function(src, dest, options) {\n if (!options)\n return fs.cp(src, dest);\n if (typeof options !== \"object\")\n @throwTypeError(\"options must be an object\");\n if (options.dereference || options.filter || options.preserveTimestamps || options.verbatimSymlinks) {\n if (!lazy_cp)\n lazy_cp = @getInternalField(@internalModuleRegistry, 3) || @createInternalModuleById(3);\n return lazy_cp(src, dest, options);\n }\n return fs.cp(src, dest, options.recursive, options.errorOnExist, options.force \?\? !0, options.mode);\n};\nasync function opendir(dir) {\n const entries = await fs.readdir(dir, { withFileTypes: !0 });\n return new Dir(entries);\n}\nvar $, constants = @processBindingConstants.fs, fs = Bun.fs(), notrace = \"::bunternal::\", promisify = {\n [notrace]: (fsFunction) => {\n return async function(...args) {\n return await 1, fsFunction.apply(fs, args);\n };\n }\n}[notrace], lazy_cp = null;\n\nclass Dir {\n #entries;\n constructor(e) {\n this.#entries = e;\n }\n readSync() {\n return this.#entries.shift() \?\? null;\n }\n read(c) {\n if (c)\n process.nextTick(c, null, this.readSync());\n return @Promise.resolve(this.readSync());\n }\n closeSync() {\n }\n close(c) {\n if (c)\n process.nextTick(c);\n return @Promise.resolve();\n }\n *[Symbol.asyncIterator]() {\n var next;\n while (next = this.readSync())\n yield next;\n }\n}\n$ = {\n access: promisify(fs.accessSync),\n appendFile: promisify(fs.appendFileSync),\n close: promisify(fs.closeSync),\n copyFile: fs.copyFile.bind(fs),\n cp,\n exists: promisify(fs.existsSync),\n chown: promisify(fs.chownSync),\n chmod: promisify(fs.chmodSync),\n fchmod: promisify(fs.fchmodSync),\n fchown: promisify(fs.fchownSync),\n fstat: promisify(fs.fstatSync),\n fsync: promisify(fs.fsyncSync),\n ftruncate: promisify(fs.ftruncateSync),\n futimes: promisify(fs.futimesSync),\n lchmod: promisify(fs.lchmodSync),\n lchown: promisify(fs.lchownSync),\n link: promisify(fs.linkSync),\n lstat: fs.lstat.bind(fs),\n mkdir: promisify(fs.mkdirSync),\n mkdtemp: promisify(fs.mkdtempSync),\n open: promisify(fs.openSync),\n read: promisify(fs.readSync),\n write: promisify(fs.writeSync),\n readdir: fs.readdir.bind(fs),\n readFile: fs.readFile.bind(fs),\n writeFile: promisify(fs.writeFileSync),\n readlink: promisify(fs.readlinkSync),\n realpath: fs.realpath.bind(fs),\n rename: promisify(fs.renameSync),\n stat: fs.stat.bind(fs),\n symlink: promisify(fs.symlinkSync),\n truncate: promisify(fs.truncateSync),\n unlink: promisify(fs.unlinkSync),\n utimes: promisify(fs.utimesSync),\n lutimes: promisify(fs.lutimesSync),\n rm: promisify(fs.rmSync),\n rmdir: promisify(fs.rmdirSync),\n writev: (fd, buffers, position) => {\n return new @Promise((resolve, reject) => {\n try {\n var bytesWritten = fs.writevSync(fd, buffers, position);\n } catch (err) {\n reject(err);\n return;\n }\n resolve({\n bytesWritten,\n buffers\n });\n });\n },\n readv: (fd, buffers, position) => {\n return new @Promise((resolve, reject) => {\n try {\n var bytesRead = fs.readvSync(fd, buffers, position);\n } catch (err) {\n reject(err);\n return;\n }\n resolve({\n bytesRead,\n buffers\n });\n });\n },\n constants,\n watch,\n opendir\n};\nreturn $})\n"_s; +static constexpr ASCIILiteral NodeFSPromisesCode = "(function (){\"use strict\";// src/js/out/tmp/node/fs.promises.ts\nvar watch = function(filename, options = {}) {\n if (filename instanceof URL)\n @throwTypeError(\"Watch URLs are not supported yet\");\n else if (@Buffer.isBuffer(filename))\n filename = filename.toString();\n else if (typeof filename !== \"string\")\n @throwTypeError(\"Expected path to be a string or Buffer\");\n let nextEventResolve = null;\n if (typeof options === \"string\")\n options = { encoding: options };\n const queue = @createFIFO(), watcher = fs.watch(filename, options || {}, (eventType, filename2) => {\n if (queue.push({ eventType, filename: filename2 }), nextEventResolve) {\n const resolve = nextEventResolve;\n nextEventResolve = null, resolve();\n }\n });\n return {\n [Symbol.asyncIterator]() {\n let closed = !1;\n return {\n async next() {\n while (!closed) {\n let event;\n while (event = queue.shift()) {\n if (event.eventType === \"close\")\n return closed = !0, { value: @undefined, done: !0 };\n if (event.eventType === \"error\")\n throw closed = !0, event.filename;\n return { value: event, done: !1 };\n }\n const { promise, resolve } = @Promise.withResolvers();\n nextEventResolve = resolve, await promise;\n }\n return { value: @undefined, done: !0 };\n },\n return() {\n if (!closed) {\n if (watcher.close(), closed = !0, nextEventResolve) {\n const resolve = nextEventResolve;\n nextEventResolve = null, resolve();\n }\n }\n return { value: @undefined, done: !0 };\n }\n };\n }\n };\n}, cp = function(src, dest, options) {\n if (!options)\n return fs.cp(src, dest);\n if (typeof options !== \"object\")\n @throwTypeError(\"options must be an object\");\n if (options.dereference || options.filter || options.preserveTimestamps || options.verbatimSymlinks) {\n if (!lazy_cp)\n lazy_cp = @getInternalField(@internalModuleRegistry, 3) || @createInternalModuleById(3);\n return lazy_cp(src, dest, options);\n }\n return fs.cp(src, dest, options.recursive, options.errorOnExist, options.force \?\? !0, options.mode);\n};\nasync function opendir(dir) {\n const entries = await fs.readdir(dir, { withFileTypes: !0 });\n return new Dir(entries);\n}\nvar $, constants = @processBindingConstants.fs, fs = Bun.fs();\nvar lazy_cp = null;\n\nclass Dir {\n #entries;\n constructor(e) {\n this.#entries = e;\n }\n readSync() {\n return this.#entries.shift() \?\? null;\n }\n read(c) {\n if (c)\n process.nextTick(c, null, this.readSync());\n return @Promise.resolve(this.readSync());\n }\n closeSync() {\n }\n close(c) {\n if (c)\n process.nextTick(c);\n return @Promise.resolve();\n }\n *[Symbol.asyncIterator]() {\n var next;\n while (next = this.readSync())\n yield next;\n }\n}\n$ = {\n access: fs.access.bind(fs),\n appendFile: fs.appendFile.bind(fs),\n close: fs.close.bind(fs),\n copyFile: fs.copyFile.bind(fs),\n cp,\n exists: fs.exists.bind(fs),\n chown: fs.chown.bind(fs),\n chmod: fs.chmod.bind(fs),\n fchmod: fs.fchmod.bind(fs),\n fchown: fs.fchown.bind(fs),\n fstat: fs.fstat.bind(fs),\n fsync: fs.fsync.bind(fs),\n ftruncate: fs.ftruncate.bind(fs),\n futimes: fs.futimes.bind(fs),\n lchmod: fs.lchmod.bind(fs),\n lchown: fs.lchown.bind(fs),\n link: fs.link.bind(fs),\n lstat: fs.lstat.bind(fs),\n mkdir: fs.mkdir.bind(fs),\n mkdtemp: fs.mkdtemp.bind(fs),\n open: fs.open.bind(fs),\n read: fs.read.bind(fs),\n write: fs.write.bind(fs),\n readdir: fs.readdir.bind(fs),\n readFile: fs.readFile.bind(fs),\n writeFile: fs.writeFile.bind(fs),\n readlink: fs.readlink.bind(fs),\n realpath: fs.realpath.bind(fs),\n rename: fs.rename.bind(fs),\n stat: fs.stat.bind(fs),\n symlink: fs.symlink.bind(fs),\n truncate: fs.truncate.bind(fs),\n unlink: fs.unlink.bind(fs),\n utimes: fs.utimes.bind(fs),\n lutimes: fs.lutimes.bind(fs),\n rm: fs.rm.bind(fs),\n rmdir: fs.rmdir.bind(fs),\n writev: async (fd, buffers, position) => {\n var bytesWritten = await fs.writev(fd, buffers, position);\n return {\n bytesWritten,\n buffers\n };\n },\n readv: async (fd, buffers, position) => {\n var bytesRead = await fs.readv(fd, buffers, position);\n return {\n bytesRead,\n buffers\n };\n },\n constants,\n watch,\n opendir\n};\nreturn $})\n"_s; // // @@ -565,11 +565,11 @@ static constexpr ASCIILiteral NodeEventsCode = "(function (){\"use strict\";// s // // -static constexpr ASCIILiteral NodeFSCode = "(function (){\"use strict\";// src/js/out/tmp/node/fs.ts\nvar getValidatedPath = function(p) {\n if (p instanceof URL)\n return Bun.fileURLToPath(p);\n if (typeof p !== \"string\")\n @throwTypeError(\"Path must be a string or URL.\");\n return (_pathModule \?\?= @getInternalField(@internalModuleRegistry, 28) || @createInternalModuleById(28)).resolve(p);\n}, watchFile = function(filename, options, listener) {\n if (filename = getValidatedPath(filename), typeof options === \"function\")\n listener = options, options = {};\n if (typeof listener !== \"function\")\n @throwTypeError(\"listener must be a function\");\n var stat = statWatchers.get(filename);\n if (!stat)\n stat = new StatWatcher(filename, options), statWatchers.set(filename, stat);\n return stat.addListener(\"change\", listener), stat;\n}, unwatchFile = function(filename, listener) {\n filename = getValidatedPath(filename);\n var stat = statWatchers.get(filename);\n if (!stat)\n return;\n if (listener) {\n if (stat.removeListener(\"change\", listener), stat.listenerCount(\"change\") !== 0)\n return;\n } else\n stat.removeAllListeners(\"change\");\n stat.stop(), statWatchers.delete(filename);\n}, callbackify = function(fsFunction, args) {\n try {\n const result = fsFunction.apply(fs, args.slice(0, args.length - 1)), callback = args[args.length - 1];\n if (typeof callback === \"function\")\n queueMicrotask(() => callback(null, result));\n } catch (e) {\n const callback = args[args.length - 1];\n if (typeof callback === \"function\")\n queueMicrotask(() => callback(e));\n }\n}, createReadStream = function(path, options) {\n return new ReadStream(path, options);\n}, WriteStream_handleWrite = function(er, bytes) {\n if (er)\n return WriteStream_errorOrDestroy.call(this, er);\n this.bytesWritten += bytes;\n}, WriteStream_internalClose = function(err, cb) {\n this[_writeStreamPathFastPathSymbol] = !1;\n var fd = this.fd;\n this[_fs].close(fd, (er) => {\n this.fd = null, cb(err || er);\n });\n}, WriteStream_errorOrDestroy = function(err) {\n var {\n _readableState: r = { destroyed: !1, autoDestroy: !1 },\n _writableState: w = { destroyed: !1, autoDestroy: !1 }\n } = this;\n if (w\?.destroyed || r\?.destroyed)\n return this;\n if (r\?.autoDestroy || w\?.autoDestroy)\n this.destroy(err);\n else if (err)\n this.emit(\"error\", err);\n}, createWriteStream = function(path, options) {\n return new WriteStream(path, options);\n}, cpSync = function(src, dest, options) {\n if (!options)\n return fs.cpSync(src, dest);\n if (typeof options !== \"object\")\n @throwTypeError(\"options must be an object\");\n if (options.dereference || options.filter || options.preserveTimestamps || options.verbatimSymlinks) {\n if (!lazy_cpSync)\n lazy_cpSync = @getInternalField(@internalModuleRegistry, 3) || @createInternalModuleById(3);\n return lazy_cpSync(src, dest, options);\n }\n return fs.cpSync(src, dest, options.recursive, options.errorOnExist, options.force \?\? !0, options.mode);\n}, cp = function(src, dest, options, callback) {\n if (typeof options === \"function\")\n callback = options, options = @undefined;\n promises.cp(src, dest, options).then(() => callback(), callback);\n}, _toUnixTimestamp = function(time, name = \"time\") {\n if (typeof time === \"string\" && +time == time)\n return +time;\n if (NumberIsFinite(time)) {\n if (time < 0)\n return DateNow() / 1000;\n return time;\n }\n if (isDate(time))\n return DatePrototypeGetTime(time) / 1000;\n @throwTypeError(`Expected ${name} to be a number or Date`);\n}, $, ReadStream, WriteStream, EventEmitter = @getInternalField(@internalModuleRegistry, 18) || @createInternalModuleById(18), promises = @getInternalField(@internalModuleRegistry, 20) || @createInternalModuleById(20), Stream = @getInternalField(@internalModuleRegistry, 37) || @createInternalModuleById(37), { isArrayBufferView } = @requireNativeModule(\"util/types\"), _writeStreamPathFastPathSymbol = Symbol.for(\"Bun.NodeWriteStreamFastPath\"), _fs = Symbol.for(\"#fs\"), constants = @processBindingConstants.fs, fs = Bun.fs();\n\nclass FSWatcher extends EventEmitter {\n #watcher;\n #listener;\n constructor(path, options, listener) {\n super();\n if (typeof options === \"function\")\n listener = options, options = {};\n else if (typeof options === \"string\")\n options = { encoding: options };\n if (typeof listener !== \"function\")\n listener = () => {\n };\n this.#listener = listener;\n try {\n this.#watcher = fs.watch(path, options || {}, this.#onEvent.bind(this));\n } catch (e) {\n if (!e.message\?.startsWith(\"FileNotFound\"))\n throw e;\n const notFound = new Error(`ENOENT: no such file or directory, watch '${path}'`);\n throw notFound.code = \"ENOENT\", notFound.errno = -2, notFound.path = path, notFound.syscall = \"watch\", notFound.filename = path, notFound;\n }\n }\n #onEvent(eventType, filenameOrError) {\n if (eventType === \"error\" || eventType === \"close\")\n this.emit(eventType, filenameOrError);\n else\n this.emit(\"change\", eventType, filenameOrError), this.#listener(eventType, filenameOrError);\n }\n close() {\n this.#watcher\?.close(), this.#watcher = null;\n }\n ref() {\n this.#watcher\?.ref();\n }\n unref() {\n this.#watcher\?.unref();\n }\n start() {\n }\n}\n\nclass StatWatcher extends EventEmitter {\n constructor(path, options) {\n super();\n this._handle = fs.watchFile(path, options, this.#onChange.bind(this));\n }\n #onChange(curr, prev) {\n this.emit(\"change\", curr, prev);\n }\n start() {\n }\n stop() {\n this._handle\?.close(), this._handle = null;\n }\n ref() {\n this._handle\?.ref();\n }\n unref() {\n this._handle\?.unref();\n }\n}\nvar access = function access2(...args) {\n callbackify(fs.accessSync, args);\n}, appendFile = function appendFile2(...args) {\n callbackify(fs.appendFileSync, args);\n}, close = function close2(...args) {\n callbackify(fs.closeSync, args);\n}, rm = function rm2(...args) {\n callbackify(fs.rmSync, args);\n}, rmdir = function rmdir2(...args) {\n callbackify(fs.rmdirSync, args);\n}, copyFile = function copyFile2(...args) {\n const callback = args[args.length - 1];\n if (typeof callback !== \"function\")\n @throwTypeError(\"Callback must be a function\");\n fs.copyFile(...args).then((result) => callback(null, result), callback);\n}, exists = function exists2(...args) {\n callbackify(fs.existsSync, args);\n}, chown = function chown2(...args) {\n callbackify(fs.chownSync, args);\n}, chmod = function chmod2(...args) {\n callbackify(fs.chmodSync, args);\n}, fchmod = function fchmod2(...args) {\n callbackify(fs.fchmodSync, args);\n}, fchown = function fchown2(...args) {\n callbackify(fs.fchownSync, args);\n}, fstat = function fstat2(...args) {\n callbackify(fs.fstatSync, args);\n}, fsync = function fsync2(...args) {\n callbackify(fs.fsyncSync, args);\n}, ftruncate = function ftruncate2(...args) {\n callbackify(fs.ftruncateSync, args);\n}, futimes = function futimes2(...args) {\n callbackify(fs.futimesSync, args);\n}, lchmod = function lchmod2(...args) {\n callbackify(fs.lchmodSync, args);\n}, lchown = function lchown2(...args) {\n callbackify(fs.lchownSync, args);\n}, link = function link2(...args) {\n callbackify(fs.linkSync, args);\n}, mkdir = function mkdir2(...args) {\n callbackify(fs.mkdirSync, args);\n}, mkdtemp = function mkdtemp2(...args) {\n callbackify(fs.mkdtempSync, args);\n}, open = function open2(...args) {\n callbackify(fs.openSync, args);\n}, read = function read2(fd, buffer, offsetOrOptions, length, position, callback) {\n let offset = offsetOrOptions, params = null;\n if (arguments.length <= 4) {\n if (arguments.length === 4)\n callback = length, params = offsetOrOptions;\n else if (arguments.length === 3) {\n if (!isArrayBufferView(buffer))\n params = buffer, { buffer = @Buffer.alloc(16384) } = params \?\? {};\n callback = offsetOrOptions;\n } else\n callback = buffer, buffer = @Buffer.alloc(16384);\n ({ offset = 0, length = buffer\?.byteLength - offset, position = null } = params \?\? {});\n }\n queueMicrotask(() => {\n try {\n var bytesRead = fs.readSync(fd, buffer, offset, length, position);\n } catch (e) {\n callback(e);\n }\n callback(null, bytesRead, buffer);\n });\n}, write = function write2(...args) {\n callbackify(fs.writeSync, args);\n}, readdir = function readdir2(...args) {\n const callback = args[args.length - 1];\n if (typeof callback !== \"function\")\n @throwTypeError(\"Callback must be a function\");\n fs.readdir(...args).then((result) => callback(null, result), callback);\n}, readFile = function readFile2(...args) {\n const callback = args[args.length - 1];\n if (typeof callback !== \"function\")\n @throwTypeError(\"Callback must be a function\");\n fs.readFile(...args).then((result) => callback(null, result), callback);\n}, writeFile = function writeFile2(...args) {\n callbackify(fs.writeFileSync, args);\n}, readlink = function readlink2(...args) {\n callbackify(fs.readlinkSync, args);\n}, realpath = function realpath2(...args) {\n const callback = args[args.length - 1];\n if (typeof callback !== \"function\")\n @throwTypeError(\"Callback must be a function\");\n fs.realpath(...args).then((result) => callback(null, result), callback);\n}, rename = function rename2(...args) {\n callbackify(fs.renameSync, args);\n}, lstat = function lstat2(...args) {\n const callback = args[args.length - 1];\n if (typeof callback !== \"function\")\n @throwTypeError(\"Callback must be a function\");\n fs.lstat(...args).then((result) => callback(null, result), callback);\n}, stat = function stat2(...args) {\n const callback = args[args.length - 1];\n if (typeof callback !== \"function\")\n @throwTypeError(\"Callback must be a function\");\n fs.stat(...args).then((result) => callback(null, result), callback);\n}, symlink = function symlink2(...args) {\n callbackify(fs.symlinkSync, args);\n}, truncate = function truncate2(...args) {\n callbackify(fs.truncateSync, args);\n}, unlink = function unlink2(...args) {\n callbackify(fs.unlinkSync, args);\n}, utimes = function utimes2(...args) {\n callbackify(fs.utimesSync, args);\n}, lutimes = function lutimes2(...args) {\n callbackify(fs.lutimesSync, args);\n}, accessSync = fs.accessSync.bind(fs), appendFileSync = fs.appendFileSync.bind(fs), closeSync = fs.closeSync.bind(fs), copyFileSync = fs.copyFileSync.bind(fs), existsSync = fs.existsSync.bind(fs), chownSync = fs.chownSync.bind(fs), chmodSync = fs.chmodSync.bind(fs), fchmodSync = fs.fchmodSync.bind(fs), fchownSync = fs.fchownSync.bind(fs), fstatSync = fs.fstatSync.bind(fs), fsyncSync = fs.fsyncSync.bind(fs), ftruncateSync = fs.ftruncateSync.bind(fs), futimesSync = fs.futimesSync.bind(fs), lchmodSync = fs.lchmodSync.bind(fs), lchownSync = fs.lchownSync.bind(fs), linkSync = fs.linkSync.bind(fs), lstatSync = fs.lstatSync.bind(fs), mkdirSync = fs.mkdirSync.bind(fs), mkdtempSync = fs.mkdtempSync.bind(fs), openSync = fs.openSync.bind(fs), readSync = fs.readSync.bind(fs), writeSync = fs.writeSync.bind(fs), readdirSync = fs.readdirSync.bind(fs), readFileSync = fs.readFileSync.bind(fs), writeFileSync = fs.writeFileSync.bind(fs), readlinkSync = fs.readlinkSync.bind(fs), realpathSync = fs.realpathSync.bind(fs), renameSync = fs.renameSync.bind(fs), statSync = fs.statSync.bind(fs), symlinkSync = fs.symlinkSync.bind(fs), truncateSync = fs.truncateSync.bind(fs), unlinkSync = fs.unlinkSync.bind(fs), utimesSync = fs.utimesSync.bind(fs), lutimesSync = fs.lutimesSync.bind(fs), rmSync = fs.rmSync.bind(fs), rmdirSync = fs.rmdirSync.bind(fs), writev = (fd, buffers, position, callback) => {\n if (typeof position === \"function\")\n callback = position, position = null;\n queueMicrotask(() => {\n try {\n var written = fs.writevSync(fd, buffers, position);\n } catch (e) {\n callback(e);\n }\n callback(null, written, buffers);\n });\n}, writevSync = fs.writevSync.bind(fs), readv = (fd, buffers, position, callback) => {\n if (typeof position === \"function\")\n callback = position, position = null;\n queueMicrotask(() => {\n try {\n var written = fs.readvSync(fd, buffers, position);\n } catch (e) {\n callback(e);\n }\n callback(null, written, buffers);\n });\n}, readvSync = fs.readvSync.bind(fs), Dirent = fs.Dirent, Stats = fs.Stats, watch = function watch2(path, options, listener) {\n return new FSWatcher(path, options, listener);\n}, statWatchers = new Map, _pathModule, readStreamPathFastPathSymbol = Symbol.for(\"Bun.Node.readStreamPathFastPath\"), readStreamSymbol = Symbol.for(\"Bun.NodeReadStream\"), readStreamPathOrFdSymbol = Symbol.for(\"Bun.NodeReadStreamPathOrFd\"), writeStreamSymbol = Symbol.for(\"Bun.NodeWriteStream\"), writeStreamPathFastPathSymbol = Symbol.for(\"Bun.NodeWriteStreamFastPath\"), writeStreamPathFastPathCallSymbol = Symbol.for(\"Bun.NodeWriteStreamFastPathCall\"), kIoDone = Symbol.for(\"kIoDone\"), defaultReadStreamOptions = {\n file: @undefined,\n fd: null,\n flags: \"r\",\n encoding: @undefined,\n mode: 438,\n autoClose: !0,\n emitClose: !0,\n start: 0,\n end: @Infinity,\n highWaterMark: 65536,\n fs: {\n read,\n open: (path, flags, mode, cb) => {\n var fd;\n try {\n fd = openSync(path, flags, mode);\n } catch (e) {\n cb(e);\n return;\n }\n cb(null, fd);\n },\n openSync,\n close\n },\n autoDestroy: !0\n}, ReadStreamClass;\nReadStream = function(InternalReadStream) {\n ReadStreamClass = InternalReadStream, Object.defineProperty(ReadStreamClass.prototype, Symbol.toStringTag, {\n value: \"ReadStream\",\n enumerable: !1\n });\n function ReadStream3(path, options) {\n return new InternalReadStream(path, options);\n }\n return ReadStream3.prototype = InternalReadStream.prototype, Object.defineProperty(ReadStream3, Symbol.hasInstance, {\n value(instance) {\n return instance instanceof InternalReadStream;\n }\n });\n}(class ReadStream2 extends Stream._getNativeReadableStreamPrototype(2, Stream.Readable) {\n constructor(pathOrFd, options = defaultReadStreamOptions) {\n if (typeof options !== \"object\" || !options)\n @throwTypeError(\"Expected options to be an object\");\n var {\n flags = defaultReadStreamOptions.flags,\n encoding = defaultReadStreamOptions.encoding,\n mode = defaultReadStreamOptions.mode,\n autoClose = defaultReadStreamOptions.autoClose,\n emitClose = defaultReadStreamOptions.emitClose,\n start = defaultReadStreamOptions.start,\n end = defaultReadStreamOptions.end,\n autoDestroy = defaultReadStreamOptions.autoClose,\n fs: fs2 = defaultReadStreamOptions.fs,\n highWaterMark = defaultReadStreamOptions.highWaterMark,\n fd = defaultReadStreamOptions.fd\n } = options;\n if (pathOrFd\?.constructor\?.name === \"URL\")\n pathOrFd = Bun.fileURLToPath(pathOrFd);\n var tempThis = {};\n if (fd != null) {\n if (typeof fd !== \"number\")\n @throwTypeError(\"Expected options.fd to be a number\");\n tempThis.fd = tempThis[readStreamPathOrFdSymbol] = fd, tempThis.autoClose = !1;\n } else if (typeof pathOrFd === \"string\") {\n if (pathOrFd.startsWith(\"file://\"))\n pathOrFd = Bun.fileURLToPath(pathOrFd);\n if (pathOrFd.length === 0)\n @throwTypeError(\"Expected path to be a non-empty string\");\n tempThis.path = tempThis.file = tempThis[readStreamPathOrFdSymbol] = pathOrFd;\n } else if (typeof pathOrFd === \"number\") {\n if (pathOrFd |= 0, pathOrFd < 0)\n @throwTypeError(\"Expected fd to be a positive integer\");\n tempThis.fd = tempThis[readStreamPathOrFdSymbol] = pathOrFd, tempThis.autoClose = !1;\n } else\n @throwTypeError(\"Expected a path or file descriptor\");\n if (tempThis.fd === @undefined)\n tempThis.fd = fs2.openSync(pathOrFd, flags, mode);\n var fileRef = Bun.file(tempThis.fd), stream = fileRef.stream(), native = @direct(stream);\n if (!native)\n throw new Error(\"no native readable stream\");\n var { stream: ptr } = native;\n super(ptr, {\n ...options,\n encoding,\n autoDestroy,\n autoClose,\n emitClose,\n highWaterMark\n });\n if (Object.assign(this, tempThis), this.#fileRef = fileRef, this.end = end, this._read = this.#internalRead, this.start = start, this.flags = flags, this.mode = mode, this.emitClose = emitClose, this[readStreamPathFastPathSymbol] = start === 0 && end === @Infinity && autoClose && fs2 === defaultReadStreamOptions.fs && (encoding === \"buffer\" || encoding === \"binary\" || encoding == null || encoding === \"utf-8\" || encoding === \"utf8\"), this._readableState.autoClose = autoDestroy = autoClose, this._readableState.highWaterMark = highWaterMark, start !== @undefined)\n this.pos = start;\n }\n #fileRef;\n #fs;\n file;\n path;\n fd = null;\n flags;\n mode;\n start;\n end;\n pos;\n bytesRead = 0;\n #fileSize = -1;\n _read;\n [readStreamSymbol] = !0;\n [readStreamPathOrFdSymbol];\n [readStreamPathFastPathSymbol];\n _construct(callback) {\n if (super._construct)\n super._construct(callback);\n else\n callback();\n this.emit(\"open\", this.fd), this.emit(\"ready\");\n }\n _destroy(err, cb) {\n super._destroy(err, cb);\n try {\n var fd = this.fd;\n if (this[readStreamPathFastPathSymbol] = !1, !fd)\n cb(err);\n else\n this.#fs.close(fd, (er) => {\n cb(er || err);\n }), this.fd = null;\n } catch (e) {\n throw e;\n }\n }\n close(cb) {\n if (typeof cb === \"function\")\n Stream.eos(this, cb);\n this.destroy();\n }\n push(chunk) {\n var bytesRead = chunk\?.length \?\? 0;\n if (bytesRead > 0) {\n this.bytesRead += bytesRead;\n var currPos = this.pos;\n if (currPos !== @undefined) {\n if (this.bytesRead < currPos)\n return !0;\n if (currPos === this.start) {\n var n = this.bytesRead - currPos;\n chunk = chunk.slice(-n);\n var [_, ...rest] = arguments;\n if (this.pos = this.bytesRead, this.end !== @undefined && this.bytesRead > this.end)\n chunk = chunk.slice(0, this.end - this.start + 1);\n return super.push(chunk, ...rest);\n }\n var end = this.end;\n if (end !== @undefined && this.bytesRead > end) {\n chunk = chunk.slice(0, end - currPos + 1);\n var [_, ...rest] = arguments;\n return this.pos = this.bytesRead, super.push(chunk, ...rest);\n }\n this.pos = this.bytesRead;\n }\n }\n return super.push(...arguments);\n }\n #internalRead(n) {\n var { pos, end, bytesRead, fd, encoding } = this;\n if (n = pos !== @undefined \? Math.min(end - pos + 1, n) : Math.min(end - bytesRead + 1, n), n <= 0) {\n this.push(null);\n return;\n }\n if (this.#fileSize === -1 && bytesRead === 0 && pos === @undefined) {\n var stat3 = fstatSync(fd);\n if (this.#fileSize = stat3.size, this.#fileSize > 0 && n > this.#fileSize)\n n = this.#fileSize + 1;\n }\n this[kIoDone] = !1;\n var res = super._read(n);\n if (@isPromise(res)) {\n var then = res\?.then;\n if (then && @isCallable(then))\n res.then(() => {\n if (this[kIoDone] = !0, this.destroyed)\n this.emit(kIoDone);\n }, (er) => {\n this[kIoDone] = !0, this.#errorOrDestroy(er);\n });\n } else if (this[kIoDone] = !0, this.destroyed)\n this.emit(kIoDone), this.#errorOrDestroy(new Error(\"ERR_STREAM_PREMATURE_CLOSE\"));\n }\n #errorOrDestroy(err, sync = null) {\n var {\n _readableState: r = { destroyed: !1, autoDestroy: !1 },\n _writableState: w = { destroyed: !1, autoDestroy: !1 }\n } = this;\n if (w\?.destroyed || r\?.destroyed)\n return this;\n if (r\?.autoDestroy || w\?.autoDestroy)\n this.destroy(err);\n else if (err)\n this.emit(\"error\", err);\n }\n pause() {\n return this[readStreamPathFastPathSymbol] = !1, super.pause();\n }\n resume() {\n return this[readStreamPathFastPathSymbol] = !1, super.resume();\n }\n unshift(...args) {\n return this[readStreamPathFastPathSymbol] = !1, super.unshift(...args);\n }\n pipe(dest, pipeOpts) {\n if (this[readStreamPathFastPathSymbol] && (pipeOpts\?.end \?\? !0) && this._readableState\?.pipes\?.length === 0) {\n if ((writeStreamPathFastPathSymbol in dest) && dest[writeStreamPathFastPathSymbol]) {\n if (dest[writeStreamPathFastPathCallSymbol](this, pipeOpts))\n return this;\n }\n }\n return this[readStreamPathFastPathSymbol] = !1, super.pipe(dest, pipeOpts);\n }\n});\nvar defaultWriteStreamOptions = {\n fd: null,\n start: @undefined,\n pos: @undefined,\n encoding: @undefined,\n flags: \"w\",\n mode: 438,\n fs: {\n write,\n close,\n open,\n openSync\n }\n}, WriteStreamClass = WriteStream = function WriteStream2(path, options = defaultWriteStreamOptions) {\n if (!(this instanceof WriteStream2))\n return new WriteStream2(path, options);\n if (!options)\n @throwTypeError(\"Expected options to be an object\");\n var {\n fs: fs2 = defaultWriteStreamOptions.fs,\n start = defaultWriteStreamOptions.start,\n flags = defaultWriteStreamOptions.flags,\n mode = defaultWriteStreamOptions.mode,\n autoClose = !0,\n emitClose = !1,\n autoDestroy = autoClose,\n encoding = defaultWriteStreamOptions.encoding,\n fd = defaultWriteStreamOptions.fd,\n pos = defaultWriteStreamOptions.pos\n } = options, tempThis = {};\n if (fd != null) {\n if (typeof fd !== \"number\")\n throw new Error(\"Expected options.fd to be a number\");\n tempThis.fd = fd, tempThis[_writeStreamPathFastPathSymbol] = !1;\n } else if (typeof path === \"string\") {\n if (path.length === 0)\n @throwTypeError(\"Expected a non-empty path\");\n if (path.startsWith(\"file:\"))\n path = Bun.fileURLToPath(path);\n tempThis.path = path, tempThis.fd = null, tempThis[_writeStreamPathFastPathSymbol] = autoClose && (start === @undefined || start === 0) && fs2.write === defaultWriteStreamOptions.fs.write && fs2.close === defaultWriteStreamOptions.fs.close;\n }\n if (tempThis.fd == null)\n tempThis.fd = fs2.openSync(path, flags, mode);\n if (NativeWritable.call(this, tempThis.fd, {\n ...options,\n decodeStrings: !1,\n autoDestroy,\n emitClose,\n fd: tempThis\n }), Object.assign(this, tempThis), typeof fs2\?.write !== \"function\")\n @throwTypeError(\"Expected fs.write to be a function\");\n if (typeof fs2\?.close !== \"function\")\n @throwTypeError(\"Expected fs.close to be a function\");\n if (typeof fs2\?.open !== \"function\")\n @throwTypeError(\"Expected fs.open to be a function\");\n if (typeof path === \"object\" && path) {\n if (path instanceof URL)\n path = Bun.fileURLToPath(path);\n }\n if (typeof path !== \"string\" && typeof fd !== \"number\")\n @throwTypeError(\"Expected a path or file descriptor\");\n if (this.start = start, this[_fs] = fs2, this.flags = flags, this.mode = mode, this.bytesWritten = 0, this[writeStreamSymbol] = !0, this[kIoDone] = !1, this.start !== @undefined)\n this.pos = this.start;\n if (encoding !== defaultWriteStreamOptions.encoding) {\n if (this.setDefaultEncoding(encoding), encoding !== \"buffer\" && encoding !== \"utf8\" && encoding !== \"utf-8\" && encoding !== \"binary\")\n this[_writeStreamPathFastPathSymbol] = !1;\n }\n return this;\n}, NativeWritable = Stream.NativeWritable, WriteStreamPrototype = WriteStream.prototype = Object.create(NativeWritable.prototype);\nObject.defineProperties(WriteStreamPrototype, {\n autoClose: {\n get() {\n return this._writableState.autoDestroy;\n },\n set(val) {\n this._writableState.autoDestroy = val;\n }\n },\n pending: {\n get() {\n return this.fd === null;\n }\n }\n});\nWriteStreamPrototype.destroySoon = WriteStreamPrototype.end;\nWriteStreamPrototype.open = function open3() {\n};\nWriteStreamPrototype[writeStreamPathFastPathCallSymbol] = function WriteStreamPathFastPathCallSymbol(readStream, pipeOpts) {\n if (!this[_writeStreamPathFastPathSymbol])\n return !1;\n if (this.fd !== null)\n return this[_writeStreamPathFastPathSymbol] = !1, !1;\n return this[kIoDone] = !1, readStream[kIoDone] = !1, Bun.write(this[_writeStreamPathFastPathSymbol], readStream[readStreamPathOrFdSymbol]).then((bytesWritten) => {\n readStream[kIoDone] = this[kIoDone] = !0, this.bytesWritten += bytesWritten, readStream.bytesRead += bytesWritten, this.end(), readStream.close();\n }, (err) => {\n readStream[kIoDone] = this[kIoDone] = !0, WriteStream_errorOrDestroy.call(this, err), readStream.emit(\"error\", err);\n });\n};\nWriteStreamPrototype.isBunFastPathEnabled = function isBunFastPathEnabled() {\n return this[_writeStreamPathFastPathSymbol];\n};\nWriteStreamPrototype.disableBunFastPath = function disableBunFastPath() {\n this[_writeStreamPathFastPathSymbol] = !1;\n};\nWriteStreamPrototype._construct = function _construct(callback) {\n if (typeof this.fd === \"number\") {\n callback();\n return;\n }\n callback(), this.emit(\"open\", this.fd), this.emit(\"ready\");\n};\nWriteStreamPrototype._destroy = function _destroy(err, cb) {\n if (this.fd === null)\n return cb(err);\n if (this[kIoDone]) {\n this.once(kIoDone, () => WriteStream_internalClose.call(this, err, cb));\n return;\n }\n WriteStream_internalClose.call(this, err, cb);\n};\nWriteStreamPrototype.close = function close3(cb) {\n if (cb) {\n if (this.closed) {\n process.nextTick(cb);\n return;\n }\n this.on(\"close\", cb);\n }\n if (!this.autoClose)\n this.on(\"finish\", this.destroy);\n this.end();\n};\nWriteStreamPrototype.write = function write3(chunk, encoding, cb) {\n if (encoding \?\?= this._writableState\?.defaultEncoding, this[_writeStreamPathFastPathSymbol] = !1, typeof chunk === \"string\")\n chunk = @Buffer.from(chunk, encoding);\n var native = this.pos === @undefined;\n const callback = native \? (err, bytes) => {\n if (this[kIoDone] = !1, WriteStream_handleWrite.call(this, err, bytes), this.emit(kIoDone), cb)\n !err \? cb() : cb(err);\n } : () => {\n };\n if (this[kIoDone] = !0, this._write)\n return this._write(chunk, encoding, callback);\n else\n return NativeWritable.prototype.write.call(this, chunk, encoding, callback, native);\n};\nWriteStreamPrototype._write = @undefined;\nWriteStreamPrototype._writev = @undefined;\nWriteStreamPrototype.end = function end(chunk, encoding, cb) {\n var native = this.pos === @undefined;\n return NativeWritable.prototype.end.call(this, chunk, encoding, cb, native);\n};\nWriteStreamPrototype._destroy = function _destroy2(err, cb) {\n this.close(err, cb);\n};\nObject.defineProperties(fs, {\n createReadStream: {\n value: createReadStream\n },\n createWriteStream: {\n value: createWriteStream\n },\n ReadStream: {\n value: ReadStream\n },\n WriteStream: {\n value: WriteStream\n }\n});\nrealpath.native = realpath;\nrealpathSync.native = realpathSync;\nvar lazy_cpSync = null;\n$ = {\n Dirent,\n FSWatcher,\n ReadStream,\n Stats,\n WriteStream,\n _toUnixTimestamp,\n access,\n accessSync,\n appendFile,\n appendFileSync,\n chmod,\n chmodSync,\n chown,\n chownSync,\n close,\n closeSync,\n constants,\n copyFile,\n copyFileSync,\n cp,\n cpSync,\n createReadStream,\n createWriteStream,\n exists,\n existsSync,\n fchmod,\n fchmodSync,\n fchown,\n fchownSync,\n fstat,\n fstatSync,\n fsync,\n fsyncSync,\n ftruncate,\n ftruncateSync,\n futimes,\n futimesSync,\n lchmod,\n lchmodSync,\n lchown,\n lchownSync,\n link,\n linkSync,\n lstat,\n lstatSync,\n lutimes,\n lutimesSync,\n mkdir,\n mkdirSync,\n mkdtemp,\n mkdtempSync,\n open,\n openSync,\n promises,\n read,\n readFile,\n readFileSync,\n readSync,\n readdir,\n readdirSync,\n readlink,\n readlinkSync,\n readv,\n readvSync,\n realpath,\n realpathSync,\n rename,\n renameSync,\n rm,\n rmSync,\n rmdir,\n rmdirSync,\n stat,\n statSync,\n symlink,\n symlinkSync,\n truncate,\n truncateSync,\n unlink,\n unlinkSync,\n unwatchFile,\n utimes,\n utimesSync,\n watch,\n watchFile,\n write,\n writeFile,\n writeFileSync,\n writeSync,\n writev,\n writevSync,\n [Symbol.for(\"::bunternal::\")]: {\n ReadStreamClass,\n WriteStreamClass\n }\n};\nreturn $})\n"_s; +static constexpr ASCIILiteral NodeFSCode = "(function (){\"use strict\";// src/js/out/tmp/node/fs.ts\nvar getValidatedPath = function(p) {\n if (p instanceof URL)\n return Bun.fileURLToPath(p);\n if (typeof p !== \"string\")\n @throwTypeError(\"Path must be a string or URL.\");\n return (_pathModule \?\?= @getInternalField(@internalModuleRegistry, 28) || @createInternalModuleById(28)).resolve(p);\n}, watchFile = function(filename, options, listener) {\n if (filename = getValidatedPath(filename), typeof options === \"function\")\n listener = options, options = {};\n if (typeof listener !== \"function\")\n @throwTypeError(\"listener must be a function\");\n var stat = statWatchers.get(filename);\n if (!stat)\n stat = new StatWatcher(filename, options), statWatchers.set(filename, stat);\n return stat.addListener(\"change\", listener), stat;\n}, unwatchFile = function(filename, listener) {\n filename = getValidatedPath(filename);\n var stat = statWatchers.get(filename);\n if (!stat)\n return;\n if (listener) {\n if (stat.removeListener(\"change\", listener), stat.listenerCount(\"change\") !== 0)\n return;\n } else\n stat.removeAllListeners(\"change\");\n stat.stop(), statWatchers.delete(filename);\n}, callbackify = function(fsFunction, args) {\n const callback = args[args.length - 1];\n try {\n var result = fsFunction.apply(fs, args.slice(0, args.length - 1));\n result.then((...args2) => callback(null, ...args2), (err) => callback(err));\n } catch (e) {\n if (typeof callback === \"function\")\n callback(e);\n else\n throw e;\n }\n}, createReadStream = function(path, options) {\n return new ReadStream(path, options);\n}, WriteStream_handleWrite = function(er, bytes) {\n if (er)\n return WriteStream_errorOrDestroy.call(this, er);\n this.bytesWritten += bytes;\n}, WriteStream_internalClose = function(err, cb) {\n this[_writeStreamPathFastPathSymbol] = !1;\n var fd = this.fd;\n this[_fs].close(fd, (er) => {\n this.fd = null, cb(err || er);\n });\n}, WriteStream_errorOrDestroy = function(err) {\n var {\n _readableState: r = { destroyed: !1, autoDestroy: !1 },\n _writableState: w = { destroyed: !1, autoDestroy: !1 }\n } = this;\n if (w\?.destroyed || r\?.destroyed)\n return this;\n if (r\?.autoDestroy || w\?.autoDestroy)\n this.destroy(err);\n else if (err)\n this.emit(\"error\", err);\n}, createWriteStream = function(path, options) {\n return new WriteStream(path, options);\n}, cpSync = function(src, dest, options) {\n if (!options)\n return fs.cpSync(src, dest);\n if (typeof options !== \"object\")\n @throwTypeError(\"options must be an object\");\n if (options.dereference || options.filter || options.preserveTimestamps || options.verbatimSymlinks) {\n if (!lazy_cpSync)\n lazy_cpSync = @getInternalField(@internalModuleRegistry, 3) || @createInternalModuleById(3);\n return lazy_cpSync(src, dest, options);\n }\n return fs.cpSync(src, dest, options.recursive, options.errorOnExist, options.force \?\? !0, options.mode);\n}, cp = function(src, dest, options, callback) {\n if (typeof options === \"function\")\n callback = options, options = @undefined;\n promises.cp(src, dest, options).then(() => callback(), callback);\n}, _toUnixTimestamp = function(time, name = \"time\") {\n if (typeof time === \"string\" && +time == time)\n return +time;\n if (NumberIsFinite(time)) {\n if (time < 0)\n return DateNow() / 1000;\n return time;\n }\n if (isDate(time))\n return DatePrototypeGetTime(time) / 1000;\n @throwTypeError(`Expected ${name} to be a number or Date`);\n}, $, ReadStream, WriteStream, EventEmitter = @getInternalField(@internalModuleRegistry, 18) || @createInternalModuleById(18), promises = @getInternalField(@internalModuleRegistry, 20) || @createInternalModuleById(20), Stream = @getInternalField(@internalModuleRegistry, 37) || @createInternalModuleById(37), { isArrayBufferView } = @requireNativeModule(\"util/types\"), _writeStreamPathFastPathSymbol = Symbol.for(\"Bun.NodeWriteStreamFastPath\"), _fs = Symbol.for(\"#fs\"), constants = @processBindingConstants.fs, fs = Bun.fs();\n\nclass FSWatcher extends EventEmitter {\n #watcher;\n #listener;\n constructor(path, options, listener) {\n super();\n if (typeof options === \"function\")\n listener = options, options = {};\n else if (typeof options === \"string\")\n options = { encoding: options };\n if (typeof listener !== \"function\")\n listener = () => {\n };\n this.#listener = listener;\n try {\n this.#watcher = fs.watch(path, options || {}, this.#onEvent.bind(this));\n } catch (e) {\n if (!e.message\?.startsWith(\"FileNotFound\"))\n throw e;\n const notFound = new Error(`ENOENT: no such file or directory, watch '${path}'`);\n throw notFound.code = \"ENOENT\", notFound.errno = -2, notFound.path = path, notFound.syscall = \"watch\", notFound.filename = path, notFound;\n }\n }\n #onEvent(eventType, filenameOrError) {\n if (eventType === \"error\" || eventType === \"close\")\n this.emit(eventType, filenameOrError);\n else\n this.emit(\"change\", eventType, filenameOrError), this.#listener(eventType, filenameOrError);\n }\n close() {\n this.#watcher\?.close(), this.#watcher = null;\n }\n ref() {\n this.#watcher\?.ref();\n }\n unref() {\n this.#watcher\?.unref();\n }\n start() {\n }\n}\n\nclass StatWatcher extends EventEmitter {\n constructor(path, options) {\n super();\n this._handle = fs.watchFile(path, options, this.#onChange.bind(this));\n }\n #onChange(curr, prev) {\n this.emit(\"change\", curr, prev);\n }\n start() {\n }\n stop() {\n this._handle\?.close(), this._handle = null;\n }\n ref() {\n this._handle\?.ref();\n }\n unref() {\n this._handle\?.unref();\n }\n}\nvar access = function access2(...args) {\n callbackify(fs.access, args);\n}, appendFile = function appendFile2(...args) {\n callbackify(fs.appendFile, args);\n}, close = function close2(...args) {\n callbackify(fs.close, args);\n}, rm = function rm2(...args) {\n callbackify(fs.rm, args);\n}, rmdir = function rmdir2(...args) {\n callbackify(fs.rmdir, args);\n}, copyFile = function copyFile2(...args) {\n const callback = args[args.length - 1];\n if (typeof callback !== \"function\")\n @throwTypeError(\"Callback must be a function\");\n fs.copyFile(...args).then((result) => callback(null, result), callback);\n}, exists = function exists2(...args) {\n callbackify(fs.exists, args);\n}, chown = function chown2(...args) {\n callbackify(fs.chown, args);\n}, chmod = function chmod2(...args) {\n callbackify(fs.chmod, args);\n}, fchmod = function fchmod2(...args) {\n callbackify(fs.fchmod, args);\n}, fchown = function fchown2(...args) {\n callbackify(fs.fchown, args);\n}, fstat = function fstat2(...args) {\n callbackify(fs.fstat, args);\n}, fsync = function fsync2(...args) {\n callbackify(fs.fsync, args);\n}, ftruncate = function ftruncate2(...args) {\n callbackify(fs.ftruncate, args);\n}, futimes = function futimes2(...args) {\n callbackify(fs.futimes, args);\n}, lchmod = function lchmod2(...args) {\n callbackify(fs.lchmod, args);\n}, lchown = function lchown2(...args) {\n callbackify(fs.lchown, args);\n}, link = function link2(...args) {\n callbackify(fs.link, args);\n}, mkdir = function mkdir2(...args) {\n callbackify(fs.mkdir, args);\n}, mkdtemp = function mkdtemp2(...args) {\n callbackify(fs.mkdtemp, args);\n}, open = function open2(...args) {\n callbackify(fs.open, args);\n}, read = function read2(fd, buffer, offsetOrOptions, length, position, callback) {\n let offset = offsetOrOptions, params = null;\n if (arguments.length <= 4) {\n if (arguments.length === 4)\n callback = length, params = offsetOrOptions;\n else if (arguments.length === 3) {\n if (!isArrayBufferView(buffer))\n params = buffer, { buffer = @Buffer.alloc(16384) } = params \?\? {};\n callback = offsetOrOptions;\n } else\n callback = buffer, buffer = @Buffer.alloc(16384);\n ({ offset = 0, length = buffer\?.byteLength - offset, position = null } = params \?\? {});\n }\n queueMicrotask(() => {\n try {\n var bytesRead = fs.readSync(fd, buffer, offset, length, position);\n } catch (e) {\n callback(e);\n }\n callback(null, bytesRead, buffer);\n });\n}, write = function write2(...args) {\n callbackify(fs.write, args);\n}, readdir = function readdir2(...args) {\n const callback = args[args.length - 1];\n if (typeof callback !== \"function\")\n @throwTypeError(\"Callback must be a function\");\n fs.readdir(...args).then((result) => callback(null, result), callback);\n}, readFile = function readFile2(...args) {\n const callback = args[args.length - 1];\n if (typeof callback !== \"function\")\n @throwTypeError(\"Callback must be a function\");\n fs.readFile(...args).then((result) => callback(null, result), callback);\n}, writeFile = function writeFile2(...args) {\n callbackify(fs.writeFile, args);\n}, readlink = function readlink2(...args) {\n callbackify(fs.readlink, args);\n}, realpath = function realpath2(...args) {\n const callback = args[args.length - 1];\n if (typeof callback !== \"function\")\n @throwTypeError(\"Callback must be a function\");\n fs.realpath(...args).then((result) => callback(null, result), callback);\n}, rename = function rename2(...args) {\n callbackify(fs.rename, args);\n}, lstat = function lstat2(...args) {\n const callback = args[args.length - 1];\n if (typeof callback !== \"function\")\n @throwTypeError(\"Callback must be a function\");\n fs.lstat(...args).then((result) => callback(null, result), callback);\n}, stat = function stat2(...args) {\n const callback = args[args.length - 1];\n if (typeof callback !== \"function\")\n @throwTypeError(\"Callback must be a function\");\n fs.stat(...args).then((result) => callback(null, result), callback);\n}, symlink = function symlink2(...args) {\n callbackify(fs.symlink, args);\n}, truncate = function truncate2(...args) {\n callbackify(fs.truncate, args);\n}, unlink = function unlink2(...args) {\n callbackify(fs.unlink, args);\n}, utimes = function utimes2(...args) {\n callbackify(fs.utimes, args);\n}, lutimes = function lutimes2(...args) {\n callbackify(fs.lutimes, args);\n}, accessSync = fs.accessSync.bind(fs), appendFileSync = fs.appendFileSync.bind(fs), closeSync = fs.closeSync.bind(fs), copyFileSync = fs.copyFileSync.bind(fs), existsSync = fs.existsSync.bind(fs), chownSync = fs.chownSync.bind(fs), chmodSync = fs.chmodSync.bind(fs), fchmodSync = fs.fchmodSync.bind(fs), fchownSync = fs.fchownSync.bind(fs), fstatSync = fs.fstatSync.bind(fs), fsyncSync = fs.fsyncSync.bind(fs), ftruncateSync = fs.ftruncateSync.bind(fs), futimesSync = fs.futimesSync.bind(fs), lchmodSync = fs.lchmodSync.bind(fs), lchownSync = fs.lchownSync.bind(fs), linkSync = fs.linkSync.bind(fs), lstatSync = fs.lstatSync.bind(fs), mkdirSync = fs.mkdirSync.bind(fs), mkdtempSync = fs.mkdtempSync.bind(fs), openSync = fs.openSync.bind(fs), readSync = fs.readSync.bind(fs), writeSync = fs.writeSync.bind(fs), readdirSync = fs.readdirSync.bind(fs), readFileSync = fs.readFileSync.bind(fs), writeFileSync = fs.writeFileSync.bind(fs), readlinkSync = fs.readlinkSync.bind(fs), realpathSync = fs.realpathSync.bind(fs), renameSync = fs.renameSync.bind(fs), statSync = fs.statSync.bind(fs), symlinkSync = fs.symlinkSync.bind(fs), truncateSync = fs.truncateSync.bind(fs), unlinkSync = fs.unlinkSync.bind(fs), utimesSync = fs.utimesSync.bind(fs), lutimesSync = fs.lutimesSync.bind(fs), rmSync = fs.rmSync.bind(fs), rmdirSync = fs.rmdirSync.bind(fs), writev = (fd, buffers, position, callback) => {\n if (typeof position === \"function\")\n callback = position, position = null;\n queueMicrotask(() => {\n try {\n var written = fs.writevSync(fd, buffers, position);\n } catch (e) {\n callback(e);\n }\n callback(null, written, buffers);\n });\n}, writevSync = fs.writevSync.bind(fs), readv = (fd, buffers, position, callback) => {\n if (typeof position === \"function\")\n callback = position, position = null;\n queueMicrotask(() => {\n try {\n var written = fs.readvSync(fd, buffers, position);\n } catch (e) {\n callback(e);\n }\n callback(null, written, buffers);\n });\n}, readvSync = fs.readvSync.bind(fs), Dirent = fs.Dirent, Stats = fs.Stats, watch = function watch2(path, options, listener) {\n return new FSWatcher(path, options, listener);\n}, statWatchers = new Map, _pathModule, readStreamPathFastPathSymbol = Symbol.for(\"Bun.Node.readStreamPathFastPath\"), readStreamSymbol = Symbol.for(\"Bun.NodeReadStream\"), readStreamPathOrFdSymbol = Symbol.for(\"Bun.NodeReadStreamPathOrFd\"), writeStreamSymbol = Symbol.for(\"Bun.NodeWriteStream\"), writeStreamPathFastPathSymbol = Symbol.for(\"Bun.NodeWriteStreamFastPath\"), writeStreamPathFastPathCallSymbol = Symbol.for(\"Bun.NodeWriteStreamFastPathCall\"), kIoDone = Symbol.for(\"kIoDone\"), defaultReadStreamOptions = {\n file: @undefined,\n fd: null,\n flags: \"r\",\n encoding: @undefined,\n mode: 438,\n autoClose: !0,\n emitClose: !0,\n start: 0,\n end: @Infinity,\n highWaterMark: 65536,\n fs: {\n read,\n open: (path, flags, mode, cb) => {\n var fd;\n try {\n fd = openSync(path, flags, mode);\n } catch (e) {\n cb(e);\n return;\n }\n cb(null, fd);\n },\n openSync,\n close\n },\n autoDestroy: !0\n}, ReadStreamClass;\nReadStream = function(InternalReadStream) {\n ReadStreamClass = InternalReadStream, Object.defineProperty(ReadStreamClass.prototype, Symbol.toStringTag, {\n value: \"ReadStream\",\n enumerable: !1\n });\n function ReadStream3(path, options) {\n return new InternalReadStream(path, options);\n }\n return ReadStream3.prototype = InternalReadStream.prototype, Object.defineProperty(ReadStream3, Symbol.hasInstance, {\n value(instance) {\n return instance instanceof InternalReadStream;\n }\n });\n}(class ReadStream2 extends Stream._getNativeReadableStreamPrototype(2, Stream.Readable) {\n constructor(pathOrFd, options = defaultReadStreamOptions) {\n if (typeof options !== \"object\" || !options)\n @throwTypeError(\"Expected options to be an object\");\n var {\n flags = defaultReadStreamOptions.flags,\n encoding = defaultReadStreamOptions.encoding,\n mode = defaultReadStreamOptions.mode,\n autoClose = defaultReadStreamOptions.autoClose,\n emitClose = defaultReadStreamOptions.emitClose,\n start = defaultReadStreamOptions.start,\n end = defaultReadStreamOptions.end,\n autoDestroy = defaultReadStreamOptions.autoClose,\n fs: fs2 = defaultReadStreamOptions.fs,\n highWaterMark = defaultReadStreamOptions.highWaterMark,\n fd = defaultReadStreamOptions.fd\n } = options;\n if (pathOrFd\?.constructor\?.name === \"URL\")\n pathOrFd = Bun.fileURLToPath(pathOrFd);\n var tempThis = {};\n if (fd != null) {\n if (typeof fd !== \"number\")\n @throwTypeError(\"Expected options.fd to be a number\");\n tempThis.fd = tempThis[readStreamPathOrFdSymbol] = fd, tempThis.autoClose = !1;\n } else if (typeof pathOrFd === \"string\") {\n if (pathOrFd.startsWith(\"file://\"))\n pathOrFd = Bun.fileURLToPath(pathOrFd);\n if (pathOrFd.length === 0)\n @throwTypeError(\"Expected path to be a non-empty string\");\n tempThis.path = tempThis.file = tempThis[readStreamPathOrFdSymbol] = pathOrFd;\n } else if (typeof pathOrFd === \"number\") {\n if (pathOrFd |= 0, pathOrFd < 0)\n @throwTypeError(\"Expected fd to be a positive integer\");\n tempThis.fd = tempThis[readStreamPathOrFdSymbol] = pathOrFd, tempThis.autoClose = !1;\n } else\n @throwTypeError(\"Expected a path or file descriptor\");\n if (tempThis.fd === @undefined)\n tempThis.fd = fs2.openSync(pathOrFd, flags, mode);\n var fileRef = Bun.file(tempThis.fd), stream = fileRef.stream(), native = @direct(stream);\n if (!native)\n throw new Error(\"no native readable stream\");\n var { stream: ptr } = native;\n super(ptr, {\n ...options,\n encoding,\n autoDestroy,\n autoClose,\n emitClose,\n highWaterMark\n });\n if (Object.assign(this, tempThis), this.#fileRef = fileRef, this.end = end, this._read = this.#internalRead, this.start = start, this.flags = flags, this.mode = mode, this.emitClose = emitClose, this[readStreamPathFastPathSymbol] = start === 0 && end === @Infinity && autoClose && fs2 === defaultReadStreamOptions.fs && (encoding === \"buffer\" || encoding === \"binary\" || encoding == null || encoding === \"utf-8\" || encoding === \"utf8\"), this._readableState.autoClose = autoDestroy = autoClose, this._readableState.highWaterMark = highWaterMark, start !== @undefined)\n this.pos = start;\n }\n #fileRef;\n #fs;\n file;\n path;\n fd = null;\n flags;\n mode;\n start;\n end;\n pos;\n bytesRead = 0;\n #fileSize = -1;\n _read;\n [readStreamSymbol] = !0;\n [readStreamPathOrFdSymbol];\n [readStreamPathFastPathSymbol];\n _construct(callback) {\n if (super._construct)\n super._construct(callback);\n else\n callback();\n this.emit(\"open\", this.fd), this.emit(\"ready\");\n }\n _destroy(err, cb) {\n super._destroy(err, cb);\n try {\n var fd = this.fd;\n if (this[readStreamPathFastPathSymbol] = !1, !fd)\n cb(err);\n else\n this.#fs.close(fd, (er) => {\n cb(er || err);\n }), this.fd = null;\n } catch (e) {\n throw e;\n }\n }\n close(cb) {\n if (typeof cb === \"function\")\n Stream.eos(this, cb);\n this.destroy();\n }\n push(chunk) {\n var bytesRead = chunk\?.length \?\? 0;\n if (bytesRead > 0) {\n this.bytesRead += bytesRead;\n var currPos = this.pos;\n if (currPos !== @undefined) {\n if (this.bytesRead < currPos)\n return !0;\n if (currPos === this.start) {\n var n = this.bytesRead - currPos;\n chunk = chunk.slice(-n);\n var [_, ...rest] = arguments;\n if (this.pos = this.bytesRead, this.end !== @undefined && this.bytesRead > this.end)\n chunk = chunk.slice(0, this.end - this.start + 1);\n return super.push(chunk, ...rest);\n }\n var end = this.end;\n if (end !== @undefined && this.bytesRead > end) {\n chunk = chunk.slice(0, end - currPos + 1);\n var [_, ...rest] = arguments;\n return this.pos = this.bytesRead, super.push(chunk, ...rest);\n }\n this.pos = this.bytesRead;\n }\n }\n return super.push(...arguments);\n }\n #internalRead(n) {\n var { pos, end, bytesRead, fd, encoding } = this;\n if (n = pos !== @undefined \? Math.min(end - pos + 1, n) : Math.min(end - bytesRead + 1, n), n <= 0) {\n this.push(null);\n return;\n }\n if (this.#fileSize === -1 && bytesRead === 0 && pos === @undefined) {\n var stat3 = fstatSync(fd);\n if (this.#fileSize = stat3.size, this.#fileSize > 0 && n > this.#fileSize)\n n = this.#fileSize + 1;\n }\n this[kIoDone] = !1;\n var res = super._read(n);\n if (@isPromise(res)) {\n var then = res\?.then;\n if (then && @isCallable(then))\n res.then(() => {\n if (this[kIoDone] = !0, this.destroyed)\n this.emit(kIoDone);\n }, (er) => {\n this[kIoDone] = !0, this.#errorOrDestroy(er);\n });\n } else if (this[kIoDone] = !0, this.destroyed)\n this.emit(kIoDone), this.#errorOrDestroy(new Error(\"ERR_STREAM_PREMATURE_CLOSE\"));\n }\n #errorOrDestroy(err, sync = null) {\n var {\n _readableState: r = { destroyed: !1, autoDestroy: !1 },\n _writableState: w = { destroyed: !1, autoDestroy: !1 }\n } = this;\n if (w\?.destroyed || r\?.destroyed)\n return this;\n if (r\?.autoDestroy || w\?.autoDestroy)\n this.destroy(err);\n else if (err)\n this.emit(\"error\", err);\n }\n pause() {\n return this[readStreamPathFastPathSymbol] = !1, super.pause();\n }\n resume() {\n return this[readStreamPathFastPathSymbol] = !1, super.resume();\n }\n unshift(...args) {\n return this[readStreamPathFastPathSymbol] = !1, super.unshift(...args);\n }\n pipe(dest, pipeOpts) {\n if (this[readStreamPathFastPathSymbol] && (pipeOpts\?.end \?\? !0) && this._readableState\?.pipes\?.length === 0) {\n if ((writeStreamPathFastPathSymbol in dest) && dest[writeStreamPathFastPathSymbol]) {\n if (dest[writeStreamPathFastPathCallSymbol](this, pipeOpts))\n return this;\n }\n }\n return this[readStreamPathFastPathSymbol] = !1, super.pipe(dest, pipeOpts);\n }\n});\nvar defaultWriteStreamOptions = {\n fd: null,\n start: @undefined,\n pos: @undefined,\n encoding: @undefined,\n flags: \"w\",\n mode: 438,\n fs: {\n write,\n close,\n open,\n openSync\n }\n}, WriteStreamClass = WriteStream = function WriteStream2(path, options = defaultWriteStreamOptions) {\n if (!(this instanceof WriteStream2))\n return new WriteStream2(path, options);\n if (!options)\n @throwTypeError(\"Expected options to be an object\");\n var {\n fs: fs2 = defaultWriteStreamOptions.fs,\n start = defaultWriteStreamOptions.start,\n flags = defaultWriteStreamOptions.flags,\n mode = defaultWriteStreamOptions.mode,\n autoClose = !0,\n emitClose = !1,\n autoDestroy = autoClose,\n encoding = defaultWriteStreamOptions.encoding,\n fd = defaultWriteStreamOptions.fd,\n pos = defaultWriteStreamOptions.pos\n } = options, tempThis = {};\n if (fd != null) {\n if (typeof fd !== \"number\")\n throw new Error(\"Expected options.fd to be a number\");\n tempThis.fd = fd, tempThis[_writeStreamPathFastPathSymbol] = !1;\n } else if (typeof path === \"string\") {\n if (path.length === 0)\n @throwTypeError(\"Expected a non-empty path\");\n if (path.startsWith(\"file:\"))\n path = Bun.fileURLToPath(path);\n tempThis.path = path, tempThis.fd = null, tempThis[_writeStreamPathFastPathSymbol] = autoClose && (start === @undefined || start === 0) && fs2.write === defaultWriteStreamOptions.fs.write && fs2.close === defaultWriteStreamOptions.fs.close;\n }\n if (tempThis.fd == null)\n tempThis.fd = fs2.openSync(path, flags, mode);\n if (NativeWritable.call(this, tempThis.fd, {\n ...options,\n decodeStrings: !1,\n autoDestroy,\n emitClose,\n fd: tempThis\n }), Object.assign(this, tempThis), typeof fs2\?.write !== \"function\")\n @throwTypeError(\"Expected fs.write to be a function\");\n if (typeof fs2\?.close !== \"function\")\n @throwTypeError(\"Expected fs.close to be a function\");\n if (typeof fs2\?.open !== \"function\")\n @throwTypeError(\"Expected fs.open to be a function\");\n if (typeof path === \"object\" && path) {\n if (path instanceof URL)\n path = Bun.fileURLToPath(path);\n }\n if (typeof path !== \"string\" && typeof fd !== \"number\")\n @throwTypeError(\"Expected a path or file descriptor\");\n if (this.start = start, this[_fs] = fs2, this.flags = flags, this.mode = mode, this.bytesWritten = 0, this[writeStreamSymbol] = !0, this[kIoDone] = !1, this.start !== @undefined)\n this.pos = this.start;\n if (encoding !== defaultWriteStreamOptions.encoding) {\n if (this.setDefaultEncoding(encoding), encoding !== \"buffer\" && encoding !== \"utf8\" && encoding !== \"utf-8\" && encoding !== \"binary\")\n this[_writeStreamPathFastPathSymbol] = !1;\n }\n return this;\n}, NativeWritable = Stream.NativeWritable, WriteStreamPrototype = WriteStream.prototype = Object.create(NativeWritable.prototype);\nObject.defineProperties(WriteStreamPrototype, {\n autoClose: {\n get() {\n return this._writableState.autoDestroy;\n },\n set(val) {\n this._writableState.autoDestroy = val;\n }\n },\n pending: {\n get() {\n return this.fd === null;\n }\n }\n});\nWriteStreamPrototype.destroySoon = WriteStreamPrototype.end;\nWriteStreamPrototype.open = function open3() {\n};\nWriteStreamPrototype[writeStreamPathFastPathCallSymbol] = function WriteStreamPathFastPathCallSymbol(readStream, pipeOpts) {\n if (!this[_writeStreamPathFastPathSymbol])\n return !1;\n if (this.fd !== null)\n return this[_writeStreamPathFastPathSymbol] = !1, !1;\n return this[kIoDone] = !1, readStream[kIoDone] = !1, Bun.write(this[_writeStreamPathFastPathSymbol], readStream[readStreamPathOrFdSymbol]).then((bytesWritten) => {\n readStream[kIoDone] = this[kIoDone] = !0, this.bytesWritten += bytesWritten, readStream.bytesRead += bytesWritten, this.end(), readStream.close();\n }, (err) => {\n readStream[kIoDone] = this[kIoDone] = !0, WriteStream_errorOrDestroy.call(this, err), readStream.emit(\"error\", err);\n });\n};\nWriteStreamPrototype.isBunFastPathEnabled = function isBunFastPathEnabled() {\n return this[_writeStreamPathFastPathSymbol];\n};\nWriteStreamPrototype.disableBunFastPath = function disableBunFastPath() {\n this[_writeStreamPathFastPathSymbol] = !1;\n};\nWriteStreamPrototype._construct = function _construct(callback) {\n if (typeof this.fd === \"number\") {\n callback();\n return;\n }\n callback(), this.emit(\"open\", this.fd), this.emit(\"ready\");\n};\nWriteStreamPrototype._destroy = function _destroy(err, cb) {\n if (this.fd === null)\n return cb(err);\n if (this[kIoDone]) {\n this.once(kIoDone, () => WriteStream_internalClose.call(this, err, cb));\n return;\n }\n WriteStream_internalClose.call(this, err, cb);\n};\nWriteStreamPrototype.close = function close3(cb) {\n if (cb) {\n if (this.closed) {\n process.nextTick(cb);\n return;\n }\n this.on(\"close\", cb);\n }\n if (!this.autoClose)\n this.on(\"finish\", this.destroy);\n this.end();\n};\nWriteStreamPrototype.write = function write3(chunk, encoding, cb) {\n if (encoding \?\?= this._writableState\?.defaultEncoding, this[_writeStreamPathFastPathSymbol] = !1, typeof chunk === \"string\")\n chunk = @Buffer.from(chunk, encoding);\n var native = this.pos === @undefined;\n const callback = native \? (err, bytes) => {\n if (this[kIoDone] = !1, WriteStream_handleWrite.call(this, err, bytes), this.emit(kIoDone), cb)\n !err \? cb() : cb(err);\n } : () => {\n };\n if (this[kIoDone] = !0, this._write)\n return this._write(chunk, encoding, callback);\n else\n return NativeWritable.prototype.write.call(this, chunk, encoding, callback, native);\n};\nWriteStreamPrototype._write = @undefined;\nWriteStreamPrototype._writev = @undefined;\nWriteStreamPrototype.end = function end(chunk, encoding, cb) {\n var native = this.pos === @undefined;\n return NativeWritable.prototype.end.call(this, chunk, encoding, cb, native);\n};\nWriteStreamPrototype._destroy = function _destroy2(err, cb) {\n this.close(err, cb);\n};\nObject.defineProperties(fs, {\n createReadStream: {\n value: createReadStream\n },\n createWriteStream: {\n value: createWriteStream\n },\n ReadStream: {\n value: ReadStream\n },\n WriteStream: {\n value: WriteStream\n }\n});\nrealpath.native = realpath;\nrealpathSync.native = realpathSync;\nvar lazy_cpSync = null;\n$ = {\n Dirent,\n FSWatcher,\n ReadStream,\n Stats,\n WriteStream,\n _toUnixTimestamp,\n access,\n accessSync,\n appendFile,\n appendFileSync,\n chmod,\n chmodSync,\n chown,\n chownSync,\n close,\n closeSync,\n constants,\n copyFile,\n copyFileSync,\n cp,\n cpSync,\n createReadStream,\n createWriteStream,\n exists,\n existsSync,\n fchmod,\n fchmodSync,\n fchown,\n fchownSync,\n fstat,\n fstatSync,\n fsync,\n fsyncSync,\n ftruncate,\n ftruncateSync,\n futimes,\n futimesSync,\n lchmod,\n lchmodSync,\n lchown,\n lchownSync,\n link,\n linkSync,\n lstat,\n lstatSync,\n lutimes,\n lutimesSync,\n mkdir,\n mkdirSync,\n mkdtemp,\n mkdtempSync,\n open,\n openSync,\n promises,\n read,\n readFile,\n readFileSync,\n readSync,\n readdir,\n readdirSync,\n readlink,\n readlinkSync,\n readv,\n readvSync,\n realpath,\n realpathSync,\n rename,\n renameSync,\n rm,\n rmSync,\n rmdir,\n rmdirSync,\n stat,\n statSync,\n symlink,\n symlinkSync,\n truncate,\n truncateSync,\n unlink,\n unlinkSync,\n unwatchFile,\n utimes,\n utimesSync,\n watch,\n watchFile,\n write,\n writeFile,\n writeFileSync,\n writeSync,\n writev,\n writevSync,\n [Symbol.for(\"::bunternal::\")]: {\n ReadStreamClass,\n WriteStreamClass\n }\n};\nreturn $})\n"_s; // // -static constexpr ASCIILiteral NodeFSPromisesCode = "(function (){\"use strict\";// src/js/out/tmp/node/fs.promises.ts\nvar watch = function(filename, options = {}) {\n if (filename instanceof URL)\n @throwTypeError(\"Watch URLs are not supported yet\");\n else if (@Buffer.isBuffer(filename))\n filename = filename.toString();\n else if (typeof filename !== \"string\")\n @throwTypeError(\"Expected path to be a string or Buffer\");\n let nextEventResolve = null;\n if (typeof options === \"string\")\n options = { encoding: options };\n const queue = @createFIFO(), watcher = fs.watch(filename, options || {}, (eventType, filename2) => {\n if (queue.push({ eventType, filename: filename2 }), nextEventResolve) {\n const resolve = nextEventResolve;\n nextEventResolve = null, resolve();\n }\n });\n return {\n [Symbol.asyncIterator]() {\n let closed = !1;\n return {\n async next() {\n while (!closed) {\n let event;\n while (event = queue.shift()) {\n if (event.eventType === \"close\")\n return closed = !0, { value: @undefined, done: !0 };\n if (event.eventType === \"error\")\n throw closed = !0, event.filename;\n return { value: event, done: !1 };\n }\n const { promise, resolve } = @Promise.withResolvers();\n nextEventResolve = resolve, await promise;\n }\n return { value: @undefined, done: !0 };\n },\n return() {\n if (!closed) {\n if (watcher.close(), closed = !0, nextEventResolve) {\n const resolve = nextEventResolve;\n nextEventResolve = null, resolve();\n }\n }\n return { value: @undefined, done: !0 };\n }\n };\n }\n };\n}, cp = function(src, dest, options) {\n if (!options)\n return fs.cp(src, dest);\n if (typeof options !== \"object\")\n @throwTypeError(\"options must be an object\");\n if (options.dereference || options.filter || options.preserveTimestamps || options.verbatimSymlinks) {\n if (!lazy_cp)\n lazy_cp = @getInternalField(@internalModuleRegistry, 3) || @createInternalModuleById(3);\n return lazy_cp(src, dest, options);\n }\n return fs.cp(src, dest, options.recursive, options.errorOnExist, options.force \?\? !0, options.mode);\n};\nasync function opendir(dir) {\n const entries = await fs.readdir(dir, { withFileTypes: !0 });\n return new Dir(entries);\n}\nvar $, constants = @processBindingConstants.fs, fs = Bun.fs(), notrace = \"::bunternal::\", promisify = {\n [notrace]: (fsFunction) => {\n return async function(...args) {\n return await 1, fsFunction.apply(fs, args);\n };\n }\n}[notrace], lazy_cp = null;\n\nclass Dir {\n #entries;\n constructor(e) {\n this.#entries = e;\n }\n readSync() {\n return this.#entries.shift() \?\? null;\n }\n read(c) {\n if (c)\n process.nextTick(c, null, this.readSync());\n return @Promise.resolve(this.readSync());\n }\n closeSync() {\n }\n close(c) {\n if (c)\n process.nextTick(c);\n return @Promise.resolve();\n }\n *[Symbol.asyncIterator]() {\n var next;\n while (next = this.readSync())\n yield next;\n }\n}\n$ = {\n access: promisify(fs.accessSync),\n appendFile: promisify(fs.appendFileSync),\n close: promisify(fs.closeSync),\n copyFile: fs.copyFile.bind(fs),\n cp,\n exists: promisify(fs.existsSync),\n chown: promisify(fs.chownSync),\n chmod: promisify(fs.chmodSync),\n fchmod: promisify(fs.fchmodSync),\n fchown: promisify(fs.fchownSync),\n fstat: promisify(fs.fstatSync),\n fsync: promisify(fs.fsyncSync),\n ftruncate: promisify(fs.ftruncateSync),\n futimes: promisify(fs.futimesSync),\n lchmod: promisify(fs.lchmodSync),\n lchown: promisify(fs.lchownSync),\n link: promisify(fs.linkSync),\n lstat: fs.lstat.bind(fs),\n mkdir: promisify(fs.mkdirSync),\n mkdtemp: promisify(fs.mkdtempSync),\n open: promisify(fs.openSync),\n read: promisify(fs.readSync),\n write: promisify(fs.writeSync),\n readdir: fs.readdir.bind(fs),\n readFile: fs.readFile.bind(fs),\n writeFile: promisify(fs.writeFileSync),\n readlink: promisify(fs.readlinkSync),\n realpath: fs.realpath.bind(fs),\n rename: promisify(fs.renameSync),\n stat: fs.stat.bind(fs),\n symlink: promisify(fs.symlinkSync),\n truncate: promisify(fs.truncateSync),\n unlink: promisify(fs.unlinkSync),\n utimes: promisify(fs.utimesSync),\n lutimes: promisify(fs.lutimesSync),\n rm: promisify(fs.rmSync),\n rmdir: promisify(fs.rmdirSync),\n writev: (fd, buffers, position) => {\n return new @Promise((resolve, reject) => {\n try {\n var bytesWritten = fs.writevSync(fd, buffers, position);\n } catch (err) {\n reject(err);\n return;\n }\n resolve({\n bytesWritten,\n buffers\n });\n });\n },\n readv: (fd, buffers, position) => {\n return new @Promise((resolve, reject) => {\n try {\n var bytesRead = fs.readvSync(fd, buffers, position);\n } catch (err) {\n reject(err);\n return;\n }\n resolve({\n bytesRead,\n buffers\n });\n });\n },\n constants,\n watch,\n opendir\n};\nreturn $})\n"_s; +static constexpr ASCIILiteral NodeFSPromisesCode = "(function (){\"use strict\";// src/js/out/tmp/node/fs.promises.ts\nvar watch = function(filename, options = {}) {\n if (filename instanceof URL)\n @throwTypeError(\"Watch URLs are not supported yet\");\n else if (@Buffer.isBuffer(filename))\n filename = filename.toString();\n else if (typeof filename !== \"string\")\n @throwTypeError(\"Expected path to be a string or Buffer\");\n let nextEventResolve = null;\n if (typeof options === \"string\")\n options = { encoding: options };\n const queue = @createFIFO(), watcher = fs.watch(filename, options || {}, (eventType, filename2) => {\n if (queue.push({ eventType, filename: filename2 }), nextEventResolve) {\n const resolve = nextEventResolve;\n nextEventResolve = null, resolve();\n }\n });\n return {\n [Symbol.asyncIterator]() {\n let closed = !1;\n return {\n async next() {\n while (!closed) {\n let event;\n while (event = queue.shift()) {\n if (event.eventType === \"close\")\n return closed = !0, { value: @undefined, done: !0 };\n if (event.eventType === \"error\")\n throw closed = !0, event.filename;\n return { value: event, done: !1 };\n }\n const { promise, resolve } = @Promise.withResolvers();\n nextEventResolve = resolve, await promise;\n }\n return { value: @undefined, done: !0 };\n },\n return() {\n if (!closed) {\n if (watcher.close(), closed = !0, nextEventResolve) {\n const resolve = nextEventResolve;\n nextEventResolve = null, resolve();\n }\n }\n return { value: @undefined, done: !0 };\n }\n };\n }\n };\n}, cp = function(src, dest, options) {\n if (!options)\n return fs.cp(src, dest);\n if (typeof options !== \"object\")\n @throwTypeError(\"options must be an object\");\n if (options.dereference || options.filter || options.preserveTimestamps || options.verbatimSymlinks) {\n if (!lazy_cp)\n lazy_cp = @getInternalField(@internalModuleRegistry, 3) || @createInternalModuleById(3);\n return lazy_cp(src, dest, options);\n }\n return fs.cp(src, dest, options.recursive, options.errorOnExist, options.force \?\? !0, options.mode);\n};\nasync function opendir(dir) {\n const entries = await fs.readdir(dir, { withFileTypes: !0 });\n return new Dir(entries);\n}\nvar $, constants = @processBindingConstants.fs, fs = Bun.fs();\nvar lazy_cp = null;\n\nclass Dir {\n #entries;\n constructor(e) {\n this.#entries = e;\n }\n readSync() {\n return this.#entries.shift() \?\? null;\n }\n read(c) {\n if (c)\n process.nextTick(c, null, this.readSync());\n return @Promise.resolve(this.readSync());\n }\n closeSync() {\n }\n close(c) {\n if (c)\n process.nextTick(c);\n return @Promise.resolve();\n }\n *[Symbol.asyncIterator]() {\n var next;\n while (next = this.readSync())\n yield next;\n }\n}\n$ = {\n access: fs.access.bind(fs),\n appendFile: fs.appendFile.bind(fs),\n close: fs.close.bind(fs),\n copyFile: fs.copyFile.bind(fs),\n cp,\n exists: fs.exists.bind(fs),\n chown: fs.chown.bind(fs),\n chmod: fs.chmod.bind(fs),\n fchmod: fs.fchmod.bind(fs),\n fchown: fs.fchown.bind(fs),\n fstat: fs.fstat.bind(fs),\n fsync: fs.fsync.bind(fs),\n ftruncate: fs.ftruncate.bind(fs),\n futimes: fs.futimes.bind(fs),\n lchmod: fs.lchmod.bind(fs),\n lchown: fs.lchown.bind(fs),\n link: fs.link.bind(fs),\n lstat: fs.lstat.bind(fs),\n mkdir: fs.mkdir.bind(fs),\n mkdtemp: fs.mkdtemp.bind(fs),\n open: fs.open.bind(fs),\n read: fs.read.bind(fs),\n write: fs.write.bind(fs),\n readdir: fs.readdir.bind(fs),\n readFile: fs.readFile.bind(fs),\n writeFile: fs.writeFile.bind(fs),\n readlink: fs.readlink.bind(fs),\n realpath: fs.realpath.bind(fs),\n rename: fs.rename.bind(fs),\n stat: fs.stat.bind(fs),\n symlink: fs.symlink.bind(fs),\n truncate: fs.truncate.bind(fs),\n unlink: fs.unlink.bind(fs),\n utimes: fs.utimes.bind(fs),\n lutimes: fs.lutimes.bind(fs),\n rm: fs.rm.bind(fs),\n rmdir: fs.rmdir.bind(fs),\n writev: async (fd, buffers, position) => {\n var bytesWritten = await fs.writev(fd, buffers, position);\n return {\n bytesWritten,\n buffers\n };\n },\n readv: async (fd, buffers, position) => {\n var bytesRead = await fs.readv(fd, buffers, position);\n return {\n bytesRead,\n buffers\n };\n },\n constants,\n watch,\n opendir\n};\nreturn $})\n"_s; // // |