diff options
Diffstat (limited to 'src/bun.js')
-rw-r--r-- | src/bun.js/bindings/Process.cpp | 2 | ||||
-rw-r--r-- | src/bun.js/bindings/ZigGeneratedClasses.cpp | 16 | ||||
-rw-r--r-- | src/bun.js/bindings/bindings.cpp | 22 | ||||
-rw-r--r-- | src/bun.js/bindings/bindings.zig | 81 | ||||
-rw-r--r-- | src/bun.js/bindings/generated_classes.zig | 3 | ||||
-rw-r--r-- | src/bun.js/bindings/headers.h | 5 | ||||
-rw-r--r-- | src/bun.js/bindings/headers.zig | 3 | ||||
-rw-r--r-- | src/bun.js/bindings/helpers.h | 30 | ||||
-rw-r--r-- | src/bun.js/webcore.zig | 35 | ||||
-rw-r--r-- | src/bun.js/webcore/blob.zig | 51 | ||||
-rw-r--r-- | src/bun.js/webcore/body.zig | 63 | ||||
-rw-r--r-- | src/bun.js/webcore/request.zig | 10 | ||||
-rw-r--r-- | src/bun.js/webcore/response.classes.ts | 1 | ||||
-rw-r--r-- | src/bun.js/webcore/response.zig | 28 |
14 files changed, 234 insertions, 116 deletions
diff --git a/src/bun.js/bindings/Process.cpp b/src/bun.js/bindings/Process.cpp index 7b9154211..d336d5874 100644 --- a/src/bun.js/bindings/Process.cpp +++ b/src/bun.js/bindings/Process.cpp @@ -736,6 +736,8 @@ void Process::finishCreation(JSC::VM& vm) this->putDirectNativeFunction(vm, globalObject, JSC::Identifier::fromString(this->vm(), "binding"_s), 1, Process_functionBinding, ImplementationVisibility::Public, NoIntrinsic, PropertyAttribute::DontEnum | 0); + this->putDirect(vm, vm.propertyNames->toStringTagSymbol, jsString(vm, String("process"_s)), 0); + // target_defaults: // { cflags: [], // default_configuration: 'Release', diff --git a/src/bun.js/bindings/ZigGeneratedClasses.cpp b/src/bun.js/bindings/ZigGeneratedClasses.cpp index a388490b4..a16c8d5ad 100644 --- a/src/bun.js/bindings/ZigGeneratedClasses.cpp +++ b/src/bun.js/bindings/ZigGeneratedClasses.cpp @@ -124,9 +124,6 @@ JSC_DECLARE_HOST_FUNCTION(BlobPrototype__textCallback); extern "C" JSC::EncodedJSValue BlobPrototype__getType(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject); JSC_DECLARE_CUSTOM_GETTER(BlobPrototype__typeGetterWrap); -extern "C" bool BlobPrototype__setType(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject, JSC::EncodedJSValue value); -JSC_DECLARE_CUSTOM_SETTER(BlobPrototype__typeSetterWrap); - extern "C" EncodedJSValue BlobPrototype__getWriter(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame); JSC_DECLARE_HOST_FUNCTION(BlobPrototype__writerCallback); @@ -140,7 +137,7 @@ static const HashTableValue JSBlobPrototypeTableValues[] = { { "slice"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, BlobPrototype__sliceCallback, 2 } }, { "stream"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, BlobPrototype__streamCallback, 1 } }, { "text"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, BlobPrototype__textCallback, 0 } }, - { "type"_s, static_cast<unsigned>(JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, BlobPrototype__typeGetterWrap, BlobPrototype__typeSetterWrap } }, + { "type"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::GetterSetterType, BlobPrototype__typeGetterWrap, 0 } }, { "writer"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, BlobPrototype__writerCallback, 1 } } }; @@ -278,17 +275,6 @@ JSC_DEFINE_CUSTOM_GETTER(BlobPrototype__typeGetterWrap, (JSGlobalObject * lexica RELEASE_AND_RETURN(throwScope, result); } -JSC_DEFINE_CUSTOM_SETTER(BlobPrototype__typeSetterWrap, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, EncodedJSValue encodedValue, PropertyName attributeName)) -{ - auto& vm = lexicalGlobalObject->vm(); - auto throwScope = DECLARE_THROW_SCOPE(vm); - JSBlob* thisObject = jsCast<JSBlob*>(JSValue::decode(thisValue)); - JSC::EnsureStillAliveScope thisArg = JSC::EnsureStillAliveScope(thisObject); - auto result = BlobPrototype__setType(thisObject->wrapped(), lexicalGlobalObject, encodedValue); - - RELEASE_AND_RETURN(throwScope, result); -} - JSC_DEFINE_HOST_FUNCTION(BlobPrototype__writerCallback, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) { auto& vm = lexicalGlobalObject->vm(); diff --git a/src/bun.js/bindings/bindings.cpp b/src/bun.js/bindings/bindings.cpp index 3b0137c28..774c14d0c 100644 --- a/src/bun.js/bindings/bindings.cpp +++ b/src/bun.js/bindings/bindings.cpp @@ -2031,6 +2031,21 @@ JSC__JSValue ZigString__toErrorInstance(const ZigString* str, JSC__JSGlobalObjec return JSC::JSValue::encode(Zig::getErrorInstance(str, globalObject)); } +JSC__JSValue ZigString__toTypeErrorInstance(const ZigString* str, JSC__JSGlobalObject* globalObject) +{ + return JSC::JSValue::encode(Zig::getTypeErrorInstance(str, globalObject)); +} + +JSC__JSValue ZigString__toSyntaxErrorInstance(const ZigString* str, JSC__JSGlobalObject* globalObject) +{ + return JSC::JSValue::encode(Zig::getSyntaxErrorInstance(str, globalObject)); +} + +JSC__JSValue ZigString__toRangeErrorInstance(const ZigString* str, JSC__JSGlobalObject* globalObject) +{ + return JSC::JSValue::encode(Zig::getRangeErrorInstance(str, globalObject)); +} + static JSC::EncodedJSValue resolverFunctionCallback(JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame) { @@ -2845,7 +2860,8 @@ JSC__JSString* JSC__JSValue__toStringOrNull(JSC__JSValue JSValue0, JSC__JSGlobal return value.toStringOrNull(arg1); } -bool JSC__JSValue__toMatch(JSC__JSValue regexValue, JSC__JSGlobalObject* global, JSC__JSValue value) { +bool JSC__JSValue__toMatch(JSC__JSValue regexValue, JSC__JSGlobalObject* global, JSC__JSValue value) +{ JSC::JSValue regex = JSC::JSValue::decode(regexValue); JSC::JSValue str = JSC::JSValue::decode(value); if (regex.asCell()->type() != RegExpObjectType || !str.isString()) { @@ -3831,8 +3847,8 @@ bool JSC__JSValue__isInstanceOf(JSC__JSValue JSValue0, JSC__JSGlobalObject* glob if (UNLIKELY(!jsConstructor->structure()->typeInfo().implementsHasInstance())) return false; bool result = jsConstructor->hasInstance(globalObject, jsValue); - - RETURN_IF_EXCEPTION(scope, false); + + RETURN_IF_EXCEPTION(scope, false); return result; } diff --git a/src/bun.js/bindings/bindings.zig b/src/bun.js/bindings/bindings.zig index 1ac1fc5ca..51f9c9fde 100644 --- a/src/bun.js/bindings/bindings.zig +++ b/src/bun.js/bindings/bindings.zig @@ -760,7 +760,32 @@ pub const ZigString = extern struct { return shim.cppFn("toErrorInstance", .{ this, global }); } - pub const Extern = [_][]const u8{ "toAtomicValue", "toValue", "toExternalValue", "to16BitValue", "toValueGC", "toErrorInstance", "toExternalU16", "toExternalValueWithCallback", "external" }; + pub fn toTypeErrorInstance(this: *const ZigString, global: *JSGlobalObject) JSValue { + return shim.cppFn("toTypeErrorInstance", .{ this, global }); + } + + pub fn toSyntaxErrorInstance(this: *const ZigString, global: *JSGlobalObject) JSValue { + return shim.cppFn("toSyntaxErrorInstance", .{ this, global }); + } + + pub fn toRangeErrorInstance(this: *const ZigString, global: *JSGlobalObject) JSValue { + return shim.cppFn("toRangeErrorInstance", .{ this, global }); + } + + pub const Extern = [_][]const u8{ + "toAtomicValue", + "toValue", + "toExternalValue", + "to16BitValue", + "toValueGC", + "toErrorInstance", + "toExternalU16", + "toExternalValueWithCallback", + "external", + "toTypeErrorInstance", + "toSyntaxErrorInstance", + "toRangeErrorInstance", + }; }; pub const DOMURL = opaque { @@ -2411,6 +2436,60 @@ pub const JSGlobalObject = extern struct { } } + pub fn createErrorInstanceWithCode(this: *JSGlobalObject, code: JSC.Node.ErrorCode, comptime fmt: string, args: anytype) JSValue { + var err = this.createErrorInstance(fmt, args); + err.put(this, ZigString.static("code"), ZigString.init(@tagName(code)).toValue(this)); + return err; + } + + pub fn createTypeErrorInstance(this: *JSGlobalObject, comptime fmt: string, args: anytype) JSValue { + if (comptime std.meta.fieldNames(@TypeOf(args)).len > 0) { + var stack_fallback = std.heap.stackFallback(1024 * 4, this.allocator()); + var buf = bun.MutableString.init2048(stack_fallback.get()) catch unreachable; + defer buf.deinit(); + var writer = buf.writer(); + writer.print(fmt, args) catch return ZigString.static(fmt).toErrorInstance(this); + var str = ZigString.fromUTF8(buf.toOwnedSliceLeaky()); + return str.toTypeErrorInstance(this); + } else { + return ZigString.static(fmt).toTypeErrorInstance(this); + } + } + + pub fn createSyntaxErrorInstance(this: *JSGlobalObject, comptime fmt: string, args: anytype) JSValue { + if (comptime std.meta.fieldNames(@TypeOf(args)).len > 0) { + var stack_fallback = std.heap.stackFallback(1024 * 4, this.allocator()); + var buf = bun.MutableString.init2048(stack_fallback.get()) catch unreachable; + defer buf.deinit(); + var writer = buf.writer(); + writer.print(fmt, args) catch return ZigString.static(fmt).toErrorInstance(this); + var str = ZigString.fromUTF8(buf.toOwnedSliceLeaky()); + return str.toSyntaxErrorInstance(this); + } else { + return ZigString.static(fmt).toSyntaxErrorInstance(this); + } + } + + pub fn createRangeErrorInstance(this: *JSGlobalObject, comptime fmt: string, args: anytype) JSValue { + if (comptime std.meta.fieldNames(@TypeOf(args)).len > 0) { + var stack_fallback = std.heap.stackFallback(1024 * 4, this.allocator()); + var buf = bun.MutableString.init2048(stack_fallback.get()) catch unreachable; + defer buf.deinit(); + var writer = buf.writer(); + writer.print(fmt, args) catch return ZigString.static(fmt).toErrorInstance(this); + var str = ZigString.fromUTF8(buf.toOwnedSliceLeaky()); + return str.toRangeErrorInstance(this); + } else { + return ZigString.static(fmt).toRangeErrorInstance(this); + } + } + + pub fn createRangeErrorInstanceWithCode(this: *JSGlobalObject, code: JSC.Node.ErrorCode, comptime fmt: string, args: anytype) JSValue { + var err = this.createRangeErrorInstance(fmt, args); + err.put(this, ZigString.static("code"), ZigString.init(@tagName(code)).toValue(this)); + return err; + } + pub fn createRangeError(this: *JSGlobalObject, comptime fmt: string, args: anytype) JSValue { const err = createErrorInstance(this, fmt, args); err.put(this, ZigString.static("code"), ZigString.static(@tagName(JSC.Node.ErrorCode.ERR_OUT_OF_RANGE)).toValue(this)); diff --git a/src/bun.js/bindings/generated_classes.zig b/src/bun.js/bindings/generated_classes.zig index f786e3399..ed9953004 100644 --- a/src/bun.js/bindings/generated_classes.zig +++ b/src/bun.js/bindings/generated_classes.zig @@ -102,8 +102,6 @@ pub const JSBlob = struct { if (@TypeOf(Blob.getType) != GetterType) @compileLog("Expected Blob.getType to be a getter"); - if (@TypeOf(Blob.setType) != SetterType) - @compileLog("Expected Blob.setType to be a setter"); if (@TypeOf(Blob.getWriter) != CallbackType) @compileLog("Expected Blob.getWriter to be a callback but received " ++ @typeName(@TypeOf(Blob.getWriter))); if (!JSC.is_bindgen) { @@ -118,7 +116,6 @@ pub const JSBlob = struct { @export(Blob.getText, .{ .name = "BlobPrototype__getText" }); @export(Blob.getType, .{ .name = "BlobPrototype__getType" }); @export(Blob.getWriter, .{ .name = "BlobPrototype__getWriter" }); - @export(Blob.setType, .{ .name = "BlobPrototype__setType" }); } } }; diff --git a/src/bun.js/bindings/headers.h b/src/bun.js/bindings/headers.h index e631721f7..baefaf0b9 100644 --- a/src/bun.js/bindings/headers.h +++ b/src/bun.js/bindings/headers.h @@ -1,5 +1,5 @@ // clang-format off -//-- AUTOGENERATED FILE -- 1679048516 +//-- AUTOGENERATED FILE -- 1679083592 #pragma once #include <stddef.h> @@ -146,6 +146,9 @@ CPP_DECL JSC__JSValue ZigString__toErrorInstance(const ZigString* arg0, JSC__JSG CPP_DECL JSC__JSValue ZigString__toExternalU16(const uint16_t* arg0, size_t arg1, JSC__JSGlobalObject* arg2); CPP_DECL JSC__JSValue ZigString__toExternalValue(const ZigString* arg0, JSC__JSGlobalObject* arg1); CPP_DECL JSC__JSValue ZigString__toExternalValueWithCallback(const ZigString* arg0, JSC__JSGlobalObject* arg1, void(* ArgFn2)(void* arg0, void* arg1, size_t arg2)) __attribute__((nonnull (2))); +CPP_DECL JSC__JSValue ZigString__toRangeErrorInstance(const ZigString* arg0, JSC__JSGlobalObject* arg1); +CPP_DECL JSC__JSValue ZigString__toSyntaxErrorInstance(const ZigString* arg0, JSC__JSGlobalObject* arg1); +CPP_DECL JSC__JSValue ZigString__toTypeErrorInstance(const ZigString* arg0, JSC__JSGlobalObject* arg1); CPP_DECL JSC__JSValue ZigString__toValue(const ZigString* arg0, JSC__JSGlobalObject* arg1); CPP_DECL JSC__JSValue ZigString__toValueGC(const ZigString* arg0, JSC__JSGlobalObject* arg1); CPP_DECL WebCore__DOMURL* WebCore__DOMURL__cast_(JSC__JSValue JSValue0, JSC__VM* arg1); diff --git a/src/bun.js/bindings/headers.zig b/src/bun.js/bindings/headers.zig index eff9a1b81..a6a3b52fa 100644 --- a/src/bun.js/bindings/headers.zig +++ b/src/bun.js/bindings/headers.zig @@ -92,6 +92,9 @@ pub extern fn ZigString__toErrorInstance(arg0: [*c]const ZigString, arg1: *bindi pub extern fn ZigString__toExternalU16(arg0: [*c]const u16, arg1: usize, arg2: *bindings.JSGlobalObject) JSC__JSValue; pub extern fn ZigString__toExternalValue(arg0: [*c]const ZigString, arg1: *bindings.JSGlobalObject) JSC__JSValue; pub extern fn ZigString__toExternalValueWithCallback(arg0: [*c]const ZigString, arg1: *bindings.JSGlobalObject, ArgFn2: ?*const fn (?*anyopaque, ?*anyopaque, usize) callconv(.C) void) JSC__JSValue; +pub extern fn ZigString__toRangeErrorInstance(arg0: [*c]const ZigString, arg1: *bindings.JSGlobalObject) JSC__JSValue; +pub extern fn ZigString__toSyntaxErrorInstance(arg0: [*c]const ZigString, arg1: *bindings.JSGlobalObject) JSC__JSValue; +pub extern fn ZigString__toTypeErrorInstance(arg0: [*c]const ZigString, arg1: *bindings.JSGlobalObject) JSC__JSValue; pub extern fn ZigString__toValue(arg0: [*c]const ZigString, arg1: *bindings.JSGlobalObject) JSC__JSValue; pub extern fn ZigString__toValueGC(arg0: [*c]const ZigString, arg1: *bindings.JSGlobalObject) JSC__JSValue; pub extern fn WebCore__DOMURL__cast_(JSValue0: JSC__JSValue, arg1: *bindings.VM) ?*bindings.DOMURL; diff --git a/src/bun.js/bindings/helpers.h b/src/bun.js/bindings/helpers.h index 382c760f3..8a96a94af 100644 --- a/src/bun.js/bindings/helpers.h +++ b/src/bun.js/bindings/helpers.h @@ -340,6 +340,36 @@ static JSC::JSValue getErrorInstance(const ZigString* str, JSC__JSGlobalObject* return JSC::JSValue(result); } +static JSC::JSValue getTypeErrorInstance(const ZigString* str, JSC__JSGlobalObject* globalObject) +{ + JSC::VM& vm = globalObject->vm(); + + JSC::JSObject* result = JSC::createTypeError(globalObject, toStringCopy(*str)); + JSC::EnsureStillAliveScope ensureAlive(result); + + return JSC::JSValue(result); +} + +static JSC::JSValue getSyntaxErrorInstance(const ZigString* str, JSC__JSGlobalObject* globalObject) +{ + JSC::VM& vm = globalObject->vm(); + + JSC::JSObject* result = JSC::createSyntaxError(globalObject, toStringCopy(*str)); + JSC::EnsureStillAliveScope ensureAlive(result); + + return JSC::JSValue(result); +} + +static JSC::JSValue getRangeErrorInstance(const ZigString* str, JSC__JSGlobalObject* globalObject) +{ + JSC::VM& vm = globalObject->vm(); + + JSC::JSObject* result = JSC::createRangeError(globalObject, toStringCopy(*str)); + JSC::EnsureStillAliveScope ensureAlive(result); + + return JSC::JSValue(result); +} + }; // namespace Zig template<typename WebCoreType, typename OutType> diff --git a/src/bun.js/webcore.zig b/src/bun.js/webcore.zig index c6481438b..70c6ded5c 100644 --- a/src/bun.js/webcore.zig +++ b/src/bun.js/webcore.zig @@ -435,7 +435,7 @@ pub const Crypto = struct { if (N_int < 0 or !N_value.isNumber()) { return throwInvalidParams( globalThis, - "RangeError", + .RangeError, "Invalid scrypt params\n\n N must be a positive integer\n", .{}, ); @@ -450,7 +450,7 @@ pub const Crypto = struct { if (r_int < 0 or !r_value.isNumber()) { return throwInvalidParams( globalThis, - "RangeError", + .RangeError, "Invalid scrypt params\n\n r must be a positive integer\n", .{}, ); @@ -465,7 +465,7 @@ pub const Crypto = struct { if (p_int < 0 or !p_value.isNumber()) { return throwInvalidParams( globalThis, - "RangeError", + .RangeError, "Invalid scrypt params\n\n p must be a positive integer\n", .{}, ); @@ -479,7 +479,7 @@ pub const Crypto = struct { if (p_int < 0 or !value.isNumber()) { return throwInvalidParams( globalThis, - "RangeError", + .RangeError, "Invalid scrypt params\n\n N must be a positive integer\n", .{}, ); @@ -496,7 +496,7 @@ pub const Crypto = struct { if (cost.? < 2 or cost.? > 0x3fffffff) { return throwInvalidParams( globalThis, - "RangeError", + .RangeError, "Invalid scrypt params\n\n N must be greater than 1 and less than 2^30\n", .{}, ); @@ -505,7 +505,7 @@ pub const Crypto = struct { if (cost.? == 0 or (cost.? & (cost.? - 1)) != 0) { return throwInvalidParams( globalThis, - "RangeError", + .RangeError, "Invalid scrypt params\n\n N must be a power of 2 greater than 1\n", .{}, ); @@ -524,7 +524,7 @@ pub const Crypto = struct { null, 0, ) != 1)) { - return throwInvalidParams(globalThis, "RangeError", "Invalid scrypt params\n", .{}); + return throwInvalidParams(globalThis, .RangeError, "Invalid scrypt params\n", .{}); } return JSC.ArrayBuffer.createEmpty(globalThis, .ArrayBuffer); @@ -557,16 +557,15 @@ pub const Crypto = struct { buf.ptr, keylen, ) != 1) { - return throwInvalidParams(globalThis, "RangeError", "Invalid scrypt params\n", .{}); + return throwInvalidParams(globalThis, .RangeError, "Invalid scrypt params\n", .{}); } return JSC.ArrayBuffer.create(globalThis, buf, .ArrayBuffer); } fn throwInvalidParameter(globalThis: *JSC.JSGlobalObject) JSC.JSValue { - const err = globalThis.createError( + const err = globalThis.createErrorInstanceWithCode( .ERR_CRYPTO_SCRYPT_INVALID_PARAMETER, - "Error", "Invalid scrypt parameters", .{}, ); @@ -574,13 +573,15 @@ pub const Crypto = struct { return .zero; } - fn throwInvalidParams(globalThis: *JSC.JSGlobalObject, comptime error_name: string, comptime message: string, fmt: anytype) JSC.JSValue { - const err = globalThis.createError( - .ERR_CRYPTO_INVALID_SCRYPT_PARAMS, - error_name, - message, - fmt, - ); + fn throwInvalidParams(globalThis: *JSC.JSGlobalObject, comptime error_type: @Type(.EnumLiteral), comptime message: string, fmt: anytype) JSC.JSValue { + const err = switch (error_type) { + .RangeError => globalThis.createRangeErrorInstanceWithCode( + .ERR_CRYPTO_INVALID_SCRYPT_PARAMS, + message, + fmt, + ), + else => @compileError("Error type not added!"), + }; globalThis.throwValue(err); return .zero; } diff --git a/src/bun.js/webcore/blob.zig b/src/bun.js/webcore/blob.zig index b670a3aaa..284351347 100644 --- a/src/bun.js/webcore/blob.zig +++ b/src/bun.js/webcore/blob.zig @@ -1011,7 +1011,7 @@ pub const Blob = struct { pub const Store = struct { data: Data, - mime_type: MimeType = MimeType.other, + mime_type: MimeType = MimeType.none, ref_count: u32 = 0, is_all_ascii: ?bool = null, allocator: std.mem.Allocator, @@ -2499,47 +2499,18 @@ pub const Blob = struct { this: *Blob, globalThis: *JSC.JSGlobalObject, ) callconv(.C) JSValue { - return ZigString.init(this.content_type).toValue(globalThis); - } - - pub fn setType( - this: *Blob, - globalThis: *JSC.JSGlobalObject, - value: JSC.JSValue, - ) callconv(.C) bool { - var zig_str = if (value.isString()) - value.getZigString(globalThis) - else - ZigString.Empty; - - if (!zig_str.isAllASCII()) { - zig_str = ZigString.Empty; - } - - if (zig_str.eql(ZigString.init(this.content_type))) { - return true; + if (this.content_type.len > 0) { + if (this.content_type_allocated) { + return ZigString.init(this.content_type).toValue(globalThis); + } + return ZigString.init(this.content_type).toValueGC(globalThis); } - const prev_content_type = this.content_type; - { - var slicer = zig_str.toSlice(bun.default_allocator); - defer slicer.deinit(); - const allocated = this.content_type_allocated; - defer if (allocated) bun.default_allocator.free(prev_content_type); - if (globalThis.bunVM().mimeType(slicer.slice())) |mime| { - this.content_type = mime.value; - this.content_type_allocated = false; - return true; - } - var content_type_buf = globalThis.allocator().alloc(u8, slicer.len) catch { - globalThis.throwOutOfMemory(); - return false; - }; - this.content_type = strings.copyLowercase(slicer.slice(), content_type_buf); + if (this.store) |store| { + return ZigString.init(store.mime_type.value).toValue(globalThis); } - this.content_type_allocated = true; - return true; + return ZigString.Empty.toValue(globalThis); } pub fn getSize(this: *Blob, _: *JSC.JSGlobalObject) callconv(.C) JSValue { @@ -2997,13 +2968,11 @@ pub const Blob = struct { var view_ = this.sharedView(); - if (view_.len == 0) - return ZigString.Empty.toValue(global); - return toJSONWithBytes(this, global, view_, lifetime); } pub fn toJSONWithBytes(this: *Blob, global: *JSGlobalObject, buf: []const u8, comptime lifetime: Lifetime) JSValue { + if (buf.len == 0) return global.createSyntaxErrorInstance("Unexpected end of JSON input", .{}); // null == unknown // false == can't be const could_be_all_ascii = this.is_all_ascii orelse this.store.?.is_all_ascii; diff --git a/src/bun.js/webcore/body.zig b/src/bun.js/webcore/body.zig index 509d02989..1a0831333 100644 --- a/src/bun.js/webcore/body.zig +++ b/src/bun.js/webcore/body.zig @@ -138,13 +138,13 @@ pub const Body = struct { return that; } - pub fn init(allocator: std.mem.Allocator, ctx: *JSGlobalObject, response_init: JSC.JSValue, js_type: JSC.JSValue.JSType) !?Init { + pub fn init(allocator: std.mem.Allocator, ctx: *JSGlobalObject, response_init: JSC.JSValue) !?Init { var result = Init{ .status_code = 200 }; if (!response_init.isCell()) return null; - if (js_type == .DOMWrapper) { + if (response_init.jsType() == .DOMWrapper) { // fast path: it's a Request object or a Response object // we can skip calling JS getters if (response_init.as(Request)) |req| { @@ -170,9 +170,24 @@ pub const Body = struct { } if (response_init.fastGet(ctx, .status)) |status_value| { - const number = status_value.to(i32); - if (100 <= number and number < 1000) - result.status_code = @truncate(u16, @intCast(u32, number)); + if (status_value.isHeapBigInt()) { + const less_than = switch (status_value.asBigIntCompare(ctx, JSValue.jsNumber(600))) { + .less_than => true, + else => false, + }; + const greater_than = switch (status_value.asBigIntCompare(ctx, JSValue.jsNumber(99))) { + .greater_than => true, + else => false, + }; + + if (less_than and greater_than) { + result.status_code = @truncate(u16, @intCast(u64, status_value.toInt64())); + } + } else if (status_value.isNumber()) { + const number = status_value.to(i32); + if (100 <= number and number < 600) + result.status_code = @truncate(u16, @intCast(u32, number)); + } } if (response_init.fastGet(ctx, .method)) |method_value| { @@ -233,10 +248,6 @@ pub const Body = struct { // } switch (action) { .getText, .getJSON, .getBlob, .getArrayBuffer => { - switch (readable.ptr) { - .Blob => unreachable, - else => {}, - } value.promise = switch (action) { .getJSON => globalThis.readableStreamToJSON(readable.value), .getArrayBuffer => globalThis.readableStreamToArrayBuffer(readable.value), @@ -726,9 +737,6 @@ pub const Body = struct { bun.default_allocator, JSC.VirtualMachine.get().global, ); - if (this.InternalBlob.was_string) { - new_blob.content_type = MimeType.text.value; - } this.* = .{ .Used = {} }; return new_blob; @@ -903,7 +911,6 @@ pub const Body = struct { value, false, JSValue.zero, - .Cell, ); } @@ -911,14 +918,12 @@ pub const Body = struct { globalThis: *JSGlobalObject, value: JSValue, init: JSValue, - init_type: JSValue.JSType, ) ?Body { return extractBody( globalThis, value, true, init, - init_type, ); } @@ -928,7 +933,6 @@ pub const Body = struct { value: JSValue, comptime has_init: bool, init: JSValue, - init_type: JSC.JSValue.JSType, ) ?Body { var body = Body{ .value = Value{ .Empty = {} }, @@ -937,11 +941,13 @@ pub const Body = struct { var allocator = getAllocator(globalThis); if (comptime has_init) { - if (Init.init(allocator, globalThis, init, init_type)) |maybeInit| { + if (Init.init(allocator, globalThis, init)) |maybeInit| { if (maybeInit) |init_| { body.init = init_; } - } else |_| {} + } else |_| { + return null; + } } body.value = Value.fromJS(globalThis, value) orelse return null; @@ -1065,8 +1071,12 @@ pub fn BodyMixin(comptime Type: type) type { } var encoder = this.getFormDataEncoding() orelse { - globalObject.throw("Invalid MIME type", .{}); - return .zero; + // TODO: catch specific errors from getFormDataEncoding + const err = globalObject.createTypeErrorInstance("Can't decode form data from body because of incorrect MIME type/boundary", .{}); + return JSC.JSPromise.rejectedPromiseValue( + globalObject, + err, + ); }; if (value.* == .Locked) { @@ -1084,7 +1094,7 @@ pub fn BodyMixin(comptime Type: type) type { ) catch |err| { return JSC.JSPromise.rejectedPromiseValue( globalObject, - globalObject.createErrorInstance( + globalObject.createTypeErrorInstance( "FormData parse error {s}", .{ @errorName(err), @@ -1122,6 +1132,17 @@ pub fn BodyMixin(comptime Type: type) type { var ptr = getAllocator(globalObject).create(Blob) catch unreachable; ptr.* = blob; blob.allocator = getAllocator(globalObject); + + if (blob.content_type.len == 0 and blob.store != null) { + if (this.getFetchHeaders()) |fetch_headers| { + if (fetch_headers.fastGet(.ContentType)) |content_type| { + blob.store.?.mime_type = MimeType.init(content_type.slice()); + } + } else { + blob.store.?.mime_type = MimeType.text; + } + } + return JSC.JSPromise.resolvedPromiseValue(globalObject, ptr.toJS(globalObject)); } }; diff --git a/src/bun.js/webcore/request.zig b/src/bun.js/webcore/request.zig index 6581649fc..d6484d2ba 100644 --- a/src/bun.js/webcore/request.zig +++ b/src/bun.js/webcore/request.zig @@ -399,7 +399,7 @@ pub const Request = struct { .Null = {}, }; } else { - if (Body.Init.init(getAllocator(globalThis), globalThis, arguments[0], url_or_object_type) catch null) |req_init| { + if (Body.Init.init(getAllocator(globalThis), globalThis, arguments[0]) catch null) |req_init| { request.headers = req_init.headers; request.method = req_init.method; } @@ -439,7 +439,7 @@ pub const Request = struct { } } - if (Body.Init.init(getAllocator(globalThis), globalThis, arguments[1], arguments[1].jsType()) catch null) |req_init| { + if (Body.Init.init(getAllocator(globalThis), globalThis, arguments[1]) catch null) |req_init| { request.headers = req_init.headers; request.method = req_init.method; } @@ -494,6 +494,12 @@ pub const Request = struct { return &this.body; } + pub fn getFetchHeaders( + this: *Request, + ) ?*FetchHeaders { + return this.headers; + } + pub fn doClone( this: *Request, globalThis: *JSC.JSGlobalObject, diff --git a/src/bun.js/webcore/response.classes.ts b/src/bun.js/webcore/response.classes.ts index 67ac4716b..4fdce1c0c 100644 --- a/src/bun.js/webcore/response.classes.ts +++ b/src/bun.js/webcore/response.classes.ts @@ -135,7 +135,6 @@ export default [ type: { getter: "getType", - setter: "setType", }, size: { diff --git a/src/bun.js/webcore/response.zig b/src/bun.js/webcore/response.zig index f36af88cf..9dfee821a 100644 --- a/src/bun.js/webcore/response.zig +++ b/src/bun.js/webcore/response.zig @@ -96,6 +96,12 @@ pub const Response = struct { return &this.body.value; } + pub fn getFetchHeaders( + this: *Response, + ) ?*FetchHeaders { + return this.body.init.headers; + } + pub inline fn statusCode(this: *const Response) u16 { return this.body.init.status_code; } @@ -173,7 +179,7 @@ pub const Response = struct { return ZigString.init("error").toValue(globalThis); } - return ZigString.init("basic").toValue(globalThis); + return ZigString.init("default").toValue(globalThis); } pub fn getStatusText( @@ -400,7 +406,7 @@ pub const Response = struct { if (init.isUndefinedOrNull()) {} else if (init.isNumber()) { response.body.init.status_code = @intCast(u16, @min(@max(0, init.toInt32()), std.math.maxInt(u16))); } else { - if (Body.Init.init(getAllocator(globalThis), globalThis, init, init.jsType()) catch null) |_init| { + if (Body.Init.init(getAllocator(globalThis), globalThis, init) catch null) |_init| { response.body.init = _init; } } @@ -446,7 +452,7 @@ pub const Response = struct { if (init.isUndefinedOrNull()) {} else if (init.isNumber()) { response.body.init.status_code = @intCast(u16, @min(@max(0, init.toInt32()), std.math.maxInt(u16))); } else { - if (Body.Init.init(getAllocator(globalThis), globalThis, init, init.jsType()) catch null) |_init| { + if (Body.Init.init(getAllocator(globalThis), globalThis, init) catch null) |_init| { response.body.init = _init; response.body.init.status_code = 302; } @@ -484,7 +490,7 @@ pub const Response = struct { globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame, ) callconv(.C) ?*Response { - const args_list = callframe.arguments(4); + const args_list = callframe.arguments(2); const arguments = args_list.ptr[0..args_list.len]; const body: Body = @as(?Body, brk: { switch (arguments.len) { @@ -495,14 +501,14 @@ pub const Response = struct { break :brk Body.extract(globalThis, arguments[0]); }, else => { - switch (arguments[1].jsType()) { - .Object, .FinalObject, .DOMWrapper => |js_type| { - break :brk Body.extractWithInit(globalThis, arguments[0], arguments[1], js_type); - }, - else => { - break :brk Body.extract(globalThis, arguments[0]); - }, + if (arguments[1].isUndefinedOrNull()) break :brk Body.extract(globalThis, arguments[0]); + if (arguments[1].isObject()) { + break :brk Body.extractWithInit(globalThis, arguments[0], arguments[1]); } + + const err = globalThis.createTypeErrorInstance("Expected options to be one of: null, undefined, or object", .{}); + globalThis.throwValue(err); + break :brk null; }, } unreachable; |