aboutsummaryrefslogtreecommitdiff
path: root/src/bun.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/bun.js')
-rw-r--r--src/bun.js/api/bun.zig3
-rw-r--r--src/bun.js/api/server.zig22
-rw-r--r--src/bun.js/javascript.zig5
-rw-r--r--src/bun.js/node/node_fs.zig30
-rw-r--r--src/bun.js/webcore/blob.zig36
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,