From e69e7e96b9a2268c2133f1fd314cfc54db486db2 Mon Sep 17 00:00:00 2001 From: Jarred Sumner Date: Thu, 7 Mar 2024 17:10:10 -0800 Subject: [PATCH] Make a couple shell tests pass --- src/bun.js/bindings/bindings.zig | 12 +++++++++++ src/shell/interpreter.zig | 35 +++++++++++++++++++++++++++++++- 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/src/bun.js/bindings/bindings.zig b/src/bun.js/bindings/bindings.zig index a19dafc787..96355e8ee1 100644 --- a/src/bun.js/bindings/bindings.zig +++ b/src/bun.js/bindings/bindings.zig @@ -3766,6 +3766,18 @@ pub const JSValue = enum(JSValueReprInt) { return FetchHeaders.cast(value); } + if (comptime ZigType == JSC.WebCore.Body.Value) { + if (value.as(JSC.WebCore.Request)) |req| { + return req.getBodyValue(); + } + + if (value.as(JSC.WebCore.Response)) |res| { + return res.getBodyValue(); + } + + return null; + } + if (comptime @hasDecl(ZigType, "fromJS") and @TypeOf(ZigType.fromJS) == fn (JSC.JSValue) ?*ZigType) { if (comptime ZigType == JSC.WebCore.Blob) { if (ZigType.fromJS(value)) |blob| { diff --git a/src/shell/interpreter.zig b/src/shell/interpreter.zig index 71574ae200..9c6be0ed43 100644 --- a/src/shell/interpreter.zig +++ b/src/shell/interpreter.zig @@ -1037,7 +1037,8 @@ pub const Interpreter = struct { // This will save ~2x memory var export_env = EnvMap.initWithCapacity(allocator, env_loader.map.map.unmanaged.entries.len); - var iter = env_loader.map.iterator(); + var iter = env_loader.iterator(); + while (iter.next()) |entry| { const value = EnvStr.initSlice(entry.value_ptr.value); const key = EnvStr.initSlice(entry.key_ptr.*); @@ -4265,7 +4266,39 @@ pub const Interpreter = struct { cmd.exec.bltn.stderr.deref(); cmd.exec.bltn.stderr = .{ .arraybuf = arraybuf }; } + } else if (interpreter.jsobjs[file.jsbuf.idx].as(JSC.WebCore.Body.Value)) |body| { + if ((node.redirect.stdout or node.redirect.stderr) and !(body.* == .Blob and !body.Blob.needsToReadFile())) { + // TODO: Locked->stream -> file -> blob conversion via .toBlobIfPossible() except we want to avoid modifying the Response/Request if unnecessary. + cmd.base.interpreter.event_loop.js.global.throw("Cannot redirect stdout/stderr to an immutable blob. Expected a file", .{}); + return .yield; + } + + var original_blob = body.use(); + defer original_blob.deinit(); + + const blob: *bun.JSC.WebCore.Blob = bun.newWithAlloc(arena.allocator(), JSC.WebCore.Blob, original_blob.dupe()); + + if (node.redirect.stdin) { + cmd.exec.bltn.stdin.deref(); + cmd.exec.bltn.stdin = .{ .blob = blob }; + } + + if (node.redirect.stdout) { + cmd.exec.bltn.stdout.deref(); + cmd.exec.bltn.stdout = .{ .blob = blob }; + } + + if (node.redirect.stderr) { + cmd.exec.bltn.stderr.deref(); + cmd.exec.bltn.stderr = .{ .blob = blob }; + } } else if (interpreter.jsobjs[file.jsbuf.idx].as(JSC.WebCore.Blob)) |blob| { + if ((node.redirect.stdout or node.redirect.stderr) and !blob.needsToReadFile()) { + // TODO: Locked->stream -> file -> blob conversion via .toBlobIfPossible() except we want to avoid modifying the Response/Request if unnecessary. + cmd.base.interpreter.event_loop.js.global.throw("Cannot redirect stdout/stderr to an immutable blob. Expected a file", .{}); + return .yield; + } + const theblob: *bun.JSC.WebCore.Blob = bun.newWithAlloc(arena.allocator(), JSC.WebCore.Blob, blob.dupe()); if (node.redirect.stdin) {