diff options
Diffstat (limited to 'src/bun.js')
-rw-r--r-- | src/bun.js/api/bun.zig | 3 | ||||
-rw-r--r-- | src/bun.js/api/server.zig | 22 | ||||
-rw-r--r-- | src/bun.js/javascript.zig | 5 | ||||
-rw-r--r-- | src/bun.js/node/node_fs.zig | 30 | ||||
-rw-r--r-- | src/bun.js/webcore/blob.zig | 36 |
5 files changed, 80 insertions, 16 deletions
diff --git a/src/bun.js/api/bun.zig b/src/bun.js/api/bun.zig index 034aaa81f..2e6381c74 100644 --- a/src/bun.js/api/bun.zig +++ b/src/bun.js/api/bun.zig @@ -896,6 +896,9 @@ pub fn createNodeFS( ) js.JSValueRef { var module = ctx.allocator().create(JSC.Node.NodeJSFS) catch unreachable; module.* = .{}; + var vm = ctx.bunVM(); + if (vm.standalone_module_graph != null) + module.node_fs.vm = vm; return module.toJS(ctx).asObjectRef(); } diff --git a/src/bun.js/api/server.zig b/src/bun.js/api/server.zig index a56ff971f..ebfacdcc9 100644 --- a/src/bun.js/api/server.zig +++ b/src/bun.js/api/server.zig @@ -2744,19 +2744,15 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp // 1. Bun.file("foo") // 2. The content-disposition header is not present if (!has_content_disposition and content_type.category.autosetFilename()) { - if (this.blob.store()) |store| { - if (store.data == .file) { - if (store.data.file.pathlike == .path) { - const basename = std.fs.path.basename(store.data.file.pathlike.path.slice()); - if (basename.len > 0) { - var filename_buf: [1024]u8 = undefined; - - resp.writeHeader( - "content-disposition", - std.fmt.bufPrint(&filename_buf, "filename=\"{s}\"", .{basename[0..@min(basename.len, 1024 - 32)]}) catch "", - ); - } - } + if (this.blob.getFileName()) |filename| { + const basename = std.fs.path.basename(filename); + if (basename.len > 0) { + var filename_buf: [1024]u8 = undefined; + + resp.writeHeader( + "content-disposition", + std.fmt.bufPrint(&filename_buf, "filename=\"{s}\"", .{basename[0..@min(basename.len, 1024 - 32)]}) catch "", + ); } } } diff --git a/src/bun.js/javascript.zig b/src/bun.js/javascript.zig index 3baa25e22..cb1a50f1d 100644 --- a/src/bun.js/javascript.zig +++ b/src/bun.js/javascript.zig @@ -593,7 +593,10 @@ pub const VirtualMachine = struct { pub inline fn nodeFS(this: *VirtualMachine) *Node.NodeFS { return this.node_fs orelse brk: { this.node_fs = bun.default_allocator.create(Node.NodeFS) catch unreachable; - this.node_fs.?.* = Node.NodeFS{}; + this.node_fs.?.* = Node.NodeFS{ + // only used when standalone module graph is enabled + .vm = if (this.standalone_module_graph != null) this else null, + }; break :brk this.node_fs.?; }; } diff --git a/src/bun.js/node/node_fs.zig b/src/bun.js/node/node_fs.zig index 21a65251a..35c616a89 100644 --- a/src/bun.js/node/node_fs.zig +++ b/src/bun.js/node/node_fs.zig @@ -2492,6 +2492,7 @@ pub const NodeFS = struct { /// That means a stack-allocated buffer won't suffice. Instead, we re-use /// the heap allocated buffer on the NodefS struct sync_error_buf: [bun.MAX_PATH_BYTES]u8 = undefined, + vm: ?*JSC.VirtualMachine = null, pub const ReturnType = Return; @@ -3442,6 +3443,35 @@ pub const NodeFS = struct { const fd = switch (args.path) { .path => brk: { path = args.path.path.sliceZ(&this.sync_error_buf); + if (this.vm) |vm| { + if (vm.standalone_module_graph) |graph| { + if (graph.find(path)) |file| { + if (args.encoding == .buffer) { + return .{ + .result = .{ + .buffer = Buffer.fromBytes( + bun.default_allocator.dupe(u8, file.contents) catch @panic("out of memory"), + bun.default_allocator, + .Uint8Array, + ), + }, + }; + } else if (comptime string_type == .default) + .{ + .result = .{ + .string = bun.default_allocator.dupe(u8, file.contents) catch @panic("out of memory"), + }, + } + else + .{ + .result = .{ + .null_terminated = bun.default_allocator.dupeZ(u8, file.contents) catch @panic("out of memory"), + }, + }; + } + } + } + break :brk switch (Syscall.open( path, os.O.RDONLY | os.O.NOCTTY, diff --git a/src/bun.js/webcore/blob.zig b/src/bun.js/webcore/blob.zig index 1e63ea3a2..868acbb80 100644 --- a/src/bun.js/webcore/blob.zig +++ b/src/bun.js/webcore/blob.zig @@ -952,6 +952,13 @@ pub const Blob = struct { switch (path_) { .path => { const slice = path_.path.slice(); + + if (vm.standalone_module_graph) |graph| { + if (graph.find(slice)) |file| { + return file.blob(globalThis).dupe(); + } + } + var cloned = (allocator.dupeZ(u8, slice) catch unreachable)[0..slice.len]; break :brk .{ @@ -2195,6 +2202,9 @@ pub const Blob = struct { cap: SizeType = 0, allocator: std.mem.Allocator, + /// Used by standalone module graph + stored_name: bun.PathString = bun.PathString.empty, + pub fn init(bytes: []u8, allocator: std.mem.Allocator) ByteStore { return .{ .ptr = bytes.ptr, @@ -2528,17 +2538,31 @@ pub const Blob = struct { this: *Blob, globalThis: *JSC.JSGlobalObject, ) callconv(.C) JSValue { + if (this.getFileName()) |path| { + var str = bun.String.create(path); + return str.toJS(globalThis); + } + + return JSValue.undefined; + } + + pub fn getFileName( + this: *const Blob, + ) ?[]const u8 { if (this.store) |store| { if (store.data == .file) { if (store.data.file.pathlike == .path) { - return ZigString.fromUTF8(store.data.file.pathlike.path.slice()).toValueGC(globalThis); + return store.data.file.pathlike.path.slice(); } // we shouldn't return Number here. + } else if (store.data == .bytes) { + if (store.data.bytes.stored_name.slice().len > 0) + return store.data.bytes.stored_name.slice(); } } - return JSC.JSValue.jsUndefined(); + return null; } // TODO: Move this to a separate `File` object or BunFile @@ -3469,6 +3493,14 @@ pub const AnyBlob = union(enum) { InternalBlob: InternalBlob, WTFStringImpl: bun.WTF.StringImpl, + pub fn getFileName(this: *const AnyBlob) ?[]const u8 { + return switch (this.*) { + .Blob => this.Blob.getFileName(), + .WTFStringImpl => null, + .InternalBlob => null, + }; + } + pub inline fn fastSize(this: *const AnyBlob) Blob.SizeType { return switch (this.*) { .Blob => this.Blob.size, |