diff options
-rw-r--r-- | examples/tsconfig.json | 2 | ||||
-rwxr-xr-x | packages/bun-error/bun.lockb | bin | 12182 -> 9259 bytes | |||
-rw-r--r-- | packages/bun-error/package.json | 4 | ||||
-rw-r--r-- | packages/bun-framework-next/package.json | 12 | ||||
-rw-r--r-- | src/javascript/jsc/api/server.zig | 103 | ||||
-rw-r--r-- | src/javascript/jsc/bindings/ZigGlobalObject.cpp | 2 | ||||
-rw-r--r-- | src/javascript/jsc/bindings/bindings.zig | 4 | ||||
-rw-r--r-- | src/javascript/jsc/webcore/response.zig | 6 |
8 files changed, 118 insertions, 15 deletions
diff --git a/examples/tsconfig.json b/examples/tsconfig.json index 4e99331ee..404c353e6 100644 --- a/examples/tsconfig.json +++ b/examples/tsconfig.json @@ -3,6 +3,6 @@ "lib": ["ESNext"], "module": "esnext", "target": "esnext", - "typeRoots": ["~/.bun/types"] + "typeRoots": ["../types"] } } diff --git a/packages/bun-error/bun.lockb b/packages/bun-error/bun.lockb Binary files differindex 1c7c459d1..7a58b882e 100755 --- a/packages/bun-error/bun.lockb +++ b/packages/bun-error/bun.lockb diff --git a/packages/bun-error/package.json b/packages/bun-error/package.json index d35c1377c..7bcb9f661 100644 --- a/packages/bun-error/package.json +++ b/packages/bun-error/package.json @@ -8,9 +8,7 @@ "build": "esbuild --define:process.env.NODE_ENV=\"'production'\" --minify index.tsx bun-error.css --bundle --outdir=dist --platform=browser --format=esm" }, "dependencies": { - "esbuild": "^0.14.10", - "preact": "^10.5.14", - "preact-compat": "^3.19.0", + "esbuild": "latest", "react": "^17.0.2", "react-dom": "^17.0.2" }, diff --git a/packages/bun-framework-next/package.json b/packages/bun-framework-next/package.json index bf866ac09..46602ed0b 100644 --- a/packages/bun-framework-next/package.json +++ b/packages/bun-framework-next/package.json @@ -1,6 +1,6 @@ { "name": "bun-framework-next", - "version": "12.1.0", + "version": "12.1.1", "main": "empty.js", "module": "empty.js", "description": "bun compatibility layer for Next.js v12.x.x", @@ -16,12 +16,12 @@ "next": "^12" }, "devDependencies": { - "@types/react": "^17.0.34", - "@types/react-dom": "^17.0.11", + "@types/react": "^18", + "@types/react-dom": "^18", "next": "^12.1.0", - "react": "^17.0.2", - "react-dom": "^17.0.2", - "typescript": "^4.4.4" + "react": "^18", + "react-dom": "^18", + "typescript": "^4" }, "framework": { "displayName": "Next.js", diff --git a/src/javascript/jsc/api/server.zig b/src/javascript/jsc/api/server.zig index 57fbe6d34..b81a0da4e 100644 --- a/src/javascript/jsc/api/server.zig +++ b/src/javascript/jsc/api/server.zig @@ -95,6 +95,11 @@ const linux = std.os.linux; pub const ServerConfig = struct { port: u16 = 0, hostname: [*:0]const u8 = "0.0.0.0", + + // TODO: use webkit URL parser instead of bun's + base_url: URL = URL{}, + base_uri: string = "", + ssl_config: ?SSLConfig = null, max_request_body_size: usize = 1024 * 1024 * 128, development: bool = false, @@ -238,7 +243,7 @@ pub const ServerConfig = struct { .hostname = "0.0.0.0", .development = true, }; - + var has_hostname = false; if (strings.eqlComptime(env.get("NODE_ENV") orelse "", "production")) { args.development = false; } @@ -261,6 +266,10 @@ pub const ServerConfig = struct { args.port = port; } + if (VirtualMachine.vm.bundler.options.transform_options.origin) |origin| { + args.base_uri = origin; + } + if (arguments.next()) |arg| { if (arg.isUndefinedOrNull() or !arg.isObject()) { JSC.throwInvalidArguments("Bun.serve expects an object", .{}, global.ref(), exception); @@ -271,6 +280,15 @@ pub const ServerConfig = struct { args.port = @intCast(u16, @minimum(@maximum(0, port_.toInt32()), std.math.maxInt(u16))); } + if (arg.getTruthy(global, "baseURI")) |baseURI| { + var sliced = baseURI.toSlice(global, bun.default_allocator); + + if (sliced.len > 0) { + defer sliced.deinit(); + args.base_uri = bun.default_allocator.dupe(u8, sliced.slice()) catch unreachable; + } + } + if (arg.getTruthy(global, "hostname") orelse arg.getTruthy(global, "host")) |host| { const host_str = host.toSlice( global, @@ -278,6 +296,7 @@ pub const ServerConfig = struct { ); if (host_str.len > 0) { args.hostname = bun.default_allocator.dupeZ(u8, host_str.slice()) catch unreachable; + has_hostname = true; } } @@ -329,6 +348,80 @@ pub const ServerConfig = struct { JSC.throwInvalidArguments("Invalid port: must be > 0", .{}, global.ref(), exception); } + if (args.base_uri.len > 0) { + args.base_url = URL.parse(args.base_uri); + if (args.base_url.hostname.len == 0) { + JSC.throwInvalidArguments("baseURI must have a hostname", .{}, global.ref(), exception); + bun.default_allocator.free(bun.constStrToU8(args.base_uri)); + args.base_uri = ""; + return args; + } + + if (!strings.isAllASCII(args.base_uri)) { + JSC.throwInvalidArguments("Unicode baseURI must already be encoded for now.\nnew URL(baseuRI).toString() should do the trick.", .{}, global.ref(), exception); + bun.default_allocator.free(bun.constStrToU8(args.base_uri)); + args.base_uri = ""; + return args; + } + + if (args.base_url.protocol.len == 0) { + const protocol: string = if (args.ssl_config != null) "https" else "http"; + + args.base_uri = (if ((args.port == 80 and args.ssl_config == null) or (args.port == 443 and args.ssl_config != null)) + std.fmt.allocPrint(bun.default_allocator, "{s}://{s}/{s}", .{ + protocol, + args.base_url.hostname, + strings.trimLeadingChar(args.base_url.pathname, '/'), + }) + else + std.fmt.allocPrint(bun.default_allocator, "{s}://{s}:{d}/{s}", .{ + protocol, + args.base_url.hostname, + args.port, + strings.trimLeadingChar(args.base_url.pathname, '/'), + })) catch unreachable; + + args.base_url = URL.parse(args.base_uri); + } + } else { + const hostname: string = + if (has_hostname and std.mem.span(args.hostname).len > 0) std.mem.span(args.hostname) else "localhost"; + const protocol: string = if (args.ssl_config != null) "https" else "http"; + + args.base_uri = (if ((args.port == 80 and args.ssl_config == null) or (args.port == 443 and args.ssl_config != null)) + std.fmt.allocPrint(bun.default_allocator, "{s}://{s}/", .{ + protocol, + hostname, + }) + else + std.fmt.allocPrint(bun.default_allocator, "{s}://{s}:{d}/", .{ protocol, hostname, args.port })) catch unreachable; + + if (!strings.isAllASCII(hostname)) { + JSC.throwInvalidArguments("Unicode hostnames must already be encoded for now.\nnew URL(input).hostname should do the trick.", .{}, global.ref(), exception); + bun.default_allocator.free(bun.constStrToU8(args.base_uri)); + args.base_uri = ""; + return args; + } + + args.base_url = URL.parse(args.base_uri); + } + + // I don't think there's a case where this can happen + // but let's check anyway, just in case + if (args.base_url.hostname.len == 0) { + JSC.throwInvalidArguments("baseURI must have a hostname", .{}, global.ref(), exception); + bun.default_allocator.free(bun.constStrToU8(args.base_uri)); + args.base_uri = ""; + return args; + } + + if (args.base_url.username.len > 0 or args.base_url.password.len > 0) { + JSC.throwInvalidArguments("baseURI can't have a username or password", .{}, global.ref(), exception); + bun.default_allocator.free(bun.constStrToU8(args.base_uri)); + args.base_uri = ""; + return args; + } + return args; } }; @@ -499,7 +592,9 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp this.* = .{ .resp = resp, .req = req, - .url = req.url(), + // this memory is owned by the Request object + .url = strings.append(bun.default_allocator, server.base_url_string_for_joining, req.url()) catch + @panic("Out of memory while joining the URL path?"), .method = HTTP.Method.which(req.method()) orelse .GET, .server = server, }; @@ -1030,7 +1125,7 @@ pub fn NewServer(comptime ssl_enabled_: bool, comptime debug_mode_: bool) type { app: *App = undefined, globalThis: *JSGlobalObject, - + base_url_string_for_joining: string = "", response_objects_pool: JSC.WebCore.Response.Pool = JSC.WebCore.Response.Pool{}, config: ServerConfig = ServerConfig{}, request_pool_allocator: std.mem.Allocator = undefined, @@ -1040,6 +1135,7 @@ pub fn NewServer(comptime ssl_enabled_: bool, comptime debug_mode_: bool) type { server.* = .{ .globalThis = globalThis, .config = config, + .base_url_string_for_joining = strings.trim(config.base_url.href, "/"), }; RequestContext.pool = bun.default_allocator.create(RequestContext.RequestContextStackAllocator) catch @panic("Out of memory!"); server.request_pool_allocator = RequestContext.pool.get(); @@ -1190,6 +1286,7 @@ pub fn NewServer(comptime ssl_enabled_: bool, comptime debug_mode_: bool) type { }, }, }; + request_object.url.mark(); // We keep the Request object alive for the duration of the request so that we can remove the pointer to the UWS request object. var args = [_]JSC.C.JSValueRef{JSC.WebCore.Request.Class.make(this.globalThis.ref(), request_object)}; ctx.request_js_object = args[0]; diff --git a/src/javascript/jsc/bindings/ZigGlobalObject.cpp b/src/javascript/jsc/bindings/ZigGlobalObject.cpp index 8d005a981..d3c7d2785 100644 --- a/src/javascript/jsc/bindings/ZigGlobalObject.cpp +++ b/src/javascript/jsc/bindings/ZigGlobalObject.cpp @@ -1085,7 +1085,7 @@ JSC::JSObject* GlobalObject::moduleLoaderCreateImportMetaProperties(JSGlobalObje metaProperties->putDirect(vm, clientData->builtinNames().resolvePublicName(), JSC::JSFunction::create(vm, JSC::jsCast<JSC::JSGlobalObject*>(globalObject), 0, - WTF::String("resolve"), functionImportMeta__resolve), + WTF::String("resolve"_s), functionImportMeta__resolve), 0); } diff --git a/src/javascript/jsc/bindings/bindings.zig b/src/javascript/jsc/bindings/bindings.zig index 7797ae4c5..2d384a924 100644 --- a/src/javascript/jsc/bindings/bindings.zig +++ b/src/javascript/jsc/bindings/bindings.zig @@ -2780,6 +2780,10 @@ pub const JSValue = enum(u64) { return @intToPtr(C_API.JSValueRef, @intCast(usize, @enumToInt(this))); } + pub inline fn c(this: C_API.JSValueRef) JSValue { + return @intToEnum(JSValue, @ptrToInt(this)); + } + pub inline fn fromRef(this: C_API.JSValueRef) JSValue { return @intToEnum(JSValue, @ptrToInt(this)); } diff --git a/src/javascript/jsc/webcore/response.zig b/src/javascript/jsc/webcore/response.zig index f1fa6223b..16122721f 100644 --- a/src/javascript/jsc/webcore/response.zig +++ b/src/javascript/jsc/webcore/response.zig @@ -231,7 +231,7 @@ pub const Response = struct { _: js.ExceptionRef, ) js.JSValueRef { // https://developer.mozilla.org/en-US/docs/Web/API/Response/url - return ZigString.init(this.url).withEncoding().toValueGC(ctx.ptr()).asObjectRef(); + return ZigString.init(this.url).toValueGC(ctx.ptr()).asObjectRef(); } pub fn getResponseType( @@ -4352,6 +4352,10 @@ pub const Request = struct { this.headers = null; } + if (this.url.isGloballyAllocated()) { + bun.default_allocator.free(bun.constStrToU8(this.url.slice())); + } + bun.default_allocator.destroy(this); } |