mirror of
https://github.com/oven-sh/bun
synced 2026-02-09 10:28:47 +00:00
[bun.js] Bun.write for macOS
This commit is contained in:
@@ -42,6 +42,19 @@ describe("HTMLRewriter", () => {
|
||||
expect(await output.text()).toBe("<div><blink>it worked!</blink></div>");
|
||||
});
|
||||
|
||||
it("(from file) supports element handlers", async () => {
|
||||
var rewriter = new HTMLRewriter();
|
||||
rewriter.on("div", {
|
||||
element(element) {
|
||||
element.setInnerContent("<blink>it worked!</blink>", { html: true });
|
||||
},
|
||||
});
|
||||
await Bun.write("/tmp/html-rewriter.txt.js", "<div>hello</div>");
|
||||
var input = new Response(Bun.file("/tmp/html-rewriter.txt.js"));
|
||||
var output = rewriter.transform(input);
|
||||
expect(await output.text()).toBe("<div><blink>it worked!</blink></div>");
|
||||
});
|
||||
|
||||
it("supports attribute iterator", async () => {
|
||||
var rewriter = new HTMLRewriter();
|
||||
var expected = [
|
||||
|
||||
@@ -10,12 +10,32 @@ it("Bun.write('out.txt', 'string')", async () => {
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
const out = await Bun.write("/tmp/out.txt", "string");
|
||||
await Bun.write("/tmp/out.txt", "string");
|
||||
const out = Bun.file("/tmp/out.txt");
|
||||
expect(await out.text()).toBe("string");
|
||||
expect(await out.text()).toBe(fs.readFileSync("/tmp/out.txt", "utf8"));
|
||||
}
|
||||
});
|
||||
|
||||
it("Bun.write blob", async () => {
|
||||
await Bun.write(
|
||||
Bun.file("/tmp/response-file.test.txt"),
|
||||
Bun.file(path.join(import.meta.dir, "fetch.js.txt"))
|
||||
);
|
||||
await Bun.write(Bun.file("/tmp/response-file.test.txt"), "blah blah blha");
|
||||
await Bun.write(
|
||||
Bun.file("/tmp/response-file.test.txt"),
|
||||
new Uint32Array(1024)
|
||||
);
|
||||
await Bun.write("/tmp/response-file.test.txt", new Uint32Array(1024));
|
||||
expect(
|
||||
await Bun.write(
|
||||
new TextEncoder().encode("/tmp/response-file.test.txt"),
|
||||
new Uint32Array(1024)
|
||||
)
|
||||
).toBe(new Uint32Array(1024).byteLength);
|
||||
});
|
||||
|
||||
it("Bun.file -> Bun.file", async () => {
|
||||
try {
|
||||
fs.unlinkSync(path.join("/tmp", "fetch.js.in"));
|
||||
@@ -33,23 +53,22 @@ it("Bun.file -> Bun.file", async () => {
|
||||
Bun.file("/tmp/fetch.js.out"),
|
||||
Bun.file("/tmp/fetch.js.in")
|
||||
);
|
||||
expect(await result.text()).toBe(text);
|
||||
expect(await Bun.file("/tmp/fetch.js.out").text()).toBe(text);
|
||||
}
|
||||
|
||||
{
|
||||
const result = await Bun.write(
|
||||
await Bun.write(
|
||||
Bun.file("/tmp/fetch.js.in").slice(0, (text.length / 2) | 0),
|
||||
Bun.file("/tmp/fetch.js.out")
|
||||
);
|
||||
expect(await result.text()).toBe(text.substring(0, (text.length / 2) | 0));
|
||||
expect(await Bun.file("/tmp/fetch.js.in").text()).toBe(
|
||||
text.substring(0, (text.length / 2) | 0)
|
||||
);
|
||||
}
|
||||
|
||||
{
|
||||
const result = await Bun.write(
|
||||
"/tmp/fetch.js.in",
|
||||
Bun.file("/tmp/fetch.js.out")
|
||||
);
|
||||
expect(await result.text()).toBe(text);
|
||||
await Bun.write("/tmp/fetch.js.in", Bun.file("/tmp/fetch.js.out"));
|
||||
expect(await Bun.file("/tmp/fetch.js.in").text()).toBe(text);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -99,6 +118,19 @@ it("Response -> Bun.file", async () => {
|
||||
expect(await response.text()).toBe(text);
|
||||
});
|
||||
|
||||
it("Bun.file -> Response", async () => {
|
||||
// ensure the file doesn't already exist
|
||||
try {
|
||||
fs.unlinkSync("/tmp/fetch.js.out");
|
||||
} catch {}
|
||||
|
||||
const file = path.join(import.meta.dir, "fetch.js.txt");
|
||||
const text = fs.readFileSync(file, "utf8");
|
||||
const resp = await fetch("https://example.com");
|
||||
expect(await Bun.write("/tmp/fetch.js.out", resp)).toBe(text.length);
|
||||
expect(await Bun.file("/tmp/fetch.js.out").text()).toBe(text);
|
||||
});
|
||||
|
||||
it("Response -> Bun.file -> Response -> text", async () => {
|
||||
const file = path.join(import.meta.dir, "fetch.js.txt");
|
||||
const text = fs.readFileSync(file, "utf8");
|
||||
|
||||
@@ -1 +1 @@
|
||||
3c32b2da4ba87f18
|
||||
871e1d1d6a2e7805
|
||||
@@ -303,7 +303,7 @@ pub const HTMLRewriter = struct {
|
||||
const is_pending = input.needsToReadFile();
|
||||
defer if (!is_pending) input.detach();
|
||||
|
||||
if (input.needsToReadFile()) {
|
||||
if (is_pending) {
|
||||
input.doReadFileInternal(*BufferOutputSink, sink, onFinishedLoadingWrap, global);
|
||||
} else if (sink.runOutputSink(input.sharedView(), false)) |error_value| {
|
||||
return error_value;
|
||||
@@ -321,8 +321,6 @@ pub const HTMLRewriter = struct {
|
||||
}
|
||||
|
||||
pub fn onFinishedLoading(sink: *BufferOutputSink, bytes: anyerror![]u8) void {
|
||||
var input = sink.input;
|
||||
defer input.detach();
|
||||
const data = bytes catch |err| {
|
||||
if (sink.response.body.value == .Locked and @ptrToInt(sink.response.body.value.Locked.task) == @ptrToInt(sink)) {
|
||||
sink.response.body.value = .{ .Empty = .{} };
|
||||
@@ -378,16 +376,10 @@ pub const HTMLRewriter = struct {
|
||||
this.response.body.value = .{
|
||||
.Blob = JSC.WebCore.Blob.init(bytes, this.bytes.allocator, this.global),
|
||||
};
|
||||
|
||||
if (prev_value.Locked.promise) |promise| {
|
||||
prev_value.Locked.promise = null;
|
||||
promise.asInternalPromise().?.resolve(this.global, JSC.JSValue.fromRef(
|
||||
Response.makeMaybePooled(
|
||||
this.global.ref(),
|
||||
this.response,
|
||||
),
|
||||
));
|
||||
}
|
||||
prev_value.resolve(
|
||||
&this.response.body.value,
|
||||
this.global,
|
||||
);
|
||||
}
|
||||
|
||||
pub fn write(this: *BufferOutputSink, bytes: []const u8) void {
|
||||
|
||||
@@ -298,7 +298,7 @@ pub fn NewServer(comptime ssl_enabled: bool) type {
|
||||
}
|
||||
} else {
|
||||
var sbytes: std.os.off_t = adjusted_count;
|
||||
const signed_offset = @bitCast(i64, this.sendfile.offset);
|
||||
const signed_offset = @bitCast(i64, @as(u64, this.sendfile.offset));
|
||||
|
||||
// var sf_hdr_trailer: std.os.darwin.sf_hdtr = .{
|
||||
// .headers = &separator_iovec,
|
||||
@@ -320,9 +320,9 @@ pub fn NewServer(comptime ssl_enabled: bool) type {
|
||||
null,
|
||||
0,
|
||||
));
|
||||
|
||||
this.sendfile.offset += sbytes;
|
||||
this.sendfile.remain -= @intCast(JSC.WebCore.Blob.SizeType, sbytes);
|
||||
const wrote = @intCast(Blob.SizeType, sbytes);
|
||||
this.sendfile.offset += wrote;
|
||||
this.sendfile.remain -= wrote;
|
||||
if (errcode != .AGAIN or this.aborted or this.sendfile.remain == 0 or sbytes == 0) {
|
||||
if (errcode != .AGAIN and errcode != .SUCCESS) {
|
||||
Output.prettyErrorln("Error: {s}", .{@tagName(errcode)});
|
||||
|
||||
@@ -1868,6 +1868,10 @@ pub const ArrayBuffer = extern struct {
|
||||
return this.ptr[this.offset .. this.offset + this.len];
|
||||
}
|
||||
|
||||
pub inline fn byteSlice(this: *const @This()) []u8 {
|
||||
return this.ptr[this.offset .. this.offset + this.byte_len];
|
||||
}
|
||||
|
||||
pub inline fn asU16(this: *const @This()) []u16 {
|
||||
return std.mem.bytesAsSlice(u16, @alignCast(@alignOf([*]u16), this.ptr[this.offset..this.byte_len]));
|
||||
}
|
||||
|
||||
@@ -221,6 +221,12 @@ JSC__JSInternalPromise* JSC__JSValue__asInternalPromise(JSC__JSValue JSValue0)
|
||||
JSC::JSValue value = JSC::JSValue::decode(JSValue0);
|
||||
return JSC::jsCast<JSC::JSInternalPromise*>(value);
|
||||
}
|
||||
|
||||
JSC__JSPromise* JSC__JSValue__asPromise(JSC__JSValue JSValue0)
|
||||
{
|
||||
JSC::JSValue value = JSC::JSValue::decode(JSValue0);
|
||||
return JSC::jsCast<JSC::JSPromise*>(value);
|
||||
}
|
||||
JSC__JSValue JSC__JSValue__createInternalPromise(JSC__JSGlobalObject* globalObject)
|
||||
{
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
@@ -1616,19 +1622,15 @@ int64_t JSC__JSValue__toInt64(JSC__JSValue val)
|
||||
return result;
|
||||
}
|
||||
|
||||
if (auto* heapBigInt = _val.asHeapBigInt()) {
|
||||
if (heapBigInt != nullptr) {
|
||||
if (_val.isHeapBigInt()) {
|
||||
|
||||
if (auto* heapBigInt = _val.asHeapBigInt()) {
|
||||
return heapBigInt->toBigInt64(heapBigInt);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
return _val.asAnyInt();
|
||||
}
|
||||
|
||||
|
||||
JSC__JSValue JSC__JSValue__createObject2(JSC__JSGlobalObject* globalObject, const ZigString* arg1,
|
||||
const ZigString* arg2, JSC__JSValue JSValue3,
|
||||
JSC__JSValue JSValue4)
|
||||
|
||||
@@ -1836,6 +1836,7 @@ pub const JSValue = enum(u64) {
|
||||
c_uint => @intCast(c_uint, toU32(this)),
|
||||
c_int => @intCast(c_int, toInt32(this)),
|
||||
?*JSInternalPromise => asInternalPromise(this),
|
||||
?*JSPromise => asPromise(this),
|
||||
|
||||
// TODO: BigUint64?
|
||||
u64 => @as(u64, toU32(this)),
|
||||
@@ -1935,6 +1936,14 @@ pub const JSValue = enum(u64) {
|
||||
});
|
||||
}
|
||||
|
||||
pub fn asPromise(
|
||||
value: JSValue,
|
||||
) ?*JSPromise {
|
||||
return cppFn("asPromise", .{
|
||||
value,
|
||||
});
|
||||
}
|
||||
|
||||
pub fn jsNumber(number: anytype) JSValue {
|
||||
return jsNumberWithType(@TypeOf(number), number);
|
||||
}
|
||||
@@ -2371,7 +2380,7 @@ pub const JSValue = enum(u64) {
|
||||
return @intToPtr(*anyopaque, @enumToInt(this));
|
||||
}
|
||||
|
||||
pub const Extern = [_][]const u8{ "toInt64", "_then", "put", "makeWithNameAndPrototype", "parseJSON", "symbolKeyFor", "symbolFor", "getSymbolDescription", "createInternalPromise", "asInternalPromise", "asArrayBuffer_", "getReadableStreamState", "getWritableStreamState", "fromEntries", "createTypeError", "createRangeError", "createObject2", "getIfPropertyExistsImpl", "jsType", "jsonStringify", "kind_", "isTerminationException", "isSameValue", "getLengthOfArray", "toZigString", "createStringArray", "createEmptyObject", "putRecord", "asPromise", "isClass", "getNameProperty", "getClassName", "getErrorsProperty", "toInt32", "toBoolean", "isInt32", "isIterable", "forEach", "isAggregateError", "toZigException", "isException", "toWTFString", "hasProperty", "getPropertyNames", "getDirect", "putDirect", "getIfExists", "asString", "asObject", "asNumber", "isError", "jsNull", "jsUndefined", "jsTDZValue", "jsBoolean", "jsDoubleNumber", "jsNumberFromDouble", "jsNumberFromChar", "jsNumberFromU16", "jsNumberFromInt32", "jsNumberFromInt64", "jsNumberFromUint64", "isBoolean", "isAnyInt", "isUInt32AsAnyInt", "isInt32AsAnyInt", "isNumber", "isString", "isBigInt", "isHeapBigInt", "isBigInt32", "isSymbol", "isPrimitive", "isGetterSetter", "isCustomGetterSetter", "isObject", "isCell", "asCell", "toString", "toStringOrNull", "toPropertyKey", "toPropertyKeyValue", "toObject", "toString", "getPrototype", "getPropertyByPropertyName", "eqlValue", "eqlCell", "isCallable" };
|
||||
pub const Extern = [_][]const u8{ "asPromise", "toInt64", "_then", "put", "makeWithNameAndPrototype", "parseJSON", "symbolKeyFor", "symbolFor", "getSymbolDescription", "createInternalPromise", "asInternalPromise", "asArrayBuffer_", "getReadableStreamState", "getWritableStreamState", "fromEntries", "createTypeError", "createRangeError", "createObject2", "getIfPropertyExistsImpl", "jsType", "jsonStringify", "kind_", "isTerminationException", "isSameValue", "getLengthOfArray", "toZigString", "createStringArray", "createEmptyObject", "putRecord", "asPromise", "isClass", "getNameProperty", "getClassName", "getErrorsProperty", "toInt32", "toBoolean", "isInt32", "isIterable", "forEach", "isAggregateError", "toZigException", "isException", "toWTFString", "hasProperty", "getPropertyNames", "getDirect", "putDirect", "getIfExists", "asString", "asObject", "asNumber", "isError", "jsNull", "jsUndefined", "jsTDZValue", "jsBoolean", "jsDoubleNumber", "jsNumberFromDouble", "jsNumberFromChar", "jsNumberFromU16", "jsNumberFromInt32", "jsNumberFromInt64", "jsNumberFromUint64", "isBoolean", "isAnyInt", "isUInt32AsAnyInt", "isInt32AsAnyInt", "isNumber", "isString", "isBigInt", "isHeapBigInt", "isBigInt32", "isSymbol", "isPrimitive", "isGetterSetter", "isCustomGetterSetter", "isObject", "isCell", "asCell", "toString", "toStringOrNull", "toPropertyKey", "toPropertyKeyValue", "toObject", "toString", "getPrototype", "getPropertyByPropertyName", "eqlValue", "eqlCell", "isCallable" };
|
||||
};
|
||||
|
||||
extern "c" fn Microtask__run(*Microtask, *JSGlobalObject) void;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//-- AUTOGENERATED FILE -- 1647946969
|
||||
//-- AUTOGENERATED FILE -- 1648033260
|
||||
// clang-format off
|
||||
#pragma once
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// clang-format: off
|
||||
//-- AUTOGENERATED FILE -- 1647946969
|
||||
//-- AUTOGENERATED FILE -- 1648033260
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
@@ -434,6 +434,8 @@ CPP_DECL JSC__JSCell* JSC__JSValue__asCell(JSC__JSValue JSValue0);
|
||||
CPP_DECL JSC__JSInternalPromise* JSC__JSValue__asInternalPromise(JSC__JSValue JSValue0);
|
||||
CPP_DECL double JSC__JSValue__asNumber(JSC__JSValue JSValue0);
|
||||
CPP_DECL bJSC__JSObject JSC__JSValue__asObject(JSC__JSValue JSValue0);
|
||||
CPP_DECL JSC__JSPromise* JSC__JSValue__asPromise(JSC__JSValue JSValue0);
|
||||
CPP_DECL JSC__JSPromise* JSC__JSValue__asPromise(JSC__JSValue JSValue0);
|
||||
CPP_DECL JSC__JSString* JSC__JSValue__asString(JSC__JSValue JSValue0);
|
||||
CPP_DECL JSC__JSValue JSC__JSValue__createEmptyObject(JSC__JSGlobalObject* arg0, size_t arg1);
|
||||
CPP_DECL JSC__JSValue JSC__JSValue__createInternalPromise(JSC__JSGlobalObject* arg0);
|
||||
|
||||
@@ -273,6 +273,7 @@ pub extern fn JSC__JSValue__asCell(JSValue0: JSC__JSValue) [*c]JSC__JSCell;
|
||||
pub extern fn JSC__JSValue__asInternalPromise(JSValue0: JSC__JSValue) [*c]JSC__JSInternalPromise;
|
||||
pub extern fn JSC__JSValue__asNumber(JSValue0: JSC__JSValue) f64;
|
||||
pub extern fn JSC__JSValue__asObject(JSValue0: JSC__JSValue) bJSC__JSObject;
|
||||
pub extern fn JSC__JSValue__asPromise(JSValue0: JSC__JSValue) [*c]JSC__JSPromise;
|
||||
pub extern fn JSC__JSValue__asString(JSValue0: JSC__JSValue) [*c]JSC__JSString;
|
||||
pub extern fn JSC__JSValue__createEmptyObject(arg0: [*c]JSC__JSGlobalObject, arg1: usize) JSC__JSValue;
|
||||
pub extern fn JSC__JSValue__createInternalPromise(arg0: [*c]JSC__JSGlobalObject) JSC__JSValue;
|
||||
|
||||
@@ -328,7 +328,7 @@ pub fn copyfile(from: [:0]const u8, to: [:0]const u8, flags: c_int) Maybe(void)
|
||||
unreachable;
|
||||
}
|
||||
|
||||
pub fn fcopyfile(fd_in: std.os.fd_t, fd_out: std.os.fd_t, flags: c_int) Maybe(void) {
|
||||
pub fn fcopyfile(fd_in: std.os.fd_t, fd_out: std.os.fd_t, flags: u32) Maybe(void) {
|
||||
if (comptime !Environment.isMac) @compileError("macOS only");
|
||||
|
||||
while (true) {
|
||||
|
||||
@@ -157,6 +157,12 @@ pub const Response = struct {
|
||||
status_text: string = "",
|
||||
redirected: bool = false,
|
||||
|
||||
pub fn getBodyValue(
|
||||
this: *Response,
|
||||
) *Body.Value {
|
||||
return &this.body.value;
|
||||
}
|
||||
|
||||
pub inline fn statusCode(this: *const Response) u16 {
|
||||
return this.body.init.status_code;
|
||||
}
|
||||
@@ -1995,13 +2001,19 @@ pub const Blob = struct {
|
||||
|
||||
pub fn getFdMac(this: *This) AsyncIO.OpenError!JSC.Node.FileDescriptor {
|
||||
var buf: [bun.MAX_PATH_BYTES]u8 = undefined;
|
||||
this.opened_fd = AsyncIO.openSync(
|
||||
this.file_store.pathlike.path.sliceZ(&buf),
|
||||
open_flags_,
|
||||
) catch |err| {
|
||||
this.errno = err;
|
||||
return err;
|
||||
var path = if (@hasField(This, "file_store"))
|
||||
this.file_store.pathlike.path.sliceZ(&buf)
|
||||
else
|
||||
this.file_blob.store.?.data.file.pathlike.path.sliceZ(&buf);
|
||||
|
||||
this.opened_fd = switch (JSC.Node.Syscall.open(path, open_flags_, JSC.Node.default_permission)) {
|
||||
.result => |fd| fd,
|
||||
.err => |err| {
|
||||
this.errno = AsyncIO.asError(err.errno);
|
||||
return @errSetCast(AsyncIO.OpenError, this.errno.?);
|
||||
},
|
||||
};
|
||||
|
||||
return this.opened_fd;
|
||||
}
|
||||
|
||||
@@ -2437,8 +2449,8 @@ pub const Blob = struct {
|
||||
onCompleteCallback: OnWriteFileCallback = undefined,
|
||||
wrote: usize = 0,
|
||||
|
||||
pub const ResultType = anyerror!Blob;
|
||||
pub const OnWriteFileCallback = fn (ctx: *anyopaque, blob: ResultType) void;
|
||||
pub const ResultType = anyerror!SizeType;
|
||||
pub const OnWriteFileCallback = fn (ctx: *anyopaque, count: ResultType) void;
|
||||
|
||||
pub usingnamespace FileOpenerMixin(WriteFile);
|
||||
pub usingnamespace FileCloserMixin(WriteFile);
|
||||
@@ -2522,6 +2534,7 @@ pub const Blob = struct {
|
||||
var cb_ctx = this.onCompleteCtx;
|
||||
|
||||
this.bytes_blob.store.?.deref();
|
||||
this.file_blob.store.?.deref();
|
||||
|
||||
if (this.errno) |err| {
|
||||
bun.default_allocator.destroy(this);
|
||||
@@ -2529,10 +2542,8 @@ pub const Blob = struct {
|
||||
return;
|
||||
}
|
||||
|
||||
var blob = this.file_blob;
|
||||
|
||||
bun.default_allocator.destroy(this);
|
||||
cb(cb_ctx, blob);
|
||||
cb(cb_ctx, @truncate(SizeType, this.wrote));
|
||||
}
|
||||
pub fn run(this: *WriteFile, task: *WriteFileTask) void {
|
||||
this.runAsyncFrame = async this.runAsync(task);
|
||||
@@ -2580,7 +2591,7 @@ pub const Blob = struct {
|
||||
if (wrote_len == 0) break;
|
||||
}
|
||||
|
||||
this.file_blob.size = @truncate(SizeType, total_written);
|
||||
this.wrote = @truncate(SizeType, total_written);
|
||||
|
||||
if (needs_close) {
|
||||
this.doClose() catch {};
|
||||
@@ -2613,7 +2624,7 @@ pub const Blob = struct {
|
||||
|
||||
globalThis: *JSGlobalObject,
|
||||
|
||||
pub const ResultType = anyerror!Blob;
|
||||
pub const ResultType = anyerror!SizeType;
|
||||
|
||||
pub const Callback = fn (ctx: *anyopaque, len: ResultType) void;
|
||||
pub const CopyFilePromiseTask = JSC.ConcurrentPromiseTask(CopyFile);
|
||||
@@ -2651,6 +2662,7 @@ pub const Blob = struct {
|
||||
bun.default_allocator.free(bun.constStrToU8(this.source_file_store.pathlike.path.slice()));
|
||||
}
|
||||
}
|
||||
this.store.?.deref();
|
||||
|
||||
bun.default_allocator.destroy(this);
|
||||
}
|
||||
@@ -2673,21 +2685,14 @@ pub const Blob = struct {
|
||||
}
|
||||
|
||||
pub fn then(this: *CopyFile, promise: *JSC.JSInternalPromise) void {
|
||||
defer this.source_store.?.deref();
|
||||
this.source_store.?.deref();
|
||||
|
||||
if (this.errno != null) {
|
||||
this.reject(promise);
|
||||
return;
|
||||
}
|
||||
var blob = Blob{
|
||||
.offset = this.read_off,
|
||||
.size = this.read_len,
|
||||
.store = this.store,
|
||||
};
|
||||
blob.allocator = bun.default_allocator;
|
||||
var ptr = bun.default_allocator.create(Blob) catch unreachable;
|
||||
ptr.* = blob;
|
||||
promise.resolve(this.globalThis, JSC.JSValue.fromRef(Blob.Class.make(this.globalThis.ref(), ptr)));
|
||||
|
||||
promise.resolve(this.globalThis, JSC.JSValue.jsNumberFromUint64(this.read_len));
|
||||
}
|
||||
pub fn run(this: *CopyFile) void {
|
||||
this.runAsync();
|
||||
@@ -2802,14 +2807,23 @@ pub const Blob = struct {
|
||||
|
||||
pub fn doFCopyFile(this: *CopyFile) anyerror!void {
|
||||
switch (JSC.Node.Syscall.fcopyfile(this.source_fd, this.destination_fd, os.system.COPYFILE_DATA)) {
|
||||
else => |errno| {
|
||||
this.errno = AsyncIO.asError(errno);
|
||||
.err => |errno| {
|
||||
this.errno = AsyncIO.asError(errno.errno);
|
||||
return this.errno.?;
|
||||
},
|
||||
.result => {},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn doClonefile(this: *CopyFile) anyerror!void {
|
||||
switch (JSC.Node.Syscall.clonefile(this.destination_file_store.pathlike.path.sliceZAssume(), this.source_file_store.pathlike.path.sliceZAssume())) {
|
||||
.err => |errno| {
|
||||
return AsyncIO.asError(errno.errno);
|
||||
},
|
||||
.result => {},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn runAsync(this: *CopyFile) void {
|
||||
// defer task.onFinish();
|
||||
|
||||
@@ -2829,7 +2843,7 @@ pub const Blob = struct {
|
||||
// First, we attempt to clonefile() on macOS
|
||||
// This is the fastest way to copy a file.
|
||||
if (comptime Environment.isMac) {
|
||||
if (this.offset == 0) {
|
||||
if (this.offset == 0 and this.source_file_store.pathlike == .path and this.destination_file_store.pathlike == .path) {
|
||||
do_clonefile: {
|
||||
|
||||
// stat the output file, make sure it:
|
||||
@@ -2848,12 +2862,12 @@ pub const Blob = struct {
|
||||
},
|
||||
.err => |err| {
|
||||
// If we can't stat it, we also can't copy it.
|
||||
this.errno = err;
|
||||
this.errno = AsyncIO.asError(err.errno);
|
||||
return;
|
||||
},
|
||||
}
|
||||
|
||||
if (this.doCloneFile()) {
|
||||
if (this.doClonefile()) {
|
||||
if (this.max_length != Blob.max_size and this.max_length < @intCast(SizeType, stat_.?.size)) {
|
||||
// If this fails...well, there's not much we can do about it.
|
||||
_ = bun.C.truncate(
|
||||
@@ -3448,11 +3462,11 @@ pub const Blob = struct {
|
||||
pub const WriteFilePromise = struct {
|
||||
promise: *JSPromise,
|
||||
globalThis: *JSGlobalObject,
|
||||
pub fn run(handler: *@This(), blob_: Blob.Store.WriteFile.ResultType) void {
|
||||
pub fn run(handler: *@This(), count: Blob.Store.WriteFile.ResultType) void {
|
||||
var promise = handler.promise;
|
||||
var globalThis = handler.globalThis;
|
||||
bun.default_allocator.destroy(handler);
|
||||
var blob = blob_ catch |err| {
|
||||
var wrote = count catch |err| {
|
||||
var error_string = ZigString.init(
|
||||
std.fmt.allocPrint(bun.default_allocator, "Failed to write file \"{s}\"", .{std.mem.span(@errorName(err))}) catch unreachable,
|
||||
);
|
||||
@@ -3461,10 +3475,7 @@ pub const Blob = struct {
|
||||
return;
|
||||
};
|
||||
|
||||
var ptr = bun.default_allocator.create(Blob) catch unreachable;
|
||||
ptr.* = blob;
|
||||
|
||||
promise.resolve(globalThis, JSC.JSValue.fromRef(Blob.Class.make(globalThis.ref(), ptr)));
|
||||
promise.resolve(globalThis, JSC.JSValue.jsNumberFromUint64(wrote));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -3775,7 +3786,7 @@ pub const Blob = struct {
|
||||
JSC.JSValue.JSType.BigUint64Array,
|
||||
JSC.JSValue.JSType.DataView,
|
||||
=> {
|
||||
var buf = try bun.default_allocator.dupe(u8, top_value.asArrayBuffer(global).?.slice());
|
||||
var buf = try bun.default_allocator.dupe(u8, top_value.asArrayBuffer(global).?.byteSlice());
|
||||
return Blob.init(buf, bun.default_allocator, global);
|
||||
},
|
||||
|
||||
@@ -3866,7 +3877,7 @@ pub const Blob = struct {
|
||||
JSC.JSValue.JSType.DataView,
|
||||
=> {
|
||||
var buf = item.asArrayBuffer(global).?;
|
||||
joiner.append(buf.slice(), 0, null);
|
||||
joiner.append(buf.byteSlice(), 0, null);
|
||||
continue;
|
||||
},
|
||||
.Array, .DerivedArray => {
|
||||
@@ -4073,6 +4084,15 @@ pub const Body = struct {
|
||||
task: ?*anyopaque = null,
|
||||
callback: ?fn (ctx: *anyopaque, value: *Value) void = null,
|
||||
deinit: bool = false,
|
||||
action: Action = Action.none,
|
||||
|
||||
pub const Action = enum {
|
||||
none,
|
||||
getText,
|
||||
getJSON,
|
||||
getArrayBuffer,
|
||||
getBlob,
|
||||
};
|
||||
};
|
||||
|
||||
pub const Value = union(Tag) {
|
||||
@@ -4091,6 +4111,47 @@ pub const Body = struct {
|
||||
};
|
||||
|
||||
pub const empty = Value{ .Empty = .{} };
|
||||
|
||||
pub fn resolve(this: *Value, new: *Value, global: *JSGlobalObject) void {
|
||||
if (this.* == .Locked) {
|
||||
var locked = this.Locked;
|
||||
if (locked.callback) |callback| {
|
||||
locked.callback = null;
|
||||
callback(locked.task.?, new);
|
||||
}
|
||||
|
||||
if (locked.promise) |promise| {
|
||||
var blob = new.use();
|
||||
|
||||
switch (locked.action) {
|
||||
.getText => {
|
||||
promise.asPromise().?.resolve(global, JSValue.fromRef(blob.getTextTransfer(global.ref())));
|
||||
},
|
||||
.getJSON => {
|
||||
promise.asPromise().?.resolve(global, blob.toJSON(global));
|
||||
blob.detach();
|
||||
},
|
||||
.getArrayBuffer => {
|
||||
promise.asPromise().?.resolve(global, JSValue.fromRef(blob.getArrayBufferTransfer(global.ref())));
|
||||
},
|
||||
.getBlob => {
|
||||
var ptr = bun.default_allocator.create(Blob) catch unreachable;
|
||||
ptr.* = blob;
|
||||
ptr.allocator = bun.default_allocator;
|
||||
promise.asPromise().?.resolve(global, JSC.JSValue.fromRef(Blob.Class.make(global.ref(), ptr)));
|
||||
},
|
||||
else => {
|
||||
var ptr = bun.default_allocator.create(Blob) catch unreachable;
|
||||
ptr.* = blob;
|
||||
ptr.allocator = bun.default_allocator;
|
||||
promise.asInternalPromise().?.resolve(global, JSC.JSValue.fromRef(Blob.Class.make(global.ref(), ptr)));
|
||||
},
|
||||
}
|
||||
JSC.C.JSValueUnprotect(global.ref(), promise.asObjectRef());
|
||||
locked.promise = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn slice(this: Value) []const u8 {
|
||||
return switch (this) {
|
||||
.Blob => this.Blob.sharedView(),
|
||||
@@ -4118,8 +4179,9 @@ pub const Body = struct {
|
||||
if (locked.promise) |promise| {
|
||||
if (promise.asInternalPromise()) |internal| {
|
||||
internal.reject(global, error_instance);
|
||||
} else if (promise.asPromise()) |internal| {
|
||||
internal.reject(global, error_instance);
|
||||
}
|
||||
|
||||
JSC.C.JSValueUnprotect(global.ref(), promise.asObjectRef());
|
||||
locked.promise = null;
|
||||
}
|
||||
@@ -4535,6 +4597,12 @@ pub const Request = struct {
|
||||
);
|
||||
}
|
||||
|
||||
pub fn getBodyValue(
|
||||
this: *Request,
|
||||
) *Body.Value {
|
||||
return &this.body;
|
||||
}
|
||||
|
||||
pub fn getBodyUsed(
|
||||
this: *Request,
|
||||
_: js.JSContextRef,
|
||||
@@ -4602,6 +4670,14 @@ fn BlobInterface(comptime Type: type) type {
|
||||
_: []const js.JSValueRef,
|
||||
_: js.ExceptionRef,
|
||||
) js.JSValueRef {
|
||||
var value = this.getBodyValue();
|
||||
if (value.* == .Locked) {
|
||||
value.Locked.action = .getText;
|
||||
var promise = JSC.JSPromise.create(ctx.ptr());
|
||||
value.Locked.promise = promise.asValue(ctx.ptr());
|
||||
return value.Locked.promise.?.asObjectRef();
|
||||
}
|
||||
|
||||
var blob = this.body.use();
|
||||
return blob.getTextTransfer(ctx);
|
||||
}
|
||||
@@ -4614,6 +4690,14 @@ fn BlobInterface(comptime Type: type) type {
|
||||
_: []const js.JSValueRef,
|
||||
exception: js.ExceptionRef,
|
||||
) js.JSValueRef {
|
||||
var value = this.getBodyValue();
|
||||
if (value.* == .Locked) {
|
||||
value.Locked.action = .getJSON;
|
||||
var promise = JSC.JSPromise.create(ctx.ptr());
|
||||
value.Locked.promise = promise.asValue(ctx.ptr());
|
||||
return value.Locked.promise.?.asObjectRef();
|
||||
}
|
||||
|
||||
var blob = this.body.use();
|
||||
return blob.getJSON(ctx, null, null, &.{}, exception);
|
||||
}
|
||||
@@ -4625,6 +4709,15 @@ fn BlobInterface(comptime Type: type) type {
|
||||
_: []const js.JSValueRef,
|
||||
_: js.ExceptionRef,
|
||||
) js.JSValueRef {
|
||||
var value = this.getBodyValue();
|
||||
|
||||
if (value.* == .Locked) {
|
||||
value.Locked.action = .getArrayBuffer;
|
||||
var promise = JSC.JSPromise.create(ctx.ptr());
|
||||
value.Locked.promise = promise.asValue(ctx.ptr());
|
||||
return value.Locked.promise.?.asObjectRef();
|
||||
}
|
||||
|
||||
var blob = this.body.use();
|
||||
return blob.getArrayBufferTransfer(ctx);
|
||||
}
|
||||
@@ -4637,6 +4730,14 @@ fn BlobInterface(comptime Type: type) type {
|
||||
_: []const js.JSValueRef,
|
||||
_: js.ExceptionRef,
|
||||
) js.JSValueRef {
|
||||
var value = this.getBodyValue();
|
||||
if (value.* == .Locked) {
|
||||
value.Locked.action = .getBlob;
|
||||
var promise = JSC.JSPromise.create(ctx.ptr());
|
||||
value.Locked.promise = promise.asValue(ctx.ptr());
|
||||
return value.Locked.promise.?.asObjectRef();
|
||||
}
|
||||
|
||||
var blob = this.body.use();
|
||||
var ptr = getAllocator(ctx).create(Blob) catch unreachable;
|
||||
ptr.* = blob;
|
||||
|
||||
@@ -1 +1 @@
|
||||
118e8e9b568841b0
|
||||
139d399765744be7
|
||||
Reference in New Issue
Block a user