diff options
author | 2022-11-22 02:13:03 -0800 | |
---|---|---|
committer | 2022-11-22 02:13:03 -0800 | |
commit | d21aee514375e12335c61936ae302cd67f1f73bf (patch) | |
tree | e4985c55d27f7d1bcb7c8fa56441bd4711e15433 | |
parent | 65a56c2560a1ef7b036995a8eade45236f76f819 (diff) | |
download | bun-d21aee514375e12335c61936ae302cd67f1f73bf.tar.gz bun-d21aee514375e12335c61936ae302cd67f1f73bf.tar.zst bun-d21aee514375e12335c61936ae302cd67f1f73bf.zip |
Introduce `Bun.FileSystemRouter` API
26 files changed, 2446 insertions, 716 deletions
diff --git a/src/bun.js/api/bun.zig b/src/bun.js/api/bun.zig index 5015c4542..64c1259c4 100644 --- a/src/bun.js/api/bun.zig +++ b/src/bun.js/api/bun.zig @@ -31,7 +31,7 @@ const ImportKind = ast.ImportKind; const Analytics = @import("../../analytics/analytics_thread.zig"); const ZigString = @import("../../jsc.zig").ZigString; const Runtime = @import("../../runtime.zig"); -const Router = @import("./router.zig"); +const Router = @import("./filesystem_router.zig"); const ImportRecord = ast.ImportRecord; const DotEnv = @import("../../env_loader.zig"); const ParseResult = @import("../../bundler.zig").ParseResult; @@ -820,6 +820,10 @@ pub fn readFileAsString( } pub fn getPublicPath(to: string, origin: URL, comptime Writer: type, writer: Writer) void { + return getPublicPathWithAssetPrefix(to, origin, VirtualMachine.vm.bundler.options.routes.asset_prefix_path, comptime Writer, writer); +} + +pub fn getPublicPathWithAssetPrefix(to: string, origin: URL, asset_prefix: string, comptime Writer: type, writer: Writer) void { const relative_path = VirtualMachine.vm.bundler.fs.relativeTo(to); if (origin.isAbsolute()) { if (strings.hasPrefix(relative_path, "..") or strings.hasPrefix(relative_path, "./")) { @@ -834,7 +838,7 @@ pub fn getPublicPath(to: string, origin: URL, comptime Writer: type, writer: Wri origin.joinWrite( Writer, writer, - VirtualMachine.vm.bundler.options.routes.asset_prefix_path, + asset_prefix, "", relative_path, "", @@ -1083,7 +1087,7 @@ pub const Class = NewClass( }, .{ .match = .{ - .rfn = Router.match, + .rfn = Router.deprecatedBunGlobalMatch, }, .sleepSync = .{ .rfn = sleepSync, @@ -1280,6 +1284,9 @@ pub const Class = NewClass( .FFI = .{ .get = FFI.getter, }, + .FileSystemRouter = .{ + .get = getFileSystemRouter, + }, }, ); @@ -1796,6 +1803,16 @@ pub fn getTranspilerConstructor( return existing.asObjectRef(); } +pub fn getFileSystemRouter( + _: void, + ctx: js.JSContextRef, + _: js.JSValueRef, + _: js.JSStringRef, + _: js.ExceptionRef, +) js.JSValueRef { + return JSC.API.FileSystemRouter.getConstructor(ctx).asObjectRef(); +} + pub fn getHashObject( _: void, ctx: js.JSContextRef, diff --git a/src/bun.js/api/ffi.zig b/src/bun.js/api/ffi.zig index 269557bcc..a1d0640b2 100644 --- a/src/bun.js/api/ffi.zig +++ b/src/bun.js/api/ffi.zig @@ -31,7 +31,6 @@ const ImportKind = ast.ImportKind; const Analytics = @import("../../analytics/analytics_thread.zig"); const ZigString = @import("../../jsc.zig").ZigString; const Runtime = @import("../../runtime.zig"); -const Router = @import("./router.zig"); const ImportRecord = ast.ImportRecord; const DotEnv = @import("../../env_loader.zig"); const ParseResult = @import("../../bundler.zig").ParseResult; diff --git a/src/bun.js/api/filesystem_router.classes.ts b/src/bun.js/api/filesystem_router.classes.ts new file mode 100644 index 000000000..bf492a1c2 --- /dev/null +++ b/src/bun.js/api/filesystem_router.classes.ts @@ -0,0 +1,69 @@ +import { define } from "../scripts/class-definitions"; + +export default [ + define({ + name: "FileSystemRouter", + construct: true, + finalize: true, + JSType: "0b11101110", + + proto: { + match: { + fn: "match", + length: 1, + }, + routes: { + getter: "getRoutes", + cache: true, + }, + reload: { + fn: "reload", + length: 0, + }, + origin: { + getter: "getOrigin", + cache: true, + }, + style: { + getter: "getStyle", + cache: true, + }, + }, + klass: {}, + }), + + define({ + name: "MatchedRoute", + noConstructor: true, + JSType: "0b11101110", + construct: true, + finalize: true, + proto: { + params: { + getter: "getParams", + cache: true, + }, + pathname: { + getter: "getPathname", + cache: true, + }, + query: { + getter: "getQuery", + cache: true, + }, + name: { + getter: "getName", + cache: true, + }, + kind: { + getter: "getKind", + cache: true, + }, + filePath: { + getter: "getFilePath", + cache: true, + }, + }, + klass: {}, + }), +]; diff --git a/src/bun.js/api/filesystem_router.zig b/src/bun.js/api/filesystem_router.zig new file mode 100644 index 000000000..81ceb33a1 --- /dev/null +++ b/src/bun.js/api/filesystem_router.zig @@ -0,0 +1,701 @@ +const std = @import("std"); +const Api = @import("../../api/schema.zig").Api; +const http = @import("../../http.zig"); +const JavaScript = @import("../javascript.zig"); +const QueryStringMap = @import("../../url.zig").QueryStringMap; +const CombinedScanner = @import("../../url.zig").CombinedScanner; +const bun = @import("../../global.zig"); +const string = bun.string; +const JSC = @import("../../jsc.zig"); +const js = JSC.C; +const WebCore = @import("../webcore/response.zig"); +const Bundler = @import("../../bundler.zig"); +const VirtualMachine = JavaScript.VirtualMachine; +const ScriptSrcStream = std.io.FixedBufferStream([]u8); +const ZigString = JSC.ZigString; +const Fs = @import("../../fs.zig"); +const Base = @import("../base.zig"); +const getAllocator = Base.getAllocator; +const JSObject = JSC.JSObject; +const JSError = Base.JSError; +const JSValue = JSC.JSValue; +const JSGlobalObject = JSC.JSGlobalObject; +const strings = @import("strings"); +const NewClass = Base.NewClass; +const To = Base.To; +const Request = WebCore.Request; +const d = Base.d; +const FetchEvent = WebCore.FetchEvent; +const URLPath = @import("../../http/url_path.zig"); +const URL = @import("../../url.zig").URL; +const Log = @import("../../logger.zig"); +const Resolver = @import("../../resolver/resolver.zig").Resolver; +const Router = @import("../../router.zig"); + +const default_extensions = &[_][]const u8{ + "tsx", + "jsx", + "ts", + "mjs", + "cjs", + "js", +}; + +const DeprecatedGlobalRouter = struct { + pub fn deprecatedBunGlobalMatch( + _: void, + ctx: js.JSContextRef, + _: js.JSObjectRef, + _: js.JSObjectRef, + arguments: []const js.JSValueRef, + exception: js.ExceptionRef, + ) js.JSObjectRef { + if (arguments.len == 0) { + JSError(getAllocator(ctx), "Expected string, FetchEvent, or Request but there were no arguments", .{}, ctx, exception); + return null; + } + + const arg: JSC.JSValue = brk: { + if (FetchEvent.Class.isLoaded()) { + if (JSValue.as(JSValue.fromRef(arguments[0]), FetchEvent)) |fetch_event| { + if (fetch_event.request_context != null) { + return deprecatedMatchFetchEvent(ctx, fetch_event, exception); + } + + // When disconencted, we still have a copy of the request data in here + break :brk JSC.JSValue.fromRef(fetch_event.getRequest(ctx, null, undefined, null)); + } + } + break :brk JSC.JSValue.fromRef(arguments[0]); + }; + + var router = JavaScript.VirtualMachine.vm.bundler.router orelse { + JSError(getAllocator(ctx), "Bun.match needs a framework configured with routes", .{}, ctx, exception); + return null; + }; + + var path_: ?ZigString.Slice = null; + var pathname: string = ""; + defer { + if (path_) |path| { + path.deinit(); + } + } + + if (arg.isString()) { + var path_string = arg.getZigString(ctx); + path_ = path_string.toSlice(bun.default_allocator); + var url = URL.parse(path_.?.slice()); + pathname = url.pathname; + } else if (arg.as(Request)) |req| { + var url = URL.parse(req.url); + pathname = url.pathname; + } + + if (path_ == null) { + JSError(getAllocator(ctx), "Expected string, FetchEvent, or Request", .{}, ctx, exception); + return null; + } + + const url_path = URLPath.parse(path_.?.slice()) catch { + JSError(getAllocator(ctx), "Could not parse URL path", .{}, ctx, exception); + return null; + }; + + var match_params_fallback = std.heap.stackFallback(1024, bun.default_allocator); + var match_params_allocator = match_params_fallback.get(); + var match_params = Router.Param.List{}; + match_params.ensureTotalCapacity(match_params_allocator, 16) catch unreachable; + var prev_allocator = router.routes.allocator; + router.routes.allocator = match_params_allocator; + defer router.routes.allocator = prev_allocator; + if (router.routes.matchPage("", url_path, &match_params)) |matched| { + return createRouteObjectFromMatch(ctx, &matched); + } + // router.routes.matchPage + + return JSC.JSValue.jsNull().asObjectRef(); + } + + fn deprecatedMatchFetchEvent( + ctx: js.JSContextRef, + fetch_event: *const FetchEvent, + _: js.ExceptionRef, + ) js.JSObjectRef { + return createRouteObject(ctx, fetch_event.request_context.?); + } + + fn createRouteObject(ctx: js.JSContextRef, req: *const http.RequestContext) js.JSValueRef { + const route = &(req.matched_route orelse { + return js.JSValueMakeNull(ctx); + }); + + return createRouteObjectFromMatch(ctx, route); + } + + fn createRouteObjectFromMatch( + ctx: js.JSContextRef, + route: *const Router.Match, + ) js.JSValueRef { + var matched = MatchedRoute.init( + getAllocator(ctx), + route.*, + JSC.VirtualMachine.vm.refCountedString(JSC.VirtualMachine.vm.origin.href, null, false), + JSC.VirtualMachine.vm.refCountedString(JSC.VirtualMachine.vm.bundler.options.routes.asset_prefix_path, null, false), + ) catch unreachable; + + return matched.toJS(ctx).asObjectRef(); + } +}; + +pub const FileSystemRouter = struct { + origin: ?*JSC.RefString = null, + router: Router, + arena: *std.heap.ArenaAllocator = undefined, + allocator: std.mem.Allocator = undefined, + asset_prefix: ?*JSC.RefString = null, + + pub usingnamespace JSC.Codegen.JSFileSystemRouter; + + pub fn constructor(globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) callconv(.C) ?*FileSystemRouter { + const argument_ = callframe.arguments(1); + if (argument_.len == 0) { + globalThis.throwInvalidArguments("Expected object", .{}); + return null; + } + + const argument = argument_.ptr[0]; + if (argument.isEmptyOrUndefinedOrNull() or !argument.isObject()) { + globalThis.throwInvalidArguments("Expected object", .{}); + return null; + } + var vm = globalThis.bunVM(); + + var root_dir_path: ZigString.Slice = ZigString.Slice.fromUTF8NeverFree(vm.bundler.fs.top_level_dir); + defer root_dir_path.deinit(); + var origin_str: ZigString.Slice = .{}; + var asset_prefix_slice: ZigString.Slice = .{}; + + if (argument.get(globalThis, "style")) |style_val| { + if (!style_val.getZigString(globalThis).eqlComptime("nextjs")) { + globalThis.throwInvalidArguments("Only 'nextjs' style is currently implemented", .{}); + return null; + } + } else { + globalThis.throwInvalidArguments("Expected 'style' option (ex: \"style\": \"nextjs\")", .{}); + return null; + } + + if (argument.get(globalThis, "dir")) |dir| { + const root_dir_path_ = dir.toSlice(globalThis, globalThis.allocator()); + if (!(root_dir_path_.len == 0 or strings.eqlComptime(root_dir_path_.slice(), "."))) { + root_dir_path = root_dir_path_; + } + } + var arena = globalThis.allocator().create(std.heap.ArenaAllocator) catch unreachable; + arena.* = std.heap.ArenaAllocator.init(globalThis.allocator()); + var allocator = arena.allocator(); + var extensions = std.ArrayList(string).init(allocator); + if (argument.get(globalThis, "fileExtensions")) |file_extensions| { + if (!file_extensions.jsType().isArray()) { + globalThis.throwInvalidArguments("Expected fileExtensions to be an Array", .{}); + origin_str.deinit(); + arena.deinit(); + globalThis.allocator().destroy(arena); + return null; + } + + var iter = file_extensions.arrayIterator(globalThis); + extensions.ensureTotalCapacityPrecise(iter.len) catch unreachable; + while (iter.next()) |val| { + if (!val.isString()) { + globalThis.throwInvalidArguments("Expected fileExtensions to be an Array of strings", .{}); + origin_str.deinit(); + arena.deinit(); + globalThis.allocator().destroy(arena); + return null; + } + if (val.getLengthOfArray(globalThis) == 0) continue; + extensions.appendAssumeCapacity((val.toSlice(globalThis, allocator).clone(allocator) catch unreachable).slice()[1..]); + } + } + + if (argument.getTruthy(globalThis, "assetPrefix")) |asset_prefix| { + if (!asset_prefix.isString()) { + globalThis.throwInvalidArguments("Expected assetPrefix to be a string", .{}); + origin_str.deinit(); + arena.deinit(); + globalThis.allocator().destroy(arena); + return null; + } + + asset_prefix_slice = asset_prefix.toSlice(globalThis, allocator).clone(allocator) catch unreachable; + } + + var orig_log = vm.bundler.resolver.log; + var log = Log.Log.init(allocator); + vm.bundler.resolver.log = &log; + defer vm.bundler.resolver.log = orig_log; + + var path_to_use = (root_dir_path.cloneWithTrailingSlash(allocator) catch unreachable).slice(); + var root_dir_info = vm.bundler.resolver.readDirInfo(path_to_use) catch { + globalThis.throwValue(log.toJS(globalThis, globalThis.allocator(), "reading root directory")); + origin_str.deinit(); + arena.deinit(); + globalThis.allocator().destroy(arena); + return null; + } orelse { + globalThis.throw("Unable to find directory: {s}", .{root_dir_path.slice()}); + origin_str.deinit(); + arena.deinit(); + globalThis.allocator().destroy(arena); + return null; + }; + var router = Router.init(vm.bundler.fs, allocator, .{ + .dir = path_to_use, + .extensions = if (extensions.items.len > 0) extensions.items else default_extensions, + .asset_prefix_path = asset_prefix_slice.slice(), + }) catch unreachable; + router.loadRoutes(&log, root_dir_info, Resolver, &vm.bundler.resolver) catch { + globalThis.throwValue(log.toJS(globalThis, globalThis.allocator(), "loading routes")); + origin_str.deinit(); + arena.deinit(); + globalThis.allocator().destroy(arena); + return null; + }; + + if (argument.get(globalThis, "origin")) |origin| { + origin_str = origin.toSlice(globalThis, globalThis.allocator()); + } + + if (log.errors + log.warnings > 0) { + globalThis.throwValue(log.toJS(globalThis, globalThis.allocator(), "loading routes")); + origin_str.deinit(); + arena.deinit(); + globalThis.allocator().destroy(arena); + return null; + } + + var fs_router = globalThis.allocator().create(FileSystemRouter) catch unreachable; + fs_router.* = .{ + .origin = if (origin_str.len > 0) vm.refCountedString(origin_str.slice(), null, true) else null, + .asset_prefix = if (asset_prefix_slice.len > 0) vm.refCountedString(asset_prefix_slice.slice(), null, true) else null, + .router = router, + .arena = arena, + .allocator = allocator, + }; + return fs_router; + } + + pub fn reload(this: *FileSystemRouter, globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) callconv(.C) JSValue { + var this_value = callframe.this(); + + var arena = globalThis.allocator().create(std.heap.ArenaAllocator) catch unreachable; + arena.* = std.heap.ArenaAllocator.init(globalThis.allocator()); + + var allocator = arena.allocator(); + var vm = globalThis.bunVM(); + + var orig_log = vm.bundler.resolver.log; + var log = Log.Log.init(allocator); + vm.bundler.resolver.log = &log; + defer vm.bundler.resolver.log = orig_log; + + var root_dir_info = vm.bundler.resolver.readDirInfo(this.router.config.dir) catch { + globalThis.throwValue(log.toJS(globalThis, globalThis.allocator(), "reading root directory")); + return .zero; + } orelse { + globalThis.throw("Unable to find directory: {s}", .{this.router.config.dir}); + arena.deinit(); + globalThis.allocator().destroy(arena); + return .zero; + }; + + var router = Router.init(vm.bundler.fs, allocator, .{ + .dir = this.router.config.dir, + .extensions = allocator.dupe(string, this.router.config.extensions) catch unreachable, + .asset_prefix_path = this.router.config.asset_prefix_path, + }) catch unreachable; + router.loadRoutes(&log, root_dir_info, Resolver, &vm.bundler.resolver) catch { + globalThis.throwValue(log.toJS(globalThis, globalThis.allocator(), "loading routes")); + + arena.deinit(); + globalThis.allocator().destroy(arena); + return .zero; + }; + + this.arena.deinit(); + globalThis.allocator().destroy(this.arena); + + this.arena = arena; + @This().routesSetCached(this_value, globalThis, JSC.JSValue.zero); + this.allocator = allocator; + return this_value; + } + + pub fn match(this: *FileSystemRouter, globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) callconv(.C) JSValue { + const argument_ = callframe.arguments(2); + if (argument_.len == 0) { + globalThis.throwInvalidArguments("Expected string or Request", .{}); + return JSValue.zero; + } + + const argument = argument_.ptr[0]; + if (argument.isEmptyOrUndefinedOrNull() or !argument.isCell()) { + globalThis.throwInvalidArguments("Expected string or Request", .{}); + return JSValue.zero; + } + + var path: ZigString.Slice = brk: { + if (argument.isString()) { + break :brk argument.toSlice(globalThis, globalThis.allocator()).clone(globalThis.allocator()) catch unreachable; + } + + if (argument.isCell()) { + if (argument.as(JSC.WebCore.Request)) |req| { + req.ensureURL() catch unreachable; + break :brk ZigString.Slice.fromUTF8NeverFree(req.url).clone(globalThis.allocator()) catch unreachable; + } + } + + globalThis.throwInvalidArguments("Expected string or Request", .{}); + return JSValue.zero; + }; + + if (path.len == 0 or (path.len == 1 and path.ptr[0] == '/')) { + path = ZigString.Slice.fromUTF8NeverFree("/"); + } + + if (strings.hasPrefixComptime(path.slice(), "http:") or strings.hasPrefixComptime(path.slice(), "https:")) { + const prev_path = path; + path = ZigString.init(URL.parse(path.slice()).pathname).toSliceFast(globalThis.allocator()).clone(globalThis.allocator()) catch unreachable; + prev_path.deinit(); + } + + const url_path = URLPath.parse(path.slice()) catch |err| { + globalThis.throw("{s} parsing path: {s}", .{ @errorName(err), path.slice() }); + return JSValue.zero; + }; + var params = Router.Param.List{}; + defer params.deinit(globalThis.allocator()); + const route = this.router.routes.matchPageWithAllocator( + "", + url_path, + ¶ms, + globalThis.allocator(), + ) orelse { + return JSValue.jsNull(); + }; + + var result = MatchedRoute.init(globalThis.allocator(), route, this.origin, this.asset_prefix) catch unreachable; + return result.toJS(globalThis); + } + + pub fn getOrigin(this: *FileSystemRouter, globalThis: *JSC.JSGlobalObject) callconv(.C) JSValue { + if (this.origin) |origin| { + return JSC.ZigString.init(origin.slice()).withEncoding().toValueGC(globalThis); + } + + return JSValue.jsNull(); + } + + pub fn getRoutes(this: *FileSystemRouter, globalThis: *JSC.JSGlobalObject) callconv(.C) JSValue { + const paths = this.router.getEntryPoints() catch unreachable; + const names = this.router.getNames() catch unreachable; + var name_strings = bun.default_allocator.alloc(ZigString, names.len * 2) catch unreachable; + defer bun.default_allocator.free(name_strings); + var paths_strings = name_strings[names.len..]; + for (names) |name, i| { + name_strings[i] = ZigString.init(name).withEncoding(); + paths_strings[i] = ZigString.init(paths[i]).withEncoding(); + } + return JSC.JSValue.fromEntries( + globalThis, + name_strings.ptr, + paths_strings.ptr, + names.len, + true, + ); + } + + pub fn getStyle(_: *FileSystemRouter, globalThis: *JSC.JSGlobalObject) callconv(.C) JSValue { + return ZigString.static("nextjs").toValue(globalThis); + } + + pub fn getAssetPrefix(this: *FileSystemRouter, globalThis: *JSC.JSGlobalObject) callconv(.C) JSValue { + if (this.asset_prefix) |asset_prefix| { + return JSC.ZigString.init(asset_prefix.slice()).withEncoding().toValueGC(globalThis); + } + + return JSValue.jsNull(); + } + + pub fn finalize( + this: *FileSystemRouter, + ) callconv(.C) void { + if (this.asset_prefix) |prefix| { + prefix.deref(); + } + + if (this.origin) |prefix| { + prefix.deref(); + } + + this.arena.deinit(); + } +}; + +pub const MatchedRoute = struct { + route: *const Router.Match, + route_holder: Router.Match = undefined, + query_string_map: ?QueryStringMap = null, + param_map: ?QueryStringMap = null, + params_list_holder: Router.Param.List = .{}, + origin: ?*JSC.RefString = null, + asset_prefix: ?*JSC.RefString = null, + needs_deinit: bool = true, + + pub usingnamespace JSC.Codegen.JSMatchedRoute; + + pub fn getName(this: *MatchedRoute, globalThis: *JSC.JSGlobalObject) callconv(.C) JSValue { + return ZigString.init(this.route.name).withEncoding().toValueGC(globalThis); + } + + pub fn init(allocator: std.mem.Allocator, match: Router.Match, origin: ?*JSC.RefString, asset_prefix: ?*JSC.RefString) !*MatchedRoute { + var params_list = try match.params.clone(allocator); + + var route = try allocator.create(MatchedRoute); + + route.* = MatchedRoute{ + .route_holder = match, + .route = undefined, + .asset_prefix = asset_prefix, + .origin = origin, + }; + route.params_list_holder = params_list; + route.route = &route.route_holder; + route.route_holder.params = &route.params_list_holder; + if (origin) |o| { + o.ref(); + } + + if (asset_prefix) |prefix| { + prefix.ref(); + } + + return route; + } + + pub fn deinit(this: *MatchedRoute) void { + if (this.query_string_map) |*map| { + map.deinit(); + } + if (this.needs_deinit) { + if (this.route.pathname.len > 0 and bun.Mimalloc.mi_check_owned(this.route.pathname.ptr)) { + bun.Mimalloc.mi_free(bun.constStrToU8(this.route.pathname).ptr); + } + + this.params_list_holder.deinit(bun.default_allocator); + this.params_list_holder = .{}; + } + + if (this.origin) |o| { + o.deref(); + } + + if (this.asset_prefix) |prefix| { + prefix.deref(); + } + + bun.default_allocator.destroy(this); + } + + pub fn getFilePath( + this: *MatchedRoute, + globalThis: *JSC.JSGlobalObject, + ) callconv(.C) JSValue { + return ZigString.init(this.route.file_path) + .withEncoding() + .toValueGC(globalThis); + } + + pub fn finalize( + this: *MatchedRoute, + ) callconv(.C) void { + this.deinit(); + } + + pub fn getPathname(this: *MatchedRoute, globalThis: *JSC.JSGlobalObject) callconv(.C) JSValue { + return ZigString.init(this.route.pathname) + .withEncoding() + .toValueGC(globalThis); + } + + pub fn getRoute(this: *MatchedRoute, globalThis: *JSC.JSGlobalObject) callconv(.C) JSValue { + return ZigString.init(this.route.name) + .withEncoding() + .toValueGC(globalThis); + } + + const KindEnum = struct { + pub const exact = "exact"; + pub const catch_all = "catch-all"; + pub const optional_catch_all = "optional-catch-all"; + pub const dynamic = "dynamic"; + + // this is kinda stupid it should maybe just store it + pub fn init(name: string) ZigString { + if (strings.contains(name, "[[...")) { + return ZigString.init(optional_catch_all); + } else if (strings.contains(name, "[...")) { + return ZigString.init(catch_all); + } else if (strings.contains(name, "[")) { + return ZigString.init(dynamic); + } else { + return ZigString.init(exact); + } + } + }; + + pub fn getKind(this: *MatchedRoute, globalThis: *JSC.JSGlobalObject) callconv(.C) JSValue { + return KindEnum.init(this.route.name).toValue(globalThis); + } + + threadlocal var query_string_values_buf: [256]string = undefined; + threadlocal var query_string_value_refs_buf: [256]ZigString = undefined; + pub fn createQueryObject(ctx: js.JSContextRef, map: *QueryStringMap) callconv(.C) JSValue { + const QueryObjectCreator = struct { + query: *QueryStringMap, + pub fn create(this: *@This(), obj: *JSObject, global: *JSGlobalObject) void { + var iter = this.query.iter(); + while (iter.next(&query_string_values_buf)) |entry| { + const entry_name = entry.name; + var str = ZigString.init(entry_name).withEncoding(); + + std.debug.assert(entry.values.len > 0); + if (entry.values.len > 1) { + var values = query_string_value_refs_buf[0..entry.values.len]; + for (entry.values) |value, i| { + values[i] = ZigString.init(value).withEncoding(); + } + obj.putRecord(global, &str, values.ptr, values.len); + } else { + query_string_value_refs_buf[0] = ZigString.init(entry.values[0]).withEncoding(); + + obj.putRecord(global, &str, &query_string_value_refs_buf, 1); + } + } + } + }; + + var creator = QueryObjectCreator{ .query = map }; + + var value = JSObject.createWithInitializer(QueryObjectCreator, &creator, ctx, map.getNameCount()); + + return value; + } + + pub fn getScriptSrcString( + origin: []const u8, + comptime Writer: type, + writer: Writer, + file_path: string, + client_framework_enabled: bool, + ) void { + var entry_point_tempbuf: [bun.MAX_PATH_BYTES]u8 = undefined; + // We don't store the framework config including the client parts in the server + // instead, we just store a boolean saying whether we should generate this whenever the script is requested + // this is kind of bad. we should consider instead a way to inline the contents of the script. + if (client_framework_enabled) { + JSC.API.Bun.getPublicPath( + Bundler.ClientEntryPoint.generateEntryPointPath( + &entry_point_tempbuf, + Fs.PathName.init(file_path), + ), + origin, + Writer, + writer, + ); + } else { + JSC.API.Bun.getPublicPath(file_path, origin, Writer, writer); + } + } + + pub fn getScriptSrc( + this: *MatchedRoute, + globalThis: *JSC.JSGlobalObject, + ) callconv(.C) JSC.JSValue { + var buf: [bun.MAX_PATH_BYTES]u8 = undefined; + var stream = std.io.fixedBufferStream(&buf); + var writer = stream.writer(); + JSC.API.Bun.getPublicPathWithAssetPrefix( + this.route.file_path, + if (this.origin) |origin| URL.parse(origin) else URL{}, + if (this.asset_prefix) |prefix| prefix.slice() else "", + @TypeOf(&writer), + &writer, + ); + return ZigString.init(buf[0..writer.context.pos]) + .withEncoding() + .toValueGC(globalThis); + } + + pub fn getParams( + this: *MatchedRoute, + globalThis: *JSC.JSGlobalObject, + ) callconv(.C) JSC.JSValue { + if (this.route.params.len == 0) + return JSValue.createEmptyObject(globalThis, 0); + + if (this.param_map == null) { + this.param_map = QueryStringMap.initWithScanner( + globalThis.allocator(), + CombinedScanner.init( + "", + this.route.pathnameWithoutLeadingSlash(), + this.route.name, + this.route.params, + ), + ) catch + unreachable; + } + + return createQueryObject(globalThis, &this.param_map.?); + } + + pub fn getQuery( + this: *MatchedRoute, + globalThis: *JSC.JSGlobalObject, + ) callconv(.C) JSC.JSValue { + if (this.route.query_string.len == 0) { + return JSValue.createEmptyObject(globalThis, 0); + } + + if (this.query_string_map == null) { + if (this.route.params.len > 0) { + if (QueryStringMap.initWithScanner(globalThis.allocator(), CombinedScanner.init( + this.route.query_string, + this.route.pathnameWithoutLeadingSlash(), + this.route.name, + + this.route.params, + ))) |map| { + this.query_string_map = map; + } else |_| {} + } else { + if (QueryStringMap.init(globalThis.allocator(), this.route.query_string)) |map| { + this.query_string_map = map; + } else |_| {} + } + } + + // If it's still null, the query string has no names. + if (this.query_string_map) |*map| { + return createQueryObject(globalThis, map); + } + + return JSValue.createEmptyObject(globalThis, 0); + } +}; + +pub const deprecatedBunGlobalMatch = DeprecatedGlobalRouter.deprecatedBunGlobalMatch; diff --git a/src/bun.js/api/html_rewriter.zig b/src/bun.js/api/html_rewriter.zig index 9ab424491..91248dc5c 100644 --- a/src/bun.js/api/html_rewriter.zig +++ b/src/bun.js/api/html_rewriter.zig @@ -1,6 +1,5 @@ const std = @import("std"); const Api = @import("../../api/schema.zig").Api; -const FilesystemRouter = @import("../../router.zig"); const http = @import("../../http.zig"); const JavaScript = @import("../javascript.zig"); const QueryStringMap = @import("../../url.zig").QueryStringMap; diff --git a/src/bun.js/api/router.zig b/src/bun.js/api/router.zig deleted file mode 100644 index 21e8536c5..000000000 --- a/src/bun.js/api/router.zig +++ /dev/null @@ -1,507 +0,0 @@ -const std = @import("std"); -const Api = @import("../../api/schema.zig").Api; -const FilesystemRouter = @import("../../router.zig"); -const http = @import("../../http.zig"); -const JavaScript = @import("../javascript.zig"); -const QueryStringMap = @import("../../url.zig").QueryStringMap; -const CombinedScanner = @import("../../url.zig").CombinedScanner; -const bun = @import("../../global.zig"); -const string = bun.string; -const JSC = @import("../../jsc.zig"); -const js = JSC.C; -const WebCore = @import("../webcore/response.zig"); -const Router = @This(); -const Bundler = @import("../../bundler.zig"); -const VirtualMachine = JavaScript.VirtualMachine; -const ScriptSrcStream = std.io.FixedBufferStream([]u8); -const ZigString = JSC.ZigString; -const Fs = @import("../../fs.zig"); -const Base = @import("../base.zig"); -const getAllocator = Base.getAllocator; -const JSObject = JSC.JSObject; -const JSError = Base.JSError; -const JSValue = JSC.JSValue; -const JSGlobalObject = JSC.JSGlobalObject; -const strings = @import("strings"); -const NewClass = Base.NewClass; -const To = Base.To; -const Request = WebCore.Request; -const d = Base.d; -const FetchEvent = WebCore.FetchEvent; -const URLPath = @import("../../http/url_path.zig"); -const URL = @import("../../url.zig").URL; - -route: *const FilesystemRouter.Match, -route_holder: FilesystemRouter.Match = undefined, -needs_deinit: bool = false, -query_string_map: ?QueryStringMap = null, -param_map: ?QueryStringMap = null, -params_list_holder: FilesystemRouter.Param.List = .{}, - -pub fn importRoute( - this: *Router, - ctx: js.JSContextRef, - _: js.JSObjectRef, - _: js.JSObjectRef, - _: []const js.JSValueRef, - _: js.ExceptionRef, -) js.JSObjectRef { - const prom = JSC.JSModuleLoader.loadAndEvaluateModule(ctx.ptr(), &ZigString.init(this.route.file_path)); - - VirtualMachine.vm.tick(); - - return prom.result(ctx.ptr().vm()).asRef(); -} - -pub fn match( - _: void, - ctx: js.JSContextRef, - _: js.JSObjectRef, - _: js.JSObjectRef, - arguments: []const js.JSValueRef, - exception: js.ExceptionRef, -) js.JSObjectRef { - if (arguments.len == 0) { - JSError(getAllocator(ctx), "Expected string, FetchEvent, or Request but there were no arguments", .{}, ctx, exception); - return null; - } - - const arg: JSC.JSValue = brk: { - if (FetchEvent.Class.isLoaded()) { - if (JSValue.as(JSValue.fromRef(arguments[0]), FetchEvent)) |fetch_event| { - if (fetch_event.request_context != null) { - return matchFetchEvent(ctx, fetch_event, exception); - } - - // When disconencted, we still have a copy of the request data in here - break :brk JSC.JSValue.fromRef(fetch_event.getRequest(ctx, null, undefined, null)); - } - } - break :brk JSC.JSValue.fromRef(arguments[0]); - }; - - var router = JavaScript.VirtualMachine.vm.bundler.router orelse { - JSError(getAllocator(ctx), "Bun.match needs a framework configured with routes", .{}, ctx, exception); - return null; - }; - - var path_: ?ZigString.Slice = null; - var pathname: string = ""; - defer { - if (path_) |path| { - path.deinit(); - } - } - - if (arg.isString()) { - var path_string = arg.getZigString(ctx.ptr()); - path_ = path_string.toSlice(bun.default_allocator); - var url = URL.parse(path_.?.slice()); - pathname = url.pathname; - } else if (arg.as(Request)) |req| { - var url = URL.parse(req.url); - pathname = url.pathname; - } - - if (path_ == null) { - JSError(getAllocator(ctx), "Expected string, FetchEvent, or Request", .{}, ctx, exception); - return null; - } - - const url_path = URLPath.parse(path_.?.slice()) catch { - JSError(getAllocator(ctx), "Could not parse URL path", .{}, ctx, exception); - return null; - }; - - var match_params_fallback = std.heap.stackFallback(1024, bun.default_allocator); - var match_params_allocator = match_params_fallback.get(); - var match_params = FilesystemRouter.Param.List{}; - match_params.ensureTotalCapacity(match_params_allocator, 16) catch unreachable; - var prev_allocator = router.routes.allocator; - router.routes.allocator = match_params_allocator; - defer router.routes.allocator = prev_allocator; - if (router.routes.matchPage("", url_path, &match_params)) |matched| { - var match_ = matched; - var params_list = match_.params.clone(bun.default_allocator) catch unreachable; - var instance = getAllocator(ctx).create(Router) catch unreachable; - - instance.* = Router{ - .route_holder = match_, - .route = undefined, - }; - instance.params_list_holder = params_list; - instance.route = &instance.route_holder; - instance.route_holder.params = &instance.params_list_holder; - - return Instance.make(ctx, instance); - } - // router.routes.matchPage - - return JSC.JSValue.jsNull().asObjectRef(); -} - -fn matchRequest( - ctx: js.JSContextRef, - request: *const Request, - _: js.ExceptionRef, -) js.JSObjectRef { - return createRouteObject(ctx, request.request_context); -} - -fn matchFetchEvent( - ctx: js.JSContextRef, - fetch_event: *const FetchEvent, - _: js.ExceptionRef, -) js.JSObjectRef { - return createRouteObject(ctx, fetch_event.request_context.?); -} - -fn createRouteObject(ctx: js.JSContextRef, req: *const http.RequestContext) js.JSValueRef { - const route = &(req.matched_route orelse { - return js.JSValueMakeNull(ctx); - }); - - return createRouteObjectFromMatch(ctx, route); -} - -fn createRouteObjectFromMatch( - ctx: js.JSContextRef, - route: *const FilesystemRouter.Match, -) js.JSValueRef { - var router = getAllocator(ctx).create(Router) catch unreachable; - router.* = Router{ - .route = route, - }; - - return Instance.make(ctx, router); -} - -pub const Instance = NewClass( - Router, - .{ - .name = "Route", - .read_only = true, - .ts = .{ - .class = d.ts.class{ - .tsdoc = - \\Route matched from the filesystem. - , - }, - }, - }, - .{ - .finalize = finalize, - .import = .{ - .rfn = importRoute, - .ts = d.ts{ - .@"return" = "Object", - .tsdoc = - \\Synchronously load & evaluate the file corresponding to the route. Returns the exports of the route. This is similar to `await import(route.filepath)`, except it's synchronous. It is recommended to use this function instead of `import`. - , - }, - }, - }, - .{ - .pathname = .{ - .get = getPathname, - .ro = true, - .ts = d.ts{ - .@"return" = "string", - .@"tsdoc" = "URL path as appears in a web browser's address bar", - }, - }, - - .filePath = .{ - .get = getFilePath, - .ro = true, - .ts = d.ts{ - .@"return" = "string", - .tsdoc = - \\Project-relative filesystem path to the route file. - , - }, - }, - .scriptSrc = .{ - .get = getScriptSrc, - .ro = true, - .ts = d.ts{ - .@"return" = "string", - .tsdoc = - \\src attribute of the script tag that loads the route. - , - }, - }, - .kind = .{ - .get = getKind, - .ro = true, - .ts = d.ts{ - .@"return" = "\"exact\" | \"dynamic\" | \"catch-all\" | \"optional-catch-all\"", - }, - }, - .name = .{ - .get = getRoute, - .ro = true, - .ts = d.ts{ - .@"return" = "string", - .tsdoc = - \\Route name - \\@example - \\`"blog/posts/[id]"` - \\`"blog/posts/[id]/[[...slug]]"` - \\`"blog"` - , - }, - }, - .query = .{ - .get = getQuery, - .ro = true, - .ts = d.ts{ - .@"return" = "Record<string, string | string[]>", - .tsdoc = - \\Route parameters & parsed query string values as a key-value object - \\ - \\@example - \\```js - \\console.assert(router.query.id === "123"); - \\console.assert(router.pathname === "/blog/posts/123"); - \\console.assert(router.route === "blog/posts/[id]"); - \\``` - , - }, - }, - .params = .{ - .get = getParams, - .ro = true, - .ts = d.ts{ - .@"return" = "Record<string, string | string[]>", - .tsdoc = - \\Route parameters as a key-value object - \\ - \\@example - \\```js - \\console.assert(router.query.id === "123"); - \\console.assert(router.pathname === "/blog/posts/123"); - \\console.assert(router.route === "blog/posts/[id]"); - \\``` - , - }, - }, - }, -); - -pub fn getFilePath( - this: *Router, - ctx: js.JSContextRef, - _: js.JSObjectRef, - _: js.JSStringRef, - _: js.ExceptionRef, -) js.JSValueRef { - return ZigString.init(this.route.file_path) - .withEncoding() - .toValueGC(ctx.ptr()).asRef(); -} - -pub fn finalize( - this: *Router, -) void { - if (this.query_string_map) |*map| { - map.deinit(); - } - - if (this.needs_deinit) { - this.params_list_holder.deinit(bun.default_allocator); - this.params_list_holder = .{}; - this.needs_deinit = false; - } - - bun.default_allocator.destroy(this); -} - -pub fn getPathname( - this: *Router, - ctx: js.JSContextRef, - _: js.JSObjectRef, - _: js.JSStringRef, - _: js.ExceptionRef, -) js.JSValueRef { - return ZigString.init(this.route.pathname) - .withEncoding() - .toValueGC(ctx.ptr()).asRef(); -} - -pub fn getRoute( - this: *Router, - ctx: js.JSContextRef, - _: js.JSObjectRef, - _: js.JSStringRef, - _: js.ExceptionRef, -) js.JSValueRef { - return ZigString.init(this.route.name) - .withEncoding() - .toValueGC(ctx.ptr()).asRef(); -} - -const KindEnum = struct { - pub const exact = "exact"; - pub const catch_all = "catch-all"; - pub const optional_catch_all = "optional-catch-all"; - pub const dynamic = "dynamic"; - - // this is kinda stupid it should maybe just store it - pub fn init(name: string) ZigString { - if (strings.contains(name, "[[...")) { - return ZigString.init(optional_catch_all); - } else if (strings.contains(name, "[...")) { - return ZigString.init(catch_all); - } else if (strings.contains(name, "[")) { - return ZigString.init(dynamic); - } else { - return ZigString.init(exact); - } - } -}; - -pub fn getKind( - this: *Router, - ctx: js.JSContextRef, - _: js.JSObjectRef, - _: js.JSStringRef, - _: js.ExceptionRef, -) js.JSValueRef { - return KindEnum.init(this.route.name).toValue(ctx.ptr()).asRef(); -} - -threadlocal var query_string_values_buf: [256]string = undefined; -threadlocal var query_string_value_refs_buf: [256]ZigString = undefined; -pub fn createQueryObject(ctx: js.JSContextRef, map: *QueryStringMap, _: js.ExceptionRef) callconv(.C) js.JSValueRef { - const QueryObjectCreator = struct { - query: *QueryStringMap, - pub fn create(this: *@This(), obj: *JSObject, global: *JSGlobalObject) void { - var iter = this.query.iter(); - var str: ZigString = undefined; - while (iter.next(&query_string_values_buf)) |entry| { - str = ZigString.init(entry.name); - - std.debug.assert(entry.values.len > 0); - if (entry.values.len > 1) { - var values = query_string_value_refs_buf[0..entry.values.len]; - for (entry.values) |value, i| { - values[i] = ZigString.init(value); - } - obj.putRecord(global, &str, values.ptr, values.len); - } else { - query_string_value_refs_buf[0] = ZigString.init(entry.values[0]); - - obj.putRecord(global, &str, &query_string_value_refs_buf, 1); - } - } - } - }; - - var creator = QueryObjectCreator{ .query = map }; - - var value = JSObject.createWithInitializer(QueryObjectCreator, &creator, ctx.ptr(), map.getNameCount()); - - return value.asRef(); -} - -pub fn getScriptSrcString( - comptime Writer: type, - writer: Writer, - file_path: string, - client_framework_enabled: bool, -) void { - var entry_point_tempbuf: [bun.MAX_PATH_BYTES]u8 = undefined; - // We don't store the framework config including the client parts in the server - // instead, we just store a boolean saying whether we should generate this whenever the script is requested - // this is kind of bad. we should consider instead a way to inline the contents of the script. - if (client_framework_enabled) { - JSC.API.Bun.getPublicPath( - Bundler.ClientEntryPoint.generateEntryPointPath( - &entry_point_tempbuf, - Fs.PathName.init(file_path), - ), - VirtualMachine.vm.origin, - Writer, - writer, - ); - } else { - JSC.API.Bun.getPublicPath(file_path, VirtualMachine.vm.origin, Writer, writer); - } -} - -pub fn getScriptSrc( - this: *Router, - ctx: js.JSContextRef, - _: js.JSObjectRef, - _: js.JSStringRef, - _: js.ExceptionRef, -) js.JSValueRef { - var script_src_buffer = std.ArrayList(u8).init(bun.default_allocator); - - var writer = script_src_buffer.writer(); - getScriptSrcString(@TypeOf(&writer), &writer, this.route.file_path, this.route.client_framework_enabled); - - return ZigString.init(script_src_buffer.toOwnedSlice()).toExternalValue(ctx.ptr()).asObjectRef(); -} - -pub fn getParams( - this: *Router, - ctx: js.JSContextRef, - _: js.JSObjectRef, - _: js.JSStringRef, - exception: js.ExceptionRef, -) js.JSValueRef { - if (this.param_map == null) { - if (this.route.params.len > 0) { - if (QueryStringMap.initWithScanner(getAllocator(ctx), CombinedScanner.init( - "", - this.route.pathnameWithoutLeadingSlash(), - this.route.name, - this.route.params, - ))) |map| { - this.param_map = map; - } else |_| {} - } - } - - // If it's still null, there are no params - if (this.param_map) |*map| { - return createQueryObject(ctx, map, exception); - } else { - return JSValue.createEmptyObject(ctx.ptr(), 0).asRef(); - } -} - -pub fn getQuery( - this: *Router, - ctx: js.JSContextRef, - _: js.JSObjectRef, - _: js.JSStringRef, - exception: js.ExceptionRef, -) js.JSValueRef { - if (this.query_string_map == null) { - if (this.route.params.len > 0) { - if (QueryStringMap.initWithScanner(getAllocator(ctx), CombinedScanner.init( - this.route.query_string, - this.route.pathnameWithoutLeadingSlash(), - this.route.name, - - this.route.params, - ))) |map| { - this.query_string_map = map; - } else |_| {} - } else if (this.route.query_string.len > 0) { - if (QueryStringMap.init(getAllocator(ctx), this.route.query_string)) |map| { - this.query_string_map = map; - } else |_| {} - } - } - - // If it's still null, the query string has no names. - if (this.query_string_map) |*map| { - return createQueryObject(ctx, map, exception); - } else { - return JSValue.createEmptyObject(ctx.ptr(), 0).asRef(); - } -} diff --git a/src/bun.js/api/server.zig b/src/bun.js/api/server.zig index 92a3c23d0..c4724b1b8 100644 --- a/src/bun.js/api/server.zig +++ b/src/bun.js/api/server.zig @@ -31,7 +31,6 @@ const ImportKind = ast.ImportKind; const Analytics = @import("../../analytics/analytics_thread.zig"); const ZigString = @import("javascript_core").ZigString; const Runtime = @import("../../runtime.zig"); -const Router = @import("./router.zig"); const ImportRecord = ast.ImportRecord; const DotEnv = @import("../../env_loader.zig"); const ParseResult = @import("../../bundler.zig").ParseResult; diff --git a/src/bun.js/api/transpiler.zig b/src/bun.js/api/transpiler.zig index 11b127799..cd47e1997 100644 --- a/src/bun.js/api/transpiler.zig +++ b/src/bun.js/api/transpiler.zig @@ -1,6 +1,5 @@ const std = @import("std"); const Api = @import("../../api/schema.zig").Api; -const FilesystemRouter = @import("../../router.zig"); const http = @import("../../http.zig"); const JavaScript = @import("../javascript.zig"); const QueryStringMap = @import("../../url.zig").QueryStringMap; diff --git a/src/bun.js/base.zig b/src/bun.js/base.zig index 663861547..e456a7113 100644 --- a/src/bun.js/base.zig +++ b/src/bun.js/base.zig @@ -19,7 +19,7 @@ const Test = @import("./test/jest.zig"); const Fetch = WebCore.Fetch; const Response = WebCore.Response; const Request = WebCore.Request; -const Router = @import("./api/router.zig"); +const Router = @import("./api/filesystem_router.zig"); const FetchEvent = WebCore.FetchEvent; const IdentityContext = @import("../identity_context.zig").IdentityContext; const uws = @import("uws"); diff --git a/src/bun.js/bindings/ZigGeneratedClasses+DOMClientIsoSubspaces.h b/src/bun.js/bindings/ZigGeneratedClasses+DOMClientIsoSubspaces.h index 368708fe9..07ffb69e5 100644 --- a/src/bun.js/bindings/ZigGeneratedClasses+DOMClientIsoSubspaces.h +++ b/src/bun.js/bindings/ZigGeneratedClasses+DOMClientIsoSubspaces.h @@ -11,7 +11,9 @@ std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSHA512Constructor;std: std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSHA384Constructor;std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSHA256; std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSHA256Constructor;std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSHA512_256; std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForSHA512_256Constructor;std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForServerWebSocket; -std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForServerWebSocketConstructor;std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForExpect; +std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForServerWebSocketConstructor;std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForFileSystemRouter; +std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForFileSystemRouterConstructor;std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForMatchedRoute; +std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForExpect; std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForExpectConstructor;std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForTextDecoder; std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForTextDecoderConstructor;std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForRequest; std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForRequestConstructor;std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForResponse; diff --git a/src/bun.js/bindings/ZigGeneratedClasses+DOMIsoSubspaces.h b/src/bun.js/bindings/ZigGeneratedClasses+DOMIsoSubspaces.h index 752456c7b..71b1d1348 100644 --- a/src/bun.js/bindings/ZigGeneratedClasses+DOMIsoSubspaces.h +++ b/src/bun.js/bindings/ZigGeneratedClasses+DOMIsoSubspaces.h @@ -11,7 +11,9 @@ std::unique_ptr<IsoSubspace> m_subspaceForSHA512Constructor;std::unique_ptr<IsoS std::unique_ptr<IsoSubspace> m_subspaceForSHA384Constructor;std::unique_ptr<IsoSubspace> m_subspaceForSHA256; std::unique_ptr<IsoSubspace> m_subspaceForSHA256Constructor;std::unique_ptr<IsoSubspace> m_subspaceForSHA512_256; std::unique_ptr<IsoSubspace> m_subspaceForSHA512_256Constructor;std::unique_ptr<IsoSubspace> m_subspaceForServerWebSocket; -std::unique_ptr<IsoSubspace> m_subspaceForServerWebSocketConstructor;std::unique_ptr<IsoSubspace> m_subspaceForExpect; +std::unique_ptr<IsoSubspace> m_subspaceForServerWebSocketConstructor;std::unique_ptr<IsoSubspace> m_subspaceForFileSystemRouter; +std::unique_ptr<IsoSubspace> m_subspaceForFileSystemRouterConstructor;std::unique_ptr<IsoSubspace> m_subspaceForMatchedRoute; +std::unique_ptr<IsoSubspace> m_subspaceForExpect; std::unique_ptr<IsoSubspace> m_subspaceForExpectConstructor;std::unique_ptr<IsoSubspace> m_subspaceForTextDecoder; std::unique_ptr<IsoSubspace> m_subspaceForTextDecoderConstructor;std::unique_ptr<IsoSubspace> m_subspaceForRequest; std::unique_ptr<IsoSubspace> m_subspaceForRequestConstructor;std::unique_ptr<IsoSubspace> m_subspaceForResponse; diff --git a/src/bun.js/bindings/ZigGeneratedClasses+lazyStructureHeader.h b/src/bun.js/bindings/ZigGeneratedClasses+lazyStructureHeader.h index ff158b59e..f2d881bb5 100644 --- a/src/bun.js/bindings/ZigGeneratedClasses+lazyStructureHeader.h +++ b/src/bun.js/bindings/ZigGeneratedClasses+lazyStructureHeader.h @@ -76,6 +76,18 @@ JSC::Structure* JSServerWebSocketStructure() { return m_JSServerWebSocket.getIni JSC::LazyClassStructure m_JSServerWebSocket; bool hasJSServerWebSocketSetterValue { false }; mutable JSC::WriteBarrier<JSC::Unknown> m_JSServerWebSocketSetterValue; +JSC::Structure* JSFileSystemRouterStructure() { return m_JSFileSystemRouter.getInitializedOnMainThread(this); } + JSC::JSObject* JSFileSystemRouterConstructor() { return m_JSFileSystemRouter.constructorInitializedOnMainThread(this); } + JSC::JSValue JSFileSystemRouterPrototype() { return m_JSFileSystemRouter.prototypeInitializedOnMainThread(this); } + JSC::LazyClassStructure m_JSFileSystemRouter; + bool hasJSFileSystemRouterSetterValue { false }; + mutable JSC::WriteBarrier<JSC::Unknown> m_JSFileSystemRouterSetterValue; +JSC::Structure* JSMatchedRouteStructure() { return m_JSMatchedRoute.getInitializedOnMainThread(this); } + JSC::JSObject* JSMatchedRouteConstructor() { return m_JSMatchedRoute.constructorInitializedOnMainThread(this); } + JSC::JSValue JSMatchedRoutePrototype() { return m_JSMatchedRoute.prototypeInitializedOnMainThread(this); } + JSC::LazyClassStructure m_JSMatchedRoute; + bool hasJSMatchedRouteSetterValue { false }; + mutable JSC::WriteBarrier<JSC::Unknown> m_JSMatchedRouteSetterValue; JSC::Structure* JSExpectStructure() { return m_JSExpect.getInitializedOnMainThread(this); } JSC::JSObject* JSExpectConstructor() { return m_JSExpect.constructorInitializedOnMainThread(this); } JSC::JSValue JSExpectPrototype() { return m_JSExpect.prototypeInitializedOnMainThread(this); } diff --git a/src/bun.js/bindings/ZigGeneratedClasses+lazyStructureImpl.h b/src/bun.js/bindings/ZigGeneratedClasses+lazyStructureImpl.h index b04e10089..d50c8c38f 100644 --- a/src/bun.js/bindings/ZigGeneratedClasses+lazyStructureImpl.h +++ b/src/bun.js/bindings/ZigGeneratedClasses+lazyStructureImpl.h @@ -77,6 +77,18 @@ void GlobalObject::initGeneratedLazyClasses() { init.setStructure(WebCore::JSServerWebSocket::createStructure(init.vm, init.global, init.prototype)); init.setConstructor(WebCore::JSServerWebSocket::createConstructor(init.vm, init.global, init.prototype)); }); + m_JSFileSystemRouter.initLater( + [](LazyClassStructure::Initializer& init) { + init.setPrototype(WebCore::JSFileSystemRouter::createPrototype(init.vm, reinterpret_cast<Zig::GlobalObject*>(init.global))); + init.setStructure(WebCore::JSFileSystemRouter::createStructure(init.vm, init.global, init.prototype)); + init.setConstructor(WebCore::JSFileSystemRouter::createConstructor(init.vm, init.global, init.prototype)); + }); + m_JSMatchedRoute.initLater( + [](LazyClassStructure::Initializer& init) { + init.setPrototype(WebCore::JSMatchedRoute::createPrototype(init.vm, reinterpret_cast<Zig::GlobalObject*>(init.global))); + init.setStructure(WebCore::JSMatchedRoute::createStructure(init.vm, init.global, init.prototype)); + + }); m_JSExpect.initLater( [](LazyClassStructure::Initializer& init) { init.setPrototype(WebCore::JSExpect::createPrototype(init.vm, reinterpret_cast<Zig::GlobalObject*>(init.global))); @@ -124,6 +136,8 @@ void GlobalObject::visitGeneratedLazyClasses(GlobalObject *thisObject, Visitor& thisObject->m_JSSHA256.visit(visitor); visitor.append(thisObject->m_JSSHA256SetterValue); thisObject->m_JSSHA512_256.visit(visitor); visitor.append(thisObject->m_JSSHA512_256SetterValue); thisObject->m_JSServerWebSocket.visit(visitor); visitor.append(thisObject->m_JSServerWebSocketSetterValue); + thisObject->m_JSFileSystemRouter.visit(visitor); visitor.append(thisObject->m_JSFileSystemRouterSetterValue); + thisObject->m_JSMatchedRoute.visit(visitor); visitor.append(thisObject->m_JSMatchedRouteSetterValue); thisObject->m_JSExpect.visit(visitor); visitor.append(thisObject->m_JSExpectSetterValue); thisObject->m_JSTextDecoder.visit(visitor); visitor.append(thisObject->m_JSTextDecoderSetterValue); thisObject->m_JSRequest.visit(visitor); visitor.append(thisObject->m_JSRequestSetterValue); diff --git a/src/bun.js/bindings/ZigGeneratedClasses.cpp b/src/bun.js/bindings/ZigGeneratedClasses.cpp index cdff44ee0..4d96e8e0a 100644 --- a/src/bun.js/bindings/ZigGeneratedClasses.cpp +++ b/src/bun.js/bindings/ZigGeneratedClasses.cpp @@ -468,15 +468,6 @@ JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSTCPSocketConstructor::construct(J return JSValue::encode(instance); } -extern "C" EncodedJSValue TCPSocket__create(Zig::GlobalObject* globalObject, void* ptr) -{ - auto& vm = globalObject->vm(); - JSC::Structure* structure = globalObject->JSTCPSocketStructure(); - JSTCPSocket* instance = JSTCPSocket::create(vm, globalObject, structure, ptr); - - return JSValue::encode(instance); -} - void JSTCPSocketConstructor::initializeProperties(VM& vm, JSC::JSGlobalObject* globalObject, JSTCPSocketPrototype* prototype) { } @@ -566,6 +557,15 @@ JSObject* JSTCPSocket::createPrototype(VM& vm, JSDOMGlobalObject* globalObject) return JSTCPSocketPrototype::create(vm, globalObject, JSTCPSocketPrototype::createStructure(vm, globalObject, globalObject->objectPrototype())); } +extern "C" EncodedJSValue TCPSocket__create(Zig::GlobalObject* globalObject, void* ptr) +{ + auto& vm = globalObject->vm(); + JSC::Structure* structure = globalObject->JSTCPSocketStructure(); + JSTCPSocket* instance = JSTCPSocket::create(vm, globalObject, structure, ptr); + + return JSValue::encode(instance); +} + template<typename Visitor> void JSTCPSocket::visitChildrenImpl(JSCell* cell, Visitor& visitor) { @@ -1043,15 +1043,6 @@ JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSTLSSocketConstructor::construct(J return JSValue::encode(instance); } -extern "C" EncodedJSValue TLSSocket__create(Zig::GlobalObject* globalObject, void* ptr) -{ - auto& vm = globalObject->vm(); - JSC::Structure* structure = globalObject->JSTLSSocketStructure(); - JSTLSSocket* instance = JSTLSSocket::create(vm, globalObject, structure, ptr); - - return JSValue::encode(instance); -} - void JSTLSSocketConstructor::initializeProperties(VM& vm, JSC::JSGlobalObject* globalObject, JSTLSSocketPrototype* prototype) { } @@ -1141,6 +1132,15 @@ JSObject* JSTLSSocket::createPrototype(VM& vm, JSDOMGlobalObject* globalObject) return JSTLSSocketPrototype::create(vm, globalObject, JSTLSSocketPrototype::createStructure(vm, globalObject, globalObject->objectPrototype())); } +extern "C" EncodedJSValue TLSSocket__create(Zig::GlobalObject* globalObject, void* ptr) +{ + auto& vm = globalObject->vm(); + JSC::Structure* structure = globalObject->JSTLSSocketStructure(); + JSTLSSocket* instance = JSTLSSocket::create(vm, globalObject, structure, ptr); + + return JSValue::encode(instance); +} + template<typename Visitor> void JSTLSSocket::visitChildrenImpl(JSCell* cell, Visitor& visitor) { @@ -1522,15 +1522,6 @@ JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSListenerConstructor::construct(JS return JSValue::encode(instance); } -extern "C" EncodedJSValue Listener__create(Zig::GlobalObject* globalObject, void* ptr) -{ - auto& vm = globalObject->vm(); - JSC::Structure* structure = globalObject->JSListenerStructure(); - JSListener* instance = JSListener::create(vm, globalObject, structure, ptr); - - return JSValue::encode(instance); -} - void JSListenerConstructor::initializeProperties(VM& vm, JSC::JSGlobalObject* globalObject, JSListenerPrototype* prototype) { } @@ -1614,6 +1605,15 @@ JSObject* JSListener::createPrototype(VM& vm, JSDOMGlobalObject* globalObject) return JSListenerPrototype::create(vm, globalObject, JSListenerPrototype::createStructure(vm, globalObject, globalObject->objectPrototype())); } +extern "C" EncodedJSValue Listener__create(Zig::GlobalObject* globalObject, void* ptr) +{ + auto& vm = globalObject->vm(); + JSC::Structure* structure = globalObject->JSListenerStructure(); + JSListener* instance = JSListener::create(vm, globalObject, structure, ptr); + + return JSValue::encode(instance); +} + template<typename Visitor> void JSListener::visitChildrenImpl(JSCell* cell, Visitor& visitor) { @@ -2097,15 +2097,6 @@ JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSSubprocessConstructor::construct( return JSValue::encode(instance); } -extern "C" EncodedJSValue Subprocess__create(Zig::GlobalObject* globalObject, void* ptr) -{ - auto& vm = globalObject->vm(); - JSC::Structure* structure = globalObject->JSSubprocessStructure(); - JSSubprocess* instance = JSSubprocess::create(vm, globalObject, structure, ptr); - - return JSValue::encode(instance); -} - void JSSubprocessConstructor::initializeProperties(VM& vm, JSC::JSGlobalObject* globalObject, JSSubprocessPrototype* prototype) { } @@ -2195,6 +2186,15 @@ JSObject* JSSubprocess::createPrototype(VM& vm, JSDOMGlobalObject* globalObject) return JSSubprocessPrototype::create(vm, globalObject, JSSubprocessPrototype::createStructure(vm, globalObject, globalObject->objectPrototype())); } +extern "C" EncodedJSValue Subprocess__create(Zig::GlobalObject* globalObject, void* ptr) +{ + auto& vm = globalObject->vm(); + JSC::Structure* structure = globalObject->JSSubprocessStructure(); + JSSubprocess* instance = JSSubprocess::create(vm, globalObject, structure, ptr); + + return JSValue::encode(instance); +} + template<typename Visitor> void JSSubprocess::visitChildrenImpl(JSCell* cell, Visitor& visitor) { @@ -2446,15 +2446,6 @@ JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSSHA1Constructor::construct(JSC::J return JSValue::encode(instance); } -extern "C" EncodedJSValue SHA1__create(Zig::GlobalObject* globalObject, void* ptr) -{ - auto& vm = globalObject->vm(); - JSC::Structure* structure = globalObject->JSSHA1Structure(); - JSSHA1* instance = JSSHA1::create(vm, globalObject, structure, ptr); - - return JSValue::encode(instance); -} - void JSSHA1Constructor::initializeProperties(VM& vm, JSC::JSGlobalObject* globalObject, JSSHA1Prototype* prototype) { } @@ -2537,6 +2528,15 @@ JSObject* JSSHA1::createPrototype(VM& vm, JSDOMGlobalObject* globalObject) { return JSSHA1Prototype::create(vm, globalObject, JSSHA1Prototype::createStructure(vm, globalObject, globalObject->objectPrototype())); } + +extern "C" EncodedJSValue SHA1__create(Zig::GlobalObject* globalObject, void* ptr) +{ + auto& vm = globalObject->vm(); + JSC::Structure* structure = globalObject->JSSHA1Structure(); + JSSHA1* instance = JSSHA1::create(vm, globalObject, structure, ptr); + + return JSValue::encode(instance); +} class JSMD5Prototype final : public JSC::JSNonFinalObject { public: using Base = JSC::JSNonFinalObject; @@ -2750,15 +2750,6 @@ JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSMD5Constructor::construct(JSC::JS return JSValue::encode(instance); } -extern "C" EncodedJSValue MD5__create(Zig::GlobalObject* globalObject, void* ptr) -{ - auto& vm = globalObject->vm(); - JSC::Structure* structure = globalObject->JSMD5Structure(); - JSMD5* instance = JSMD5::create(vm, globalObject, structure, ptr); - - return JSValue::encode(instance); -} - void JSMD5Constructor::initializeProperties(VM& vm, JSC::JSGlobalObject* globalObject, JSMD5Prototype* prototype) { } @@ -2841,6 +2832,15 @@ JSObject* JSMD5::createPrototype(VM& vm, JSDOMGlobalObject* globalObject) { return JSMD5Prototype::create(vm, globalObject, JSMD5Prototype::createStructure(vm, globalObject, globalObject->objectPrototype())); } + +extern "C" EncodedJSValue MD5__create(Zig::GlobalObject* globalObject, void* ptr) +{ + auto& vm = globalObject->vm(); + JSC::Structure* structure = globalObject->JSMD5Structure(); + JSMD5* instance = JSMD5::create(vm, globalObject, structure, ptr); + + return JSValue::encode(instance); +} class JSMD4Prototype final : public JSC::JSNonFinalObject { public: using Base = JSC::JSNonFinalObject; @@ -3054,15 +3054,6 @@ JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSMD4Constructor::construct(JSC::JS return JSValue::encode(instance); } -extern "C" EncodedJSValue MD4__create(Zig::GlobalObject* globalObject, void* ptr) -{ - auto& vm = globalObject->vm(); - JSC::Structure* structure = globalObject->JSMD4Structure(); - JSMD4* instance = JSMD4::create(vm, globalObject, structure, ptr); - - return JSValue::encode(instance); -} - void JSMD4Constructor::initializeProperties(VM& vm, JSC::JSGlobalObject* globalObject, JSMD4Prototype* prototype) { } @@ -3145,6 +3136,15 @@ JSObject* JSMD4::createPrototype(VM& vm, JSDOMGlobalObject* globalObject) { return JSMD4Prototype::create(vm, globalObject, JSMD4Prototype::createStructure(vm, globalObject, globalObject->objectPrototype())); } + +extern "C" EncodedJSValue MD4__create(Zig::GlobalObject* globalObject, void* ptr) +{ + auto& vm = globalObject->vm(); + JSC::Structure* structure = globalObject->JSMD4Structure(); + JSMD4* instance = JSMD4::create(vm, globalObject, structure, ptr); + + return JSValue::encode(instance); +} class JSSHA224Prototype final : public JSC::JSNonFinalObject { public: using Base = JSC::JSNonFinalObject; @@ -3358,15 +3358,6 @@ JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSSHA224Constructor::construct(JSC: return JSValue::encode(instance); } -extern "C" EncodedJSValue SHA224__create(Zig::GlobalObject* globalObject, void* ptr) -{ - auto& vm = globalObject->vm(); - JSC::Structure* structure = globalObject->JSSHA224Structure(); - JSSHA224* instance = JSSHA224::create(vm, globalObject, structure, ptr); - - return JSValue::encode(instance); -} - void JSSHA224Constructor::initializeProperties(VM& vm, JSC::JSGlobalObject* globalObject, JSSHA224Prototype* prototype) { } @@ -3449,6 +3440,15 @@ JSObject* JSSHA224::createPrototype(VM& vm, JSDOMGlobalObject* globalObject) { return JSSHA224Prototype::create(vm, globalObject, JSSHA224Prototype::createStructure(vm, globalObject, globalObject->objectPrototype())); } + +extern "C" EncodedJSValue SHA224__create(Zig::GlobalObject* globalObject, void* ptr) +{ + auto& vm = globalObject->vm(); + JSC::Structure* structure = globalObject->JSSHA224Structure(); + JSSHA224* instance = JSSHA224::create(vm, globalObject, structure, ptr); + + return JSValue::encode(instance); +} class JSSHA512Prototype final : public JSC::JSNonFinalObject { public: using Base = JSC::JSNonFinalObject; @@ -3662,15 +3662,6 @@ JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSSHA512Constructor::construct(JSC: return JSValue::encode(instance); } -extern "C" EncodedJSValue SHA512__create(Zig::GlobalObject* globalObject, void* ptr) -{ - auto& vm = globalObject->vm(); - JSC::Structure* structure = globalObject->JSSHA512Structure(); - JSSHA512* instance = JSSHA512::create(vm, globalObject, structure, ptr); - - return JSValue::encode(instance); -} - void JSSHA512Constructor::initializeProperties(VM& vm, JSC::JSGlobalObject* globalObject, JSSHA512Prototype* prototype) { } @@ -3753,6 +3744,15 @@ JSObject* JSSHA512::createPrototype(VM& vm, JSDOMGlobalObject* globalObject) { return JSSHA512Prototype::create(vm, globalObject, JSSHA512Prototype::createStructure(vm, globalObject, globalObject->objectPrototype())); } + +extern "C" EncodedJSValue SHA512__create(Zig::GlobalObject* globalObject, void* ptr) +{ + auto& vm = globalObject->vm(); + JSC::Structure* structure = globalObject->JSSHA512Structure(); + JSSHA512* instance = JSSHA512::create(vm, globalObject, structure, ptr); + + return JSValue::encode(instance); +} class JSSHA384Prototype final : public JSC::JSNonFinalObject { public: using Base = JSC::JSNonFinalObject; @@ -3966,15 +3966,6 @@ JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSSHA384Constructor::construct(JSC: return JSValue::encode(instance); } -extern "C" EncodedJSValue SHA384__create(Zig::GlobalObject* globalObject, void* ptr) -{ - auto& vm = globalObject->vm(); - JSC::Structure* structure = globalObject->JSSHA384Structure(); - JSSHA384* instance = JSSHA384::create(vm, globalObject, structure, ptr); - - return JSValue::encode(instance); -} - void JSSHA384Constructor::initializeProperties(VM& vm, JSC::JSGlobalObject* globalObject, JSSHA384Prototype* prototype) { } @@ -4057,6 +4048,15 @@ JSObject* JSSHA384::createPrototype(VM& vm, JSDOMGlobalObject* globalObject) { return JSSHA384Prototype::create(vm, globalObject, JSSHA384Prototype::createStructure(vm, globalObject, globalObject->objectPrototype())); } + +extern "C" EncodedJSValue SHA384__create(Zig::GlobalObject* globalObject, void* ptr) +{ + auto& vm = globalObject->vm(); + JSC::Structure* structure = globalObject->JSSHA384Structure(); + JSSHA384* instance = JSSHA384::create(vm, globalObject, structure, ptr); + + return JSValue::encode(instance); +} class JSSHA256Prototype final : public JSC::JSNonFinalObject { public: using Base = JSC::JSNonFinalObject; @@ -4270,15 +4270,6 @@ JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSSHA256Constructor::construct(JSC: return JSValue::encode(instance); } -extern "C" EncodedJSValue SHA256__create(Zig::GlobalObject* globalObject, void* ptr) -{ - auto& vm = globalObject->vm(); - JSC::Structure* structure = globalObject->JSSHA256Structure(); - JSSHA256* instance = JSSHA256::create(vm, globalObject, structure, ptr); - - return JSValue::encode(instance); -} - void JSSHA256Constructor::initializeProperties(VM& vm, JSC::JSGlobalObject* globalObject, JSSHA256Prototype* prototype) { } @@ -4361,6 +4352,15 @@ JSObject* JSSHA256::createPrototype(VM& vm, JSDOMGlobalObject* globalObject) { return JSSHA256Prototype::create(vm, globalObject, JSSHA256Prototype::createStructure(vm, globalObject, globalObject->objectPrototype())); } + +extern "C" EncodedJSValue SHA256__create(Zig::GlobalObject* globalObject, void* ptr) +{ + auto& vm = globalObject->vm(); + JSC::Structure* structure = globalObject->JSSHA256Structure(); + JSSHA256* instance = JSSHA256::create(vm, globalObject, structure, ptr); + + return JSValue::encode(instance); +} class JSSHA512_256Prototype final : public JSC::JSNonFinalObject { public: using Base = JSC::JSNonFinalObject; @@ -4574,15 +4574,6 @@ JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSSHA512_256Constructor::construct( return JSValue::encode(instance); } -extern "C" EncodedJSValue SHA512_256__create(Zig::GlobalObject* globalObject, void* ptr) -{ - auto& vm = globalObject->vm(); - JSC::Structure* structure = globalObject->JSSHA512_256Structure(); - JSSHA512_256* instance = JSSHA512_256::create(vm, globalObject, structure, ptr); - - return JSValue::encode(instance); -} - void JSSHA512_256Constructor::initializeProperties(VM& vm, JSC::JSGlobalObject* globalObject, JSSHA512_256Prototype* prototype) { } @@ -4665,6 +4656,15 @@ JSObject* JSSHA512_256::createPrototype(VM& vm, JSDOMGlobalObject* globalObject) { return JSSHA512_256Prototype::create(vm, globalObject, JSSHA512_256Prototype::createStructure(vm, globalObject, globalObject->objectPrototype())); } + +extern "C" EncodedJSValue SHA512_256__create(Zig::GlobalObject* globalObject, void* ptr) +{ + auto& vm = globalObject->vm(); + JSC::Structure* structure = globalObject->JSSHA512_256Structure(); + JSSHA512_256* instance = JSSHA512_256::create(vm, globalObject, structure, ptr); + + return JSValue::encode(instance); +} class JSServerWebSocketPrototype final : public JSC::JSNonFinalObject { public: using Base = JSC::JSNonFinalObject; @@ -5256,15 +5256,6 @@ JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSServerWebSocketConstructor::const return JSValue::encode(instance); } -extern "C" EncodedJSValue ServerWebSocket__create(Zig::GlobalObject* globalObject, void* ptr) -{ - auto& vm = globalObject->vm(); - JSC::Structure* structure = globalObject->JSServerWebSocketStructure(); - JSServerWebSocket* instance = JSServerWebSocket::create(vm, globalObject, structure, ptr); - - return JSValue::encode(instance); -} - void JSServerWebSocketConstructor::initializeProperties(VM& vm, JSC::JSGlobalObject* globalObject, JSServerWebSocketPrototype* prototype) { } @@ -5348,6 +5339,15 @@ JSObject* JSServerWebSocket::createPrototype(VM& vm, JSDOMGlobalObject* globalOb return JSServerWebSocketPrototype::create(vm, globalObject, JSServerWebSocketPrototype::createStructure(vm, globalObject, globalObject->objectPrototype())); } +extern "C" EncodedJSValue ServerWebSocket__create(Zig::GlobalObject* globalObject, void* ptr) +{ + auto& vm = globalObject->vm(); + JSC::Structure* structure = globalObject->JSServerWebSocketStructure(); + JSServerWebSocket* instance = JSServerWebSocket::create(vm, globalObject, structure, ptr); + + return JSValue::encode(instance); +} + template<typename Visitor> void JSServerWebSocket::visitChildrenImpl(JSCell* cell, Visitor& visitor) { @@ -5383,6 +5383,819 @@ void JSServerWebSocket::visitOutputConstraintsImpl(JSCell* cell, Visitor& visito } DEFINE_VISIT_OUTPUT_CONSTRAINTS(JSServerWebSocket); +class JSFileSystemRouterPrototype final : public JSC::JSNonFinalObject { +public: + using Base = JSC::JSNonFinalObject; + + static JSFileSystemRouterPrototype* create(JSC::VM& vm, JSGlobalObject* globalObject, JSC::Structure* structure) + { + JSFileSystemRouterPrototype* ptr = new (NotNull, JSC::allocateCell<JSFileSystemRouterPrototype>(vm)) JSFileSystemRouterPrototype(vm, globalObject, structure); + ptr->finishCreation(vm, globalObject); + return ptr; + } + + DECLARE_INFO; + template<typename CellType, JSC::SubspaceAccess> + static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + return &vm.plainObjectSpace(); + } + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info()); + } + +private: + JSFileSystemRouterPrototype(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure) + : Base(vm, structure) + { + } + + void finishCreation(JSC::VM&, JSC::JSGlobalObject*); +}; + +class JSFileSystemRouterConstructor final : public JSC::InternalFunction { +public: + using Base = JSC::InternalFunction; + static JSFileSystemRouterConstructor* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure, JSFileSystemRouterPrototype* prototype); + + static constexpr unsigned StructureFlags = Base::StructureFlags; + static constexpr bool needsDestruction = false; + + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::InternalFunctionType, StructureFlags), info()); + } + + template<typename, JSC::SubspaceAccess mode> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + if constexpr (mode == JSC::SubspaceAccess::Concurrently) + return nullptr; + return WebCore::subspaceForImpl<JSFileSystemRouterConstructor, WebCore::UseCustomHeapCellType::No>( + vm, + [](auto& spaces) { return spaces.m_clientSubspaceForFileSystemRouterConstructor.get(); }, + [](auto& spaces, auto&& space) { spaces.m_clientSubspaceForFileSystemRouterConstructor = WTFMove(space); }, + [](auto& spaces) { return spaces.m_subspaceForFileSystemRouterConstructor.get(); }, + [](auto& spaces, auto&& space) { spaces.m_subspaceForFileSystemRouterConstructor = WTFMove(space); }); + } + + void initializeProperties(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSFileSystemRouterPrototype* prototype); + + // Must be defined for each specialization class. + static JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES construct(JSC::JSGlobalObject*, JSC::CallFrame*); + + DECLARE_EXPORT_INFO; + +private: + JSFileSystemRouterConstructor(JSC::VM& vm, JSC::Structure* structure); + void finishCreation(JSC::VM&, JSC::JSGlobalObject* globalObject, JSFileSystemRouterPrototype* prototype); +}; + +extern "C" void* FileSystemRouterClass__construct(JSC::JSGlobalObject*, JSC::CallFrame*); +JSC_DECLARE_CUSTOM_GETTER(jsFileSystemRouterConstructor); +extern "C" void FileSystemRouterClass__finalize(void*); + +extern "C" EncodedJSValue FileSystemRouterPrototype__match(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame); +JSC_DECLARE_HOST_FUNCTION(FileSystemRouterPrototype__matchCallback); + +extern "C" JSC::EncodedJSValue FileSystemRouterPrototype__getOrigin(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject); +JSC_DECLARE_CUSTOM_GETTER(FileSystemRouterPrototype__originGetterWrap); + +extern "C" EncodedJSValue FileSystemRouterPrototype__reload(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame); +JSC_DECLARE_HOST_FUNCTION(FileSystemRouterPrototype__reloadCallback); + +extern "C" JSC::EncodedJSValue FileSystemRouterPrototype__getRoutes(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject); +JSC_DECLARE_CUSTOM_GETTER(FileSystemRouterPrototype__routesGetterWrap); + +extern "C" JSC::EncodedJSValue FileSystemRouterPrototype__getStyle(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject); +JSC_DECLARE_CUSTOM_GETTER(FileSystemRouterPrototype__styleGetterWrap); + +STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSFileSystemRouterPrototype, JSFileSystemRouterPrototype::Base); + +static const HashTableValue JSFileSystemRouterPrototypeTableValues[] = { + { "match"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, FileSystemRouterPrototype__matchCallback, 1 } }, + { "origin"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { HashTableValue::GetterSetterType, FileSystemRouterPrototype__originGetterWrap, 0 } }, + { "reload"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, FileSystemRouterPrototype__reloadCallback, 0 } }, + { "routes"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { HashTableValue::GetterSetterType, FileSystemRouterPrototype__routesGetterWrap, 0 } }, + { "style"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { HashTableValue::GetterSetterType, FileSystemRouterPrototype__styleGetterWrap, 0 } } +}; + +const ClassInfo JSFileSystemRouterPrototype::s_info = { "FileSystemRouter"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSFileSystemRouterPrototype) }; + +JSC_DEFINE_CUSTOM_GETTER(jsFileSystemRouterConstructor, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName)) +{ + VM& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto* globalObject = reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject); + auto* prototype = jsDynamicCast<JSFileSystemRouterPrototype*>(JSValue::decode(thisValue)); + + if (UNLIKELY(!prototype)) + return throwVMTypeError(lexicalGlobalObject, throwScope); + return JSValue::encode(globalObject->JSFileSystemRouterConstructor()); +} + +JSC_DEFINE_HOST_FUNCTION(FileSystemRouterPrototype__matchCallback, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) +{ + auto& vm = lexicalGlobalObject->vm(); + + JSFileSystemRouter* thisObject = jsDynamicCast<JSFileSystemRouter*>(callFrame->thisValue()); + + if (UNLIKELY(!thisObject)) { + auto throwScope = DECLARE_THROW_SCOPE(vm); + return throwVMTypeError(lexicalGlobalObject, throwScope); + } + + JSC::EnsureStillAliveScope thisArg = JSC::EnsureStillAliveScope(thisObject); + + return FileSystemRouterPrototype__match(thisObject->wrapped(), lexicalGlobalObject, callFrame); +} + +JSC_DEFINE_CUSTOM_GETTER(FileSystemRouterPrototype__originGetterWrap, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + auto& vm = lexicalGlobalObject->vm(); + Zig::GlobalObject* globalObject = reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + JSFileSystemRouter* thisObject = jsCast<JSFileSystemRouter*>(JSValue::decode(thisValue)); + JSC::EnsureStillAliveScope thisArg = JSC::EnsureStillAliveScope(thisObject); + + if (JSValue cachedValue = thisObject->m_origin.get()) + return JSValue::encode(cachedValue); + + JSC::JSValue result = JSC::JSValue::decode( + FileSystemRouterPrototype__getOrigin(thisObject->wrapped(), globalObject)); + RETURN_IF_EXCEPTION(throwScope, {}); + thisObject->m_origin.set(vm, thisObject, result); + RELEASE_AND_RETURN(throwScope, JSValue::encode(result)); +} + +extern "C" void FileSystemRouterPrototype__originSetCachedValue(JSC::EncodedJSValue thisValue, JSC::JSGlobalObject* globalObject, JSC::EncodedJSValue value) +{ + auto& vm = globalObject->vm(); + auto* thisObject = jsCast<JSFileSystemRouter*>(JSValue::decode(thisValue)); + thisObject->m_origin.set(vm, thisObject, JSValue::decode(value)); +} + +extern "C" EncodedJSValue FileSystemRouterPrototype__originGetCachedValue(JSC::EncodedJSValue thisValue) +{ + auto* thisObject = jsCast<JSFileSystemRouter*>(JSValue::decode(thisValue)); + return JSValue::encode(thisObject->m_origin.get()); +} + +JSC_DEFINE_HOST_FUNCTION(FileSystemRouterPrototype__reloadCallback, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame)) +{ + auto& vm = lexicalGlobalObject->vm(); + + JSFileSystemRouter* thisObject = jsDynamicCast<JSFileSystemRouter*>(callFrame->thisValue()); + + if (UNLIKELY(!thisObject)) { + auto throwScope = DECLARE_THROW_SCOPE(vm); + return throwVMTypeError(lexicalGlobalObject, throwScope); + } + + JSC::EnsureStillAliveScope thisArg = JSC::EnsureStillAliveScope(thisObject); + + return FileSystemRouterPrototype__reload(thisObject->wrapped(), lexicalGlobalObject, callFrame); +} + +JSC_DEFINE_CUSTOM_GETTER(FileSystemRouterPrototype__routesGetterWrap, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + auto& vm = lexicalGlobalObject->vm(); + Zig::GlobalObject* globalObject = reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + JSFileSystemRouter* thisObject = jsCast<JSFileSystemRouter*>(JSValue::decode(thisValue)); + JSC::EnsureStillAliveScope thisArg = JSC::EnsureStillAliveScope(thisObject); + + if (JSValue cachedValue = thisObject->m_routes.get()) + return JSValue::encode(cachedValue); + + JSC::JSValue result = JSC::JSValue::decode( + FileSystemRouterPrototype__getRoutes(thisObject->wrapped(), globalObject)); + RETURN_IF_EXCEPTION(throwScope, {}); + thisObject->m_routes.set(vm, thisObject, result); + RELEASE_AND_RETURN(throwScope, JSValue::encode(result)); +} + +extern "C" void FileSystemRouterPrototype__routesSetCachedValue(JSC::EncodedJSValue thisValue, JSC::JSGlobalObject* globalObject, JSC::EncodedJSValue value) +{ + auto& vm = globalObject->vm(); + auto* thisObject = jsCast<JSFileSystemRouter*>(JSValue::decode(thisValue)); + thisObject->m_routes.set(vm, thisObject, JSValue::decode(value)); +} + +extern "C" EncodedJSValue FileSystemRouterPrototype__routesGetCachedValue(JSC::EncodedJSValue thisValue) +{ + auto* thisObject = jsCast<JSFileSystemRouter*>(JSValue::decode(thisValue)); + return JSValue::encode(thisObject->m_routes.get()); +} + +JSC_DEFINE_CUSTOM_GETTER(FileSystemRouterPrototype__styleGetterWrap, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + auto& vm = lexicalGlobalObject->vm(); + Zig::GlobalObject* globalObject = reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + JSFileSystemRouter* thisObject = jsCast<JSFileSystemRouter*>(JSValue::decode(thisValue)); + JSC::EnsureStillAliveScope thisArg = JSC::EnsureStillAliveScope(thisObject); + + if (JSValue cachedValue = thisObject->m_style.get()) + return JSValue::encode(cachedValue); + + JSC::JSValue result = JSC::JSValue::decode( + FileSystemRouterPrototype__getStyle(thisObject->wrapped(), globalObject)); + RETURN_IF_EXCEPTION(throwScope, {}); + thisObject->m_style.set(vm, thisObject, result); + RELEASE_AND_RETURN(throwScope, JSValue::encode(result)); +} + +extern "C" void FileSystemRouterPrototype__styleSetCachedValue(JSC::EncodedJSValue thisValue, JSC::JSGlobalObject* globalObject, JSC::EncodedJSValue value) +{ + auto& vm = globalObject->vm(); + auto* thisObject = jsCast<JSFileSystemRouter*>(JSValue::decode(thisValue)); + thisObject->m_style.set(vm, thisObject, JSValue::decode(value)); +} + +extern "C" EncodedJSValue FileSystemRouterPrototype__styleGetCachedValue(JSC::EncodedJSValue thisValue) +{ + auto* thisObject = jsCast<JSFileSystemRouter*>(JSValue::decode(thisValue)); + return JSValue::encode(thisObject->m_style.get()); +} + +void JSFileSystemRouterPrototype::finishCreation(JSC::VM& vm, JSC::JSGlobalObject* globalObject) +{ + Base::finishCreation(vm); + reifyStaticProperties(vm, JSFileSystemRouter::info(), JSFileSystemRouterPrototypeTableValues, *this); + JSC_TO_STRING_TAG_WITHOUT_TRANSITION(); +} + +void JSFileSystemRouterConstructor::finishCreation(VM& vm, JSC::JSGlobalObject* globalObject, JSFileSystemRouterPrototype* prototype) +{ + Base::finishCreation(vm, 0, "FileSystemRouter"_s, PropertyAdditionMode::WithoutStructureTransition); + + putDirectWithoutTransition(vm, vm.propertyNames->prototype, prototype, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly); + ASSERT(inherits(info())); +} + +JSFileSystemRouterConstructor::JSFileSystemRouterConstructor(JSC::VM& vm, JSC::Structure* structure) + : Base(vm, structure, construct, construct) +{ +} + +JSFileSystemRouterConstructor* JSFileSystemRouterConstructor::create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure, JSFileSystemRouterPrototype* prototype) +{ + JSFileSystemRouterConstructor* ptr = new (NotNull, JSC::allocateCell<JSFileSystemRouterConstructor>(vm)) JSFileSystemRouterConstructor(vm, structure); + ptr->finishCreation(vm, globalObject, prototype); + return ptr; +} + +JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSFileSystemRouterConstructor::construct(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame) +{ + Zig::GlobalObject* globalObject = reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject); + JSC::VM& vm = globalObject->vm(); + JSObject* newTarget = asObject(callFrame->newTarget()); + auto* constructor = globalObject->JSFileSystemRouterConstructor(); + Structure* structure = globalObject->JSFileSystemRouterStructure(); + if (constructor != newTarget) { + auto scope = DECLARE_THROW_SCOPE(vm); + + auto* functionGlobalObject = reinterpret_cast<Zig::GlobalObject*>( + // ShadowRealm functions belong to a different global object. + getFunctionRealm(globalObject, newTarget)); + RETURN_IF_EXCEPTION(scope, {}); + structure = InternalFunction::createSubclassStructure( + globalObject, + newTarget, + functionGlobalObject->JSFileSystemRouterStructure()); + } + + void* ptr = FileSystemRouterClass__construct(globalObject, callFrame); + + if (UNLIKELY(!ptr)) { + return JSValue::encode(JSC::jsUndefined()); + } + + JSFileSystemRouter* instance = JSFileSystemRouter::create(vm, globalObject, structure, ptr); + + return JSValue::encode(instance); +} + +void JSFileSystemRouterConstructor::initializeProperties(VM& vm, JSC::JSGlobalObject* globalObject, JSFileSystemRouterPrototype* prototype) +{ +} + +const ClassInfo JSFileSystemRouterConstructor::s_info = { "Function"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSFileSystemRouterConstructor) }; + +extern "C" EncodedJSValue FileSystemRouter__getConstructor(Zig::GlobalObject* globalObject) +{ + return JSValue::encode(globalObject->JSFileSystemRouterConstructor()); +} + +JSFileSystemRouter::~JSFileSystemRouter() +{ + if (m_ctx) { + FileSystemRouterClass__finalize(m_ctx); + } +} +void JSFileSystemRouter::destroy(JSCell* cell) +{ + static_cast<JSFileSystemRouter*>(cell)->JSFileSystemRouter::~JSFileSystemRouter(); +} + +const ClassInfo JSFileSystemRouter::s_info = { "FileSystemRouter"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSFileSystemRouter) }; + +void JSFileSystemRouter::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + ASSERT(inherits(info())); +} + +JSFileSystemRouter* JSFileSystemRouter::create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure, void* ctx) +{ + JSFileSystemRouter* ptr = new (NotNull, JSC::allocateCell<JSFileSystemRouter>(vm)) JSFileSystemRouter(vm, structure, ctx); + ptr->finishCreation(vm); + return ptr; +} + +extern "C" void* FileSystemRouter__fromJS(JSC::EncodedJSValue value) +{ + JSC::JSValue decodedValue = JSC::JSValue::decode(value); + if (!decodedValue || decodedValue.isUndefinedOrNull()) + return nullptr; + + JSFileSystemRouter* object = JSC::jsDynamicCast<JSFileSystemRouter*>(decodedValue); + + if (!object) + return nullptr; + + return object->wrapped(); +} + +extern "C" bool FileSystemRouter__dangerouslySetPtr(JSC::EncodedJSValue value, void* ptr) +{ + JSFileSystemRouter* object = JSC::jsDynamicCast<JSFileSystemRouter*>(JSValue::decode(value)); + if (!object) + return false; + + object->m_ctx = ptr; + return true; +} + +extern "C" const size_t FileSystemRouter__ptrOffset = JSFileSystemRouter::offsetOfWrapped(); + +void JSFileSystemRouter::analyzeHeap(JSCell* cell, HeapAnalyzer& analyzer) +{ + auto* thisObject = jsCast<JSFileSystemRouter*>(cell); + if (void* wrapped = thisObject->wrapped()) { + // if (thisObject->scriptExecutionContext()) + // analyzer.setLabelForCell(cell, "url " + thisObject->scriptExecutionContext()->url().string()); + } + Base::analyzeHeap(cell, analyzer); +} + +JSObject* JSFileSystemRouter::createConstructor(VM& vm, JSGlobalObject* globalObject, JSValue prototype) +{ + return WebCore::JSFileSystemRouterConstructor::create(vm, globalObject, WebCore::JSFileSystemRouterConstructor::createStructure(vm, globalObject, globalObject->functionPrototype()), jsCast<WebCore::JSFileSystemRouterPrototype*>(prototype)); +} + +JSObject* JSFileSystemRouter::createPrototype(VM& vm, JSDOMGlobalObject* globalObject) +{ + return JSFileSystemRouterPrototype::create(vm, globalObject, JSFileSystemRouterPrototype::createStructure(vm, globalObject, globalObject->objectPrototype())); +} + +extern "C" EncodedJSValue FileSystemRouter__create(Zig::GlobalObject* globalObject, void* ptr) +{ + auto& vm = globalObject->vm(); + JSC::Structure* structure = globalObject->JSFileSystemRouterStructure(); + JSFileSystemRouter* instance = JSFileSystemRouter::create(vm, globalObject, structure, ptr); + + return JSValue::encode(instance); +} + +template<typename Visitor> +void JSFileSystemRouter::visitChildrenImpl(JSCell* cell, Visitor& visitor) +{ + JSFileSystemRouter* thisObject = jsCast<JSFileSystemRouter*>(cell); + ASSERT_GC_OBJECT_INHERITS(thisObject, info()); + Base::visitChildren(thisObject, visitor); + + visitor.append(thisObject->m_origin); + visitor.append(thisObject->m_routes); + visitor.append(thisObject->m_style); +} + +DEFINE_VISIT_CHILDREN(JSFileSystemRouter); + +template<typename Visitor> +void JSFileSystemRouter::visitAdditionalChildren(Visitor& visitor) +{ + JSFileSystemRouter* thisObject = this; + ASSERT_GC_OBJECT_INHERITS(thisObject, info()); + + visitor.append(thisObject->m_origin); + visitor.append(thisObject->m_routes); + visitor.append(thisObject->m_style); + ; +} + +DEFINE_VISIT_ADDITIONAL_CHILDREN(JSFileSystemRouter); + +template<typename Visitor> +void JSFileSystemRouter::visitOutputConstraintsImpl(JSCell* cell, Visitor& visitor) +{ + JSFileSystemRouter* thisObject = jsCast<JSFileSystemRouter*>(cell); + ASSERT_GC_OBJECT_INHERITS(thisObject, info()); + thisObject->visitAdditionalChildren<Visitor>(visitor); +} + +DEFINE_VISIT_OUTPUT_CONSTRAINTS(JSFileSystemRouter); +class JSMatchedRoutePrototype final : public JSC::JSNonFinalObject { +public: + using Base = JSC::JSNonFinalObject; + + static JSMatchedRoutePrototype* create(JSC::VM& vm, JSGlobalObject* globalObject, JSC::Structure* structure) + { + JSMatchedRoutePrototype* ptr = new (NotNull, JSC::allocateCell<JSMatchedRoutePrototype>(vm)) JSMatchedRoutePrototype(vm, globalObject, structure); + ptr->finishCreation(vm, globalObject); + return ptr; + } + + DECLARE_INFO; + template<typename CellType, JSC::SubspaceAccess> + static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + return &vm.plainObjectSpace(); + } + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info()); + } + +private: + JSMatchedRoutePrototype(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure) + : Base(vm, structure) + { + } + + void finishCreation(JSC::VM&, JSC::JSGlobalObject*); +}; + +extern "C" void* MatchedRouteClass__construct(JSC::JSGlobalObject*, JSC::CallFrame*); +JSC_DECLARE_CUSTOM_GETTER(jsMatchedRouteConstructor); +extern "C" void MatchedRouteClass__finalize(void*); + +extern "C" JSC::EncodedJSValue MatchedRoutePrototype__getFilePath(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject); +JSC_DECLARE_CUSTOM_GETTER(MatchedRoutePrototype__filePathGetterWrap); + +extern "C" JSC::EncodedJSValue MatchedRoutePrototype__getKind(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject); +JSC_DECLARE_CUSTOM_GETTER(MatchedRoutePrototype__kindGetterWrap); + +extern "C" JSC::EncodedJSValue MatchedRoutePrototype__getName(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject); +JSC_DECLARE_CUSTOM_GETTER(MatchedRoutePrototype__nameGetterWrap); + +extern "C" JSC::EncodedJSValue MatchedRoutePrototype__getParams(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject); +JSC_DECLARE_CUSTOM_GETTER(MatchedRoutePrototype__paramsGetterWrap); + +extern "C" JSC::EncodedJSValue MatchedRoutePrototype__getPathname(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject); +JSC_DECLARE_CUSTOM_GETTER(MatchedRoutePrototype__pathnameGetterWrap); + +extern "C" JSC::EncodedJSValue MatchedRoutePrototype__getQuery(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject); +JSC_DECLARE_CUSTOM_GETTER(MatchedRoutePrototype__queryGetterWrap); + +STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSMatchedRoutePrototype, JSMatchedRoutePrototype::Base); + +static const HashTableValue JSMatchedRoutePrototypeTableValues[] = { + { "filePath"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { HashTableValue::GetterSetterType, MatchedRoutePrototype__filePathGetterWrap, 0 } }, + { "kind"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { HashTableValue::GetterSetterType, MatchedRoutePrototype__kindGetterWrap, 0 } }, + { "name"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { HashTableValue::GetterSetterType, MatchedRoutePrototype__nameGetterWrap, 0 } }, + { "params"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { HashTableValue::GetterSetterType, MatchedRoutePrototype__paramsGetterWrap, 0 } }, + { "pathname"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { HashTableValue::GetterSetterType, MatchedRoutePrototype__pathnameGetterWrap, 0 } }, + { "query"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { HashTableValue::GetterSetterType, MatchedRoutePrototype__queryGetterWrap, 0 } } +}; + +const ClassInfo JSMatchedRoutePrototype::s_info = { "MatchedRoute"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSMatchedRoutePrototype) }; + +JSC_DEFINE_CUSTOM_GETTER(jsMatchedRouteConstructor, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName)) +{ + VM& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto* globalObject = reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject); + auto* prototype = jsDynamicCast<JSMatchedRoutePrototype*>(JSValue::decode(thisValue)); + + if (UNLIKELY(!prototype)) + return throwVMTypeError(lexicalGlobalObject, throwScope); + return JSValue::encode(globalObject->JSMatchedRouteConstructor()); +} + +JSC_DEFINE_CUSTOM_GETTER(MatchedRoutePrototype__filePathGetterWrap, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + auto& vm = lexicalGlobalObject->vm(); + Zig::GlobalObject* globalObject = reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + JSMatchedRoute* thisObject = jsCast<JSMatchedRoute*>(JSValue::decode(thisValue)); + JSC::EnsureStillAliveScope thisArg = JSC::EnsureStillAliveScope(thisObject); + + if (JSValue cachedValue = thisObject->m_filePath.get()) + return JSValue::encode(cachedValue); + + JSC::JSValue result = JSC::JSValue::decode( + MatchedRoutePrototype__getFilePath(thisObject->wrapped(), globalObject)); + RETURN_IF_EXCEPTION(throwScope, {}); + thisObject->m_filePath.set(vm, thisObject, result); + RELEASE_AND_RETURN(throwScope, JSValue::encode(result)); +} + +extern "C" void MatchedRoutePrototype__filePathSetCachedValue(JSC::EncodedJSValue thisValue, JSC::JSGlobalObject* globalObject, JSC::EncodedJSValue value) +{ + auto& vm = globalObject->vm(); + auto* thisObject = jsCast<JSMatchedRoute*>(JSValue::decode(thisValue)); + thisObject->m_filePath.set(vm, thisObject, JSValue::decode(value)); +} + +extern "C" EncodedJSValue MatchedRoutePrototype__filePathGetCachedValue(JSC::EncodedJSValue thisValue) +{ + auto* thisObject = jsCast<JSMatchedRoute*>(JSValue::decode(thisValue)); + return JSValue::encode(thisObject->m_filePath.get()); +} + +JSC_DEFINE_CUSTOM_GETTER(MatchedRoutePrototype__kindGetterWrap, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + auto& vm = lexicalGlobalObject->vm(); + Zig::GlobalObject* globalObject = reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + JSMatchedRoute* thisObject = jsCast<JSMatchedRoute*>(JSValue::decode(thisValue)); + JSC::EnsureStillAliveScope thisArg = JSC::EnsureStillAliveScope(thisObject); + + if (JSValue cachedValue = thisObject->m_kind.get()) + return JSValue::encode(cachedValue); + + JSC::JSValue result = JSC::JSValue::decode( + MatchedRoutePrototype__getKind(thisObject->wrapped(), globalObject)); + RETURN_IF_EXCEPTION(throwScope, {}); + thisObject->m_kind.set(vm, thisObject, result); + RELEASE_AND_RETURN(throwScope, JSValue::encode(result)); +} + +extern "C" void MatchedRoutePrototype__kindSetCachedValue(JSC::EncodedJSValue thisValue, JSC::JSGlobalObject* globalObject, JSC::EncodedJSValue value) +{ + auto& vm = globalObject->vm(); + auto* thisObject = jsCast<JSMatchedRoute*>(JSValue::decode(thisValue)); + thisObject->m_kind.set(vm, thisObject, JSValue::decode(value)); +} + +extern "C" EncodedJSValue MatchedRoutePrototype__kindGetCachedValue(JSC::EncodedJSValue thisValue) +{ + auto* thisObject = jsCast<JSMatchedRoute*>(JSValue::decode(thisValue)); + return JSValue::encode(thisObject->m_kind.get()); +} + +JSC_DEFINE_CUSTOM_GETTER(MatchedRoutePrototype__nameGetterWrap, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + auto& vm = lexicalGlobalObject->vm(); + Zig::GlobalObject* globalObject = reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + JSMatchedRoute* thisObject = jsCast<JSMatchedRoute*>(JSValue::decode(thisValue)); + JSC::EnsureStillAliveScope thisArg = JSC::EnsureStillAliveScope(thisObject); + + if (JSValue cachedValue = thisObject->m_name.get()) + return JSValue::encode(cachedValue); + + JSC::JSValue result = JSC::JSValue::decode( + MatchedRoutePrototype__getName(thisObject->wrapped(), globalObject)); + RETURN_IF_EXCEPTION(throwScope, {}); + thisObject->m_name.set(vm, thisObject, result); + RELEASE_AND_RETURN(throwScope, JSValue::encode(result)); +} + +extern "C" void MatchedRoutePrototype__nameSetCachedValue(JSC::EncodedJSValue thisValue, JSC::JSGlobalObject* globalObject, JSC::EncodedJSValue value) +{ + auto& vm = globalObject->vm(); + auto* thisObject = jsCast<JSMatchedRoute*>(JSValue::decode(thisValue)); + thisObject->m_name.set(vm, thisObject, JSValue::decode(value)); +} + +extern "C" EncodedJSValue MatchedRoutePrototype__nameGetCachedValue(JSC::EncodedJSValue thisValue) +{ + auto* thisObject = jsCast<JSMatchedRoute*>(JSValue::decode(thisValue)); + return JSValue::encode(thisObject->m_name.get()); +} + +JSC_DEFINE_CUSTOM_GETTER(MatchedRoutePrototype__paramsGetterWrap, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + auto& vm = lexicalGlobalObject->vm(); + Zig::GlobalObject* globalObject = reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + JSMatchedRoute* thisObject = jsCast<JSMatchedRoute*>(JSValue::decode(thisValue)); + JSC::EnsureStillAliveScope thisArg = JSC::EnsureStillAliveScope(thisObject); + + if (JSValue cachedValue = thisObject->m_params.get()) + return JSValue::encode(cachedValue); + + JSC::JSValue result = JSC::JSValue::decode( + MatchedRoutePrototype__getParams(thisObject->wrapped(), globalObject)); + RETURN_IF_EXCEPTION(throwScope, {}); + thisObject->m_params.set(vm, thisObject, result); + RELEASE_AND_RETURN(throwScope, JSValue::encode(result)); +} + +extern "C" void MatchedRoutePrototype__paramsSetCachedValue(JSC::EncodedJSValue thisValue, JSC::JSGlobalObject* globalObject, JSC::EncodedJSValue value) +{ + auto& vm = globalObject->vm(); + auto* thisObject = jsCast<JSMatchedRoute*>(JSValue::decode(thisValue)); + thisObject->m_params.set(vm, thisObject, JSValue::decode(value)); +} + +extern "C" EncodedJSValue MatchedRoutePrototype__paramsGetCachedValue(JSC::EncodedJSValue thisValue) +{ + auto* thisObject = jsCast<JSMatchedRoute*>(JSValue::decode(thisValue)); + return JSValue::encode(thisObject->m_params.get()); +} + +JSC_DEFINE_CUSTOM_GETTER(MatchedRoutePrototype__pathnameGetterWrap, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + auto& vm = lexicalGlobalObject->vm(); + Zig::GlobalObject* globalObject = reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + JSMatchedRoute* thisObject = jsCast<JSMatchedRoute*>(JSValue::decode(thisValue)); + JSC::EnsureStillAliveScope thisArg = JSC::EnsureStillAliveScope(thisObject); + + if (JSValue cachedValue = thisObject->m_pathname.get()) + return JSValue::encode(cachedValue); + + JSC::JSValue result = JSC::JSValue::decode( + MatchedRoutePrototype__getPathname(thisObject->wrapped(), globalObject)); + RETURN_IF_EXCEPTION(throwScope, {}); + thisObject->m_pathname.set(vm, thisObject, result); + RELEASE_AND_RETURN(throwScope, JSValue::encode(result)); +} + +extern "C" void MatchedRoutePrototype__pathnameSetCachedValue(JSC::EncodedJSValue thisValue, JSC::JSGlobalObject* globalObject, JSC::EncodedJSValue value) +{ + auto& vm = globalObject->vm(); + auto* thisObject = jsCast<JSMatchedRoute*>(JSValue::decode(thisValue)); + thisObject->m_pathname.set(vm, thisObject, JSValue::decode(value)); +} + +extern "C" EncodedJSValue MatchedRoutePrototype__pathnameGetCachedValue(JSC::EncodedJSValue thisValue) +{ + auto* thisObject = jsCast<JSMatchedRoute*>(JSValue::decode(thisValue)); + return JSValue::encode(thisObject->m_pathname.get()); +} + +JSC_DEFINE_CUSTOM_GETTER(MatchedRoutePrototype__queryGetterWrap, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + auto& vm = lexicalGlobalObject->vm(); + Zig::GlobalObject* globalObject = reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + JSMatchedRoute* thisObject = jsCast<JSMatchedRoute*>(JSValue::decode(thisValue)); + JSC::EnsureStillAliveScope thisArg = JSC::EnsureStillAliveScope(thisObject); + + if (JSValue cachedValue = thisObject->m_query.get()) + return JSValue::encode(cachedValue); + + JSC::JSValue result = JSC::JSValue::decode( + MatchedRoutePrototype__getQuery(thisObject->wrapped(), globalObject)); + RETURN_IF_EXCEPTION(throwScope, {}); + thisObject->m_query.set(vm, thisObject, result); + RELEASE_AND_RETURN(throwScope, JSValue::encode(result)); +} + +extern "C" void MatchedRoutePrototype__querySetCachedValue(JSC::EncodedJSValue thisValue, JSC::JSGlobalObject* globalObject, JSC::EncodedJSValue value) +{ + auto& vm = globalObject->vm(); + auto* thisObject = jsCast<JSMatchedRoute*>(JSValue::decode(thisValue)); + thisObject->m_query.set(vm, thisObject, JSValue::decode(value)); +} + +extern "C" EncodedJSValue MatchedRoutePrototype__queryGetCachedValue(JSC::EncodedJSValue thisValue) +{ + auto* thisObject = jsCast<JSMatchedRoute*>(JSValue::decode(thisValue)); + return JSValue::encode(thisObject->m_query.get()); +} + +void JSMatchedRoutePrototype::finishCreation(JSC::VM& vm, JSC::JSGlobalObject* globalObject) +{ + Base::finishCreation(vm); + reifyStaticProperties(vm, JSMatchedRoute::info(), JSMatchedRoutePrototypeTableValues, *this); + JSC_TO_STRING_TAG_WITHOUT_TRANSITION(); +} + +JSMatchedRoute::~JSMatchedRoute() +{ + if (m_ctx) { + MatchedRouteClass__finalize(m_ctx); + } +} +void JSMatchedRoute::destroy(JSCell* cell) +{ + static_cast<JSMatchedRoute*>(cell)->JSMatchedRoute::~JSMatchedRoute(); +} + +const ClassInfo JSMatchedRoute::s_info = { "MatchedRoute"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSMatchedRoute) }; + +void JSMatchedRoute::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + ASSERT(inherits(info())); +} + +JSMatchedRoute* JSMatchedRoute::create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure, void* ctx) +{ + JSMatchedRoute* ptr = new (NotNull, JSC::allocateCell<JSMatchedRoute>(vm)) JSMatchedRoute(vm, structure, ctx); + ptr->finishCreation(vm); + return ptr; +} + +extern "C" void* MatchedRoute__fromJS(JSC::EncodedJSValue value) +{ + JSC::JSValue decodedValue = JSC::JSValue::decode(value); + if (!decodedValue || decodedValue.isUndefinedOrNull()) + return nullptr; + + JSMatchedRoute* object = JSC::jsDynamicCast<JSMatchedRoute*>(decodedValue); + + if (!object) + return nullptr; + + return object->wrapped(); +} + +extern "C" bool MatchedRoute__dangerouslySetPtr(JSC::EncodedJSValue value, void* ptr) +{ + JSMatchedRoute* object = JSC::jsDynamicCast<JSMatchedRoute*>(JSValue::decode(value)); + if (!object) + return false; + + object->m_ctx = ptr; + return true; +} + +extern "C" const size_t MatchedRoute__ptrOffset = JSMatchedRoute::offsetOfWrapped(); + +void JSMatchedRoute::analyzeHeap(JSCell* cell, HeapAnalyzer& analyzer) +{ + auto* thisObject = jsCast<JSMatchedRoute*>(cell); + if (void* wrapped = thisObject->wrapped()) { + // if (thisObject->scriptExecutionContext()) + // analyzer.setLabelForCell(cell, "url " + thisObject->scriptExecutionContext()->url().string()); + } + Base::analyzeHeap(cell, analyzer); +} + +JSObject* JSMatchedRoute::createPrototype(VM& vm, JSDOMGlobalObject* globalObject) +{ + return JSMatchedRoutePrototype::create(vm, globalObject, JSMatchedRoutePrototype::createStructure(vm, globalObject, globalObject->objectPrototype())); +} + +extern "C" EncodedJSValue MatchedRoute__create(Zig::GlobalObject* globalObject, void* ptr) +{ + auto& vm = globalObject->vm(); + JSC::Structure* structure = globalObject->JSMatchedRouteStructure(); + JSMatchedRoute* instance = JSMatchedRoute::create(vm, globalObject, structure, ptr); + + return JSValue::encode(instance); +} + +template<typename Visitor> +void JSMatchedRoute::visitChildrenImpl(JSCell* cell, Visitor& visitor) +{ + JSMatchedRoute* thisObject = jsCast<JSMatchedRoute*>(cell); + ASSERT_GC_OBJECT_INHERITS(thisObject, info()); + Base::visitChildren(thisObject, visitor); + + visitor.append(thisObject->m_filePath); + visitor.append(thisObject->m_kind); + visitor.append(thisObject->m_name); + visitor.append(thisObject->m_params); + visitor.append(thisObject->m_pathname); + visitor.append(thisObject->m_query); +} + +DEFINE_VISIT_CHILDREN(JSMatchedRoute); + +template<typename Visitor> +void JSMatchedRoute::visitAdditionalChildren(Visitor& visitor) +{ + JSMatchedRoute* thisObject = this; + ASSERT_GC_OBJECT_INHERITS(thisObject, info()); + + visitor.append(thisObject->m_filePath); + visitor.append(thisObject->m_kind); + visitor.append(thisObject->m_name); + visitor.append(thisObject->m_params); + visitor.append(thisObject->m_pathname); + visitor.append(thisObject->m_query); + ; +} + +DEFINE_VISIT_ADDITIONAL_CHILDREN(JSMatchedRoute); + +template<typename Visitor> +void JSMatchedRoute::visitOutputConstraintsImpl(JSCell* cell, Visitor& visitor) +{ + JSMatchedRoute* thisObject = jsCast<JSMatchedRoute*>(cell); + ASSERT_GC_OBJECT_INHERITS(thisObject, info()); + thisObject->visitAdditionalChildren<Visitor>(visitor); +} + +DEFINE_VISIT_OUTPUT_CONSTRAINTS(JSMatchedRoute); class JSExpectPrototype final : public JSC::JSNonFinalObject { public: using Base = JSC::JSNonFinalObject; @@ -6317,15 +7130,6 @@ JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSExpectConstructor::construct(JSC: return JSValue::encode(instance); } -extern "C" EncodedJSValue Expect__create(Zig::GlobalObject* globalObject, void* ptr) -{ - auto& vm = globalObject->vm(); - JSC::Structure* structure = globalObject->JSExpectStructure(); - JSExpect* instance = JSExpect::create(vm, globalObject, structure, ptr); - - return JSValue::encode(instance); -} - void JSExpectConstructor::initializeProperties(VM& vm, JSC::JSGlobalObject* globalObject, JSExpectPrototype* prototype) { } @@ -6409,6 +7213,15 @@ JSObject* JSExpect::createPrototype(VM& vm, JSDOMGlobalObject* globalObject) return JSExpectPrototype::create(vm, globalObject, JSExpectPrototype::createStructure(vm, globalObject, globalObject->objectPrototype())); } +extern "C" EncodedJSValue Expect__create(Zig::GlobalObject* globalObject, void* ptr) +{ + auto& vm = globalObject->vm(); + JSC::Structure* structure = globalObject->JSExpectStructure(); + JSExpect* instance = JSExpect::create(vm, globalObject, structure, ptr); + + return JSValue::encode(instance); +} + template<typename Visitor> void JSExpect::visitChildrenImpl(JSCell* cell, Visitor& visitor) { @@ -6681,15 +7494,6 @@ JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSTextDecoderConstructor::construct return JSValue::encode(instance); } -extern "C" EncodedJSValue TextDecoder__create(Zig::GlobalObject* globalObject, void* ptr) -{ - auto& vm = globalObject->vm(); - JSC::Structure* structure = globalObject->JSTextDecoderStructure(); - JSTextDecoder* instance = JSTextDecoder::create(vm, globalObject, structure, ptr); - - return JSValue::encode(instance); -} - void JSTextDecoderConstructor::initializeProperties(VM& vm, JSC::JSGlobalObject* globalObject, JSTextDecoderPrototype* prototype) { } @@ -6773,6 +7577,15 @@ JSObject* JSTextDecoder::createPrototype(VM& vm, JSDOMGlobalObject* globalObject return JSTextDecoderPrototype::create(vm, globalObject, JSTextDecoderPrototype::createStructure(vm, globalObject, globalObject->objectPrototype())); } +extern "C" EncodedJSValue TextDecoder__create(Zig::GlobalObject* globalObject, void* ptr) +{ + auto& vm = globalObject->vm(); + JSC::Structure* structure = globalObject->JSTextDecoderStructure(); + JSTextDecoder* instance = JSTextDecoder::create(vm, globalObject, structure, ptr); + + return JSValue::encode(instance); +} + template<typename Visitor> void JSTextDecoder::visitChildrenImpl(JSCell* cell, Visitor& visitor) { @@ -7323,15 +8136,6 @@ JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSRequestConstructor::construct(JSC return JSValue::encode(instance); } -extern "C" EncodedJSValue Request__create(Zig::GlobalObject* globalObject, void* ptr) -{ - auto& vm = globalObject->vm(); - JSC::Structure* structure = globalObject->JSRequestStructure(); - JSRequest* instance = JSRequest::create(vm, globalObject, structure, ptr); - vm.heap.reportExtraMemoryAllocated(Request__estimatedSize(ptr)); - return JSValue::encode(instance); -} - void JSRequestConstructor::initializeProperties(VM& vm, JSC::JSGlobalObject* globalObject, JSRequestPrototype* prototype) { } @@ -7415,6 +8219,15 @@ JSObject* JSRequest::createPrototype(VM& vm, JSDOMGlobalObject* globalObject) return JSRequestPrototype::create(vm, globalObject, JSRequestPrototype::createStructure(vm, globalObject, globalObject->objectPrototype())); } +extern "C" EncodedJSValue Request__create(Zig::GlobalObject* globalObject, void* ptr) +{ + auto& vm = globalObject->vm(); + JSC::Structure* structure = globalObject->JSRequestStructure(); + JSRequest* instance = JSRequest::create(vm, globalObject, structure, ptr); + vm.heap.reportExtraMemoryAllocated(Request__estimatedSize(ptr)); + return JSValue::encode(instance); +} + template<typename Visitor> void JSRequest::visitChildrenImpl(JSCell* cell, Visitor& visitor) { @@ -7936,15 +8749,6 @@ JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSResponseConstructor::construct(JS return JSValue::encode(instance); } -extern "C" EncodedJSValue Response__create(Zig::GlobalObject* globalObject, void* ptr) -{ - auto& vm = globalObject->vm(); - JSC::Structure* structure = globalObject->JSResponseStructure(); - JSResponse* instance = JSResponse::create(vm, globalObject, structure, ptr); - vm.heap.reportExtraMemoryAllocated(Response__estimatedSize(ptr)); - return JSValue::encode(instance); -} - void JSResponseConstructor::initializeProperties(VM& vm, JSC::JSGlobalObject* globalObject, JSResponsePrototype* prototype) { } @@ -8028,6 +8832,15 @@ JSObject* JSResponse::createPrototype(VM& vm, JSDOMGlobalObject* globalObject) return JSResponsePrototype::create(vm, globalObject, JSResponsePrototype::createStructure(vm, globalObject, globalObject->objectPrototype())); } +extern "C" EncodedJSValue Response__create(Zig::GlobalObject* globalObject, void* ptr) +{ + auto& vm = globalObject->vm(); + JSC::Structure* structure = globalObject->JSResponseStructure(); + JSResponse* instance = JSResponse::create(vm, globalObject, structure, ptr); + vm.heap.reportExtraMemoryAllocated(Response__estimatedSize(ptr)); + return JSValue::encode(instance); +} + template<typename Visitor> void JSResponse::visitChildrenImpl(JSCell* cell, Visitor& visitor) { @@ -8385,15 +9198,6 @@ JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSBlobConstructor::construct(JSC::J return JSValue::encode(instance); } -extern "C" EncodedJSValue Blob__create(Zig::GlobalObject* globalObject, void* ptr) -{ - auto& vm = globalObject->vm(); - JSC::Structure* structure = globalObject->JSBlobStructure(); - JSBlob* instance = JSBlob::create(vm, globalObject, structure, ptr); - - return JSValue::encode(instance); -} - void JSBlobConstructor::initializeProperties(VM& vm, JSC::JSGlobalObject* globalObject, JSBlobPrototype* prototype) { } @@ -8477,4 +9281,13 @@ JSObject* JSBlob::createPrototype(VM& vm, JSDOMGlobalObject* globalObject) return JSBlobPrototype::create(vm, globalObject, JSBlobPrototype::createStructure(vm, globalObject, globalObject->objectPrototype())); } +extern "C" EncodedJSValue Blob__create(Zig::GlobalObject* globalObject, void* ptr) +{ + auto& vm = globalObject->vm(); + JSC::Structure* structure = globalObject->JSBlobStructure(); + JSBlob* instance = JSBlob::create(vm, globalObject, structure, ptr); + + return JSValue::encode(instance); +} + } // namespace WebCore diff --git a/src/bun.js/bindings/ZigGeneratedClasses.h b/src/bun.js/bindings/ZigGeneratedClasses.h index 27665927f..32b7a8c5e 100644 --- a/src/bun.js/bindings/ZigGeneratedClasses.h +++ b/src/bun.js/bindings/ZigGeneratedClasses.h @@ -782,6 +782,125 @@ public: mutable JSC::WriteBarrier<JSC::Unknown> m_remoteAddress; }; +class JSFileSystemRouter final : public JSC::JSDestructibleObject { +public: + using Base = JSC::JSDestructibleObject; + static JSFileSystemRouter* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure, void* ctx); + + DECLARE_EXPORT_INFO; + template<typename, JSC::SubspaceAccess mode> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + if constexpr (mode == JSC::SubspaceAccess::Concurrently) + return nullptr; + return WebCore::subspaceForImpl<JSFileSystemRouter, WebCore::UseCustomHeapCellType::No>( + vm, + [](auto& spaces) { return spaces.m_clientSubspaceForFileSystemRouter.get(); }, + [](auto& spaces, auto&& space) { spaces.m_clientSubspaceForFileSystemRouter = WTFMove(space); }, + [](auto& spaces) { return spaces.m_subspaceForFileSystemRouter.get(); }, + [](auto& spaces, auto&& space) { spaces.m_subspaceForFileSystemRouter = WTFMove(space); }); + } + + static void destroy(JSC::JSCell*); + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(static_cast<JSC::JSType>(0b11101110), StructureFlags), info()); + } + + static JSObject* createPrototype(VM& vm, JSDOMGlobalObject* globalObject); + static JSObject* createConstructor(VM& vm, JSGlobalObject* globalObject, JSValue prototype); + + ~JSFileSystemRouter(); + + void* wrapped() const { return m_ctx; } + + void detach() + { + m_ctx = nullptr; + } + + static void analyzeHeap(JSCell*, JSC::HeapAnalyzer&); + static ptrdiff_t offsetOfWrapped() { return OBJECT_OFFSETOF(JSFileSystemRouter, m_ctx); } + + void* m_ctx { nullptr }; + + JSFileSystemRouter(JSC::VM& vm, JSC::Structure* structure, void* sinkPtr) + : Base(vm, structure) + { + m_ctx = sinkPtr; + } + + void finishCreation(JSC::VM&); + + DECLARE_VISIT_CHILDREN; + template<typename Visitor> void visitAdditionalChildren(Visitor&); + DECLARE_VISIT_OUTPUT_CONSTRAINTS; + + mutable JSC::WriteBarrier<JSC::Unknown> m_origin; + mutable JSC::WriteBarrier<JSC::Unknown> m_routes; + mutable JSC::WriteBarrier<JSC::Unknown> m_style; +}; + +class JSMatchedRoute final : public JSC::JSDestructibleObject { +public: + using Base = JSC::JSDestructibleObject; + static JSMatchedRoute* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure, void* ctx); + + DECLARE_EXPORT_INFO; + template<typename, JSC::SubspaceAccess mode> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + if constexpr (mode == JSC::SubspaceAccess::Concurrently) + return nullptr; + return WebCore::subspaceForImpl<JSMatchedRoute, WebCore::UseCustomHeapCellType::No>( + vm, + [](auto& spaces) { return spaces.m_clientSubspaceForMatchedRoute.get(); }, + [](auto& spaces, auto&& space) { spaces.m_clientSubspaceForMatchedRoute = WTFMove(space); }, + [](auto& spaces) { return spaces.m_subspaceForMatchedRoute.get(); }, + [](auto& spaces, auto&& space) { spaces.m_subspaceForMatchedRoute = WTFMove(space); }); + } + + static void destroy(JSC::JSCell*); + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(static_cast<JSC::JSType>(0b11101110), StructureFlags), info()); + } + + static JSObject* createPrototype(VM& vm, JSDOMGlobalObject* globalObject); + ; + + ~JSMatchedRoute(); + + void* wrapped() const { return m_ctx; } + + void detach() + { + m_ctx = nullptr; + } + + static void analyzeHeap(JSCell*, JSC::HeapAnalyzer&); + static ptrdiff_t offsetOfWrapped() { return OBJECT_OFFSETOF(JSMatchedRoute, m_ctx); } + + void* m_ctx { nullptr }; + + JSMatchedRoute(JSC::VM& vm, JSC::Structure* structure, void* sinkPtr) + : Base(vm, structure) + { + m_ctx = sinkPtr; + } + + void finishCreation(JSC::VM&); + + DECLARE_VISIT_CHILDREN; + template<typename Visitor> void visitAdditionalChildren(Visitor&); + DECLARE_VISIT_OUTPUT_CONSTRAINTS; + + mutable JSC::WriteBarrier<JSC::Unknown> m_filePath; + mutable JSC::WriteBarrier<JSC::Unknown> m_kind; + mutable JSC::WriteBarrier<JSC::Unknown> m_name; + mutable JSC::WriteBarrier<JSC::Unknown> m_params; + mutable JSC::WriteBarrier<JSC::Unknown> m_pathname; + mutable JSC::WriteBarrier<JSC::Unknown> m_query; +}; + class JSExpect final : public JSC::JSDestructibleObject { public: using Base = JSC::JSDestructibleObject; diff --git a/src/bun.js/bindings/bindings.zig b/src/bun.js/bindings/bindings.zig index 8327e7d70..c88e0ba8f 100644 --- a/src/bun.js/bindings/bindings.zig +++ b/src/bun.js/bindings/bindings.zig @@ -200,8 +200,8 @@ pub const ZigString = extern struct { pub const Slice = struct { allocator: NullableAllocator = .{}, - ptr: [*]const u8, - len: u32, + ptr: [*]const u8 = undefined, + len: u32 = 0, pub fn fromUTF8NeverFree(input: []const u8) Slice { return .{ @@ -235,6 +235,11 @@ pub const ZigString = extern struct { return Slice{ .allocator = NullableAllocator.init(allocator), .ptr = duped.ptr, .len = this.len }; } + pub fn cloneWithTrailingSlash(this: Slice, allocator: std.mem.Allocator) !Slice { + var duped = try std.fmt.allocPrintZ(allocator, "{s}/", .{strings.withoutTrailingSlash(this.slice())}); + return Slice{ .allocator = NullableAllocator.init(allocator), .ptr = duped.ptr, .len = @truncate(u32, duped.len) }; + } + pub fn cloneZ(this: Slice, allocator: std.mem.Allocator) !Slice { if (this.isAllocated() or this.len == 0) { return this; diff --git a/src/bun.js/bindings/generated_classes.zig b/src/bun.js/bindings/generated_classes.zig index 7ed127ee5..e3ea791d8 100644 --- a/src/bun.js/bindings/generated_classes.zig +++ b/src/bun.js/bindings/generated_classes.zig @@ -1510,6 +1510,370 @@ pub const JSServerWebSocket = struct { } } }; +pub const JSFileSystemRouter = struct { + const FileSystemRouter = Classes.FileSystemRouter; + const GetterType = fn (*FileSystemRouter, *JSC.JSGlobalObject) callconv(.C) JSC.JSValue; + const GetterTypeWithThisValue = fn (*FileSystemRouter, JSC.JSValue, *JSC.JSGlobalObject) callconv(.C) JSC.JSValue; + const SetterType = fn (*FileSystemRouter, *JSC.JSGlobalObject, JSC.JSValue) callconv(.C) bool; + const SetterTypeWithThisValue = fn (*FileSystemRouter, JSC.JSValue, *JSC.JSGlobalObject, JSC.JSValue) callconv(.C) bool; + const CallbackType = fn (*FileSystemRouter, *JSC.JSGlobalObject, *JSC.CallFrame) callconv(.C) JSC.JSValue; + + /// Return the pointer to the wrapped object. + /// If the object does not match the type, return null. + pub fn fromJS(value: JSC.JSValue) ?*FileSystemRouter { + JSC.markBinding(@src()); + return FileSystemRouter__fromJS(value); + } + + extern fn FileSystemRouterPrototype__originSetCachedValue(JSC.JSValue, *JSC.JSGlobalObject, JSC.JSValue) void; + + extern fn FileSystemRouterPrototype__originGetCachedValue(JSC.JSValue) JSC.JSValue; + + /// `FileSystemRouter.origin` setter + /// This value will be visited by the garbage collector. + pub fn originSetCached(thisValue: JSC.JSValue, globalObject: *JSC.JSGlobalObject, value: JSC.JSValue) void { + JSC.markBinding(@src()); + FileSystemRouterPrototype__originSetCachedValue(thisValue, globalObject, value); + } + + /// `FileSystemRouter.origin` getter + /// This value will be visited by the garbage collector. + pub fn originGetCached(thisValue: JSC.JSValue) ?JSC.JSValue { + JSC.markBinding(@src()); + const result = FileSystemRouterPrototype__originGetCachedValue(thisValue); + if (result == .zero) + return null; + + return result; + } + + extern fn FileSystemRouterPrototype__routesSetCachedValue(JSC.JSValue, *JSC.JSGlobalObject, JSC.JSValue) void; + + extern fn FileSystemRouterPrototype__routesGetCachedValue(JSC.JSValue) JSC.JSValue; + + /// `FileSystemRouter.routes` setter + /// This value will be visited by the garbage collector. + pub fn routesSetCached(thisValue: JSC.JSValue, globalObject: *JSC.JSGlobalObject, value: JSC.JSValue) void { + JSC.markBinding(@src()); + FileSystemRouterPrototype__routesSetCachedValue(thisValue, globalObject, value); + } + + /// `FileSystemRouter.routes` getter + /// This value will be visited by the garbage collector. + pub fn routesGetCached(thisValue: JSC.JSValue) ?JSC.JSValue { + JSC.markBinding(@src()); + const result = FileSystemRouterPrototype__routesGetCachedValue(thisValue); + if (result == .zero) + return null; + + return result; + } + + extern fn FileSystemRouterPrototype__styleSetCachedValue(JSC.JSValue, *JSC.JSGlobalObject, JSC.JSValue) void; + + extern fn FileSystemRouterPrototype__styleGetCachedValue(JSC.JSValue) JSC.JSValue; + + /// `FileSystemRouter.style` setter + /// This value will be visited by the garbage collector. + pub fn styleSetCached(thisValue: JSC.JSValue, globalObject: *JSC.JSGlobalObject, value: JSC.JSValue) void { + JSC.markBinding(@src()); + FileSystemRouterPrototype__styleSetCachedValue(thisValue, globalObject, value); + } + + /// `FileSystemRouter.style` getter + /// This value will be visited by the garbage collector. + pub fn styleGetCached(thisValue: JSC.JSValue) ?JSC.JSValue { + JSC.markBinding(@src()); + const result = FileSystemRouterPrototype__styleGetCachedValue(thisValue); + if (result == .zero) + return null; + + return result; + } + + /// Get the FileSystemRouter constructor value. + /// This loads lazily from the global object. + pub fn getConstructor(globalObject: *JSC.JSGlobalObject) JSC.JSValue { + JSC.markBinding(@src()); + return FileSystemRouter__getConstructor(globalObject); + } + + /// Create a new instance of FileSystemRouter + pub fn toJS(this: *FileSystemRouter, globalObject: *JSC.JSGlobalObject) JSC.JSValue { + JSC.markBinding(@src()); + if (comptime Environment.allow_assert) { + const value__ = FileSystemRouter__create(globalObject, this); + std.debug.assert(value__.as(FileSystemRouter).? == this); // If this fails, likely a C ABI issue. + return value__; + } else { + return FileSystemRouter__create(globalObject, this); + } + } + + /// Modify the internal ptr to point to a new instance of FileSystemRouter. + pub fn dangerouslySetPtr(value: JSC.JSValue, ptr: ?*FileSystemRouter) bool { + JSC.markBinding(@src()); + return FileSystemRouter__dangerouslySetPtr(value, ptr); + } + + /// Detach the ptr from the thisValue + pub fn detachPtr(_: *FileSystemRouter, value: JSC.JSValue) void { + JSC.markBinding(@src()); + std.debug.assert(FileSystemRouter__dangerouslySetPtr(value, null)); + } + + extern fn FileSystemRouter__fromJS(JSC.JSValue) ?*FileSystemRouter; + extern fn FileSystemRouter__getConstructor(*JSC.JSGlobalObject) JSC.JSValue; + + extern fn FileSystemRouter__create(globalObject: *JSC.JSGlobalObject, ptr: ?*FileSystemRouter) JSC.JSValue; + + extern fn FileSystemRouter__dangerouslySetPtr(JSC.JSValue, ?*FileSystemRouter) bool; + + comptime { + if (@TypeOf(FileSystemRouter.constructor) != (fn (*JSC.JSGlobalObject, *JSC.CallFrame) callconv(.C) ?*FileSystemRouter)) { + @compileLog("FileSystemRouter.constructor is not a constructor"); + } + + if (@TypeOf(FileSystemRouter.finalize) != (fn (*FileSystemRouter) callconv(.C) void)) { + @compileLog("FileSystemRouter.finalize is not a finalizer"); + } + + if (@TypeOf(FileSystemRouter.match) != CallbackType) + @compileLog("Expected FileSystemRouter.match to be a callback"); + if (@TypeOf(FileSystemRouter.getOrigin) != GetterType) + @compileLog("Expected FileSystemRouter.getOrigin to be a getter"); + + if (@TypeOf(FileSystemRouter.reload) != CallbackType) + @compileLog("Expected FileSystemRouter.reload to be a callback"); + if (@TypeOf(FileSystemRouter.getRoutes) != GetterType) + @compileLog("Expected FileSystemRouter.getRoutes to be a getter"); + + if (@TypeOf(FileSystemRouter.getStyle) != GetterType) + @compileLog("Expected FileSystemRouter.getStyle to be a getter"); + + if (!JSC.is_bindgen) { + @export(FileSystemRouter.constructor, .{ .name = "FileSystemRouterClass__construct" }); + @export(FileSystemRouter.finalize, .{ .name = "FileSystemRouterClass__finalize" }); + @export(FileSystemRouter.getOrigin, .{ .name = "FileSystemRouterPrototype__getOrigin" }); + @export(FileSystemRouter.getRoutes, .{ .name = "FileSystemRouterPrototype__getRoutes" }); + @export(FileSystemRouter.getStyle, .{ .name = "FileSystemRouterPrototype__getStyle" }); + @export(FileSystemRouter.match, .{ .name = "FileSystemRouterPrototype__match" }); + @export(FileSystemRouter.reload, .{ .name = "FileSystemRouterPrototype__reload" }); + } + } +}; +pub const JSMatchedRoute = struct { + const MatchedRoute = Classes.MatchedRoute; + const GetterType = fn (*MatchedRoute, *JSC.JSGlobalObject) callconv(.C) JSC.JSValue; + const GetterTypeWithThisValue = fn (*MatchedRoute, JSC.JSValue, *JSC.JSGlobalObject) callconv(.C) JSC.JSValue; + const SetterType = fn (*MatchedRoute, *JSC.JSGlobalObject, JSC.JSValue) callconv(.C) bool; + const SetterTypeWithThisValue = fn (*MatchedRoute, JSC.JSValue, *JSC.JSGlobalObject, JSC.JSValue) callconv(.C) bool; + const CallbackType = fn (*MatchedRoute, *JSC.JSGlobalObject, *JSC.CallFrame) callconv(.C) JSC.JSValue; + + /// Return the pointer to the wrapped object. + /// If the object does not match the type, return null. + pub fn fromJS(value: JSC.JSValue) ?*MatchedRoute { + JSC.markBinding(@src()); + return MatchedRoute__fromJS(value); + } + + extern fn MatchedRoutePrototype__filePathSetCachedValue(JSC.JSValue, *JSC.JSGlobalObject, JSC.JSValue) void; + + extern fn MatchedRoutePrototype__filePathGetCachedValue(JSC.JSValue) JSC.JSValue; + + /// `MatchedRoute.filePath` setter + /// This value will be visited by the garbage collector. + pub fn filePathSetCached(thisValue: JSC.JSValue, globalObject: *JSC.JSGlobalObject, value: JSC.JSValue) void { + JSC.markBinding(@src()); + MatchedRoutePrototype__filePathSetCachedValue(thisValue, globalObject, value); + } + + /// `MatchedRoute.filePath` getter + /// This value will be visited by the garbage collector. + pub fn filePathGetCached(thisValue: JSC.JSValue) ?JSC.JSValue { + JSC.markBinding(@src()); + const result = MatchedRoutePrototype__filePathGetCachedValue(thisValue); + if (result == .zero) + return null; + + return result; + } + + extern fn MatchedRoutePrototype__kindSetCachedValue(JSC.JSValue, *JSC.JSGlobalObject, JSC.JSValue) void; + + extern fn MatchedRoutePrototype__kindGetCachedValue(JSC.JSValue) JSC.JSValue; + + /// `MatchedRoute.kind` setter + /// This value will be visited by the garbage collector. + pub fn kindSetCached(thisValue: JSC.JSValue, globalObject: *JSC.JSGlobalObject, value: JSC.JSValue) void { + JSC.markBinding(@src()); + MatchedRoutePrototype__kindSetCachedValue(thisValue, globalObject, value); + } + + /// `MatchedRoute.kind` getter + /// This value will be visited by the garbage collector. + pub fn kindGetCached(thisValue: JSC.JSValue) ?JSC.JSValue { + JSC.markBinding(@src()); + const result = MatchedRoutePrototype__kindGetCachedValue(thisValue); + if (result == .zero) + return null; + + return result; + } + + extern fn MatchedRoutePrototype__nameSetCachedValue(JSC.JSValue, *JSC.JSGlobalObject, JSC.JSValue) void; + + extern fn MatchedRoutePrototype__nameGetCachedValue(JSC.JSValue) JSC.JSValue; + + /// `MatchedRoute.name` setter + /// This value will be visited by the garbage collector. + pub fn nameSetCached(thisValue: JSC.JSValue, globalObject: *JSC.JSGlobalObject, value: JSC.JSValue) void { + JSC.markBinding(@src()); + MatchedRoutePrototype__nameSetCachedValue(thisValue, globalObject, value); + } + + /// `MatchedRoute.name` getter + /// This value will be visited by the garbage collector. + pub fn nameGetCached(thisValue: JSC.JSValue) ?JSC.JSValue { + JSC.markBinding(@src()); + const result = MatchedRoutePrototype__nameGetCachedValue(thisValue); + if (result == .zero) + return null; + + return result; + } + + extern fn MatchedRoutePrototype__paramsSetCachedValue(JSC.JSValue, *JSC.JSGlobalObject, JSC.JSValue) void; + + extern fn MatchedRoutePrototype__paramsGetCachedValue(JSC.JSValue) JSC.JSValue; + + /// `MatchedRoute.params` setter + /// This value will be visited by the garbage collector. + pub fn paramsSetCached(thisValue: JSC.JSValue, globalObject: *JSC.JSGlobalObject, value: JSC.JSValue) void { + JSC.markBinding(@src()); + MatchedRoutePrototype__paramsSetCachedValue(thisValue, globalObject, value); + } + + /// `MatchedRoute.params` getter + /// This value will be visited by the garbage collector. + pub fn paramsGetCached(thisValue: JSC.JSValue) ?JSC.JSValue { + JSC.markBinding(@src()); + const result = MatchedRoutePrototype__paramsGetCachedValue(thisValue); + if (result == .zero) + return null; + + return result; + } + + extern fn MatchedRoutePrototype__pathnameSetCachedValue(JSC.JSValue, *JSC.JSGlobalObject, JSC.JSValue) void; + + extern fn MatchedRoutePrototype__pathnameGetCachedValue(JSC.JSValue) JSC.JSValue; + + /// `MatchedRoute.pathname` setter + /// This value will be visited by the garbage collector. + pub fn pathnameSetCached(thisValue: JSC.JSValue, globalObject: *JSC.JSGlobalObject, value: JSC.JSValue) void { + JSC.markBinding(@src()); + MatchedRoutePrototype__pathnameSetCachedValue(thisValue, globalObject, value); + } + + /// `MatchedRoute.pathname` getter + /// This value will be visited by the garbage collector. + pub fn pathnameGetCached(thisValue: JSC.JSValue) ?JSC.JSValue { + JSC.markBinding(@src()); + const result = MatchedRoutePrototype__pathnameGetCachedValue(thisValue); + if (result == .zero) + return null; + + return result; + } + + extern fn MatchedRoutePrototype__querySetCachedValue(JSC.JSValue, *JSC.JSGlobalObject, JSC.JSValue) void; + + extern fn MatchedRoutePrototype__queryGetCachedValue(JSC.JSValue) JSC.JSValue; + + /// `MatchedRoute.query` setter + /// This value will be visited by the garbage collector. + pub fn querySetCached(thisValue: JSC.JSValue, globalObject: *JSC.JSGlobalObject, value: JSC.JSValue) void { + JSC.markBinding(@src()); + MatchedRoutePrototype__querySetCachedValue(thisValue, globalObject, value); + } + + /// `MatchedRoute.query` getter + /// This value will be visited by the garbage collector. + pub fn queryGetCached(thisValue: JSC.JSValue) ?JSC.JSValue { + JSC.markBinding(@src()); + const result = MatchedRoutePrototype__queryGetCachedValue(thisValue); + if (result == .zero) + return null; + + return result; + } + + /// Create a new instance of MatchedRoute + pub fn toJS(this: *MatchedRoute, globalObject: *JSC.JSGlobalObject) JSC.JSValue { + JSC.markBinding(@src()); + if (comptime Environment.allow_assert) { + const value__ = MatchedRoute__create(globalObject, this); + std.debug.assert(value__.as(MatchedRoute).? == this); // If this fails, likely a C ABI issue. + return value__; + } else { + return MatchedRoute__create(globalObject, this); + } + } + + /// Modify the internal ptr to point to a new instance of MatchedRoute. + pub fn dangerouslySetPtr(value: JSC.JSValue, ptr: ?*MatchedRoute) bool { + JSC.markBinding(@src()); + return MatchedRoute__dangerouslySetPtr(value, ptr); + } + + /// Detach the ptr from the thisValue + pub fn detachPtr(_: *MatchedRoute, value: JSC.JSValue) void { + JSC.markBinding(@src()); + std.debug.assert(MatchedRoute__dangerouslySetPtr(value, null)); + } + + extern fn MatchedRoute__fromJS(JSC.JSValue) ?*MatchedRoute; + extern fn MatchedRoute__getConstructor(*JSC.JSGlobalObject) JSC.JSValue; + + extern fn MatchedRoute__create(globalObject: *JSC.JSGlobalObject, ptr: ?*MatchedRoute) JSC.JSValue; + + extern fn MatchedRoute__dangerouslySetPtr(JSC.JSValue, ?*MatchedRoute) bool; + + comptime { + if (@TypeOf(MatchedRoute.finalize) != (fn (*MatchedRoute) callconv(.C) void)) { + @compileLog("MatchedRoute.finalize is not a finalizer"); + } + + if (@TypeOf(MatchedRoute.getFilePath) != GetterType) + @compileLog("Expected MatchedRoute.getFilePath to be a getter"); + + if (@TypeOf(MatchedRoute.getKind) != GetterType) + @compileLog("Expected MatchedRoute.getKind to be a getter"); + + if (@TypeOf(MatchedRoute.getName) != GetterType) + @compileLog("Expected MatchedRoute.getName to be a getter"); + + if (@TypeOf(MatchedRoute.getParams) != GetterType) + @compileLog("Expected MatchedRoute.getParams to be a getter"); + + if (@TypeOf(MatchedRoute.getPathname) != GetterType) + @compileLog("Expected MatchedRoute.getPathname to be a getter"); + + if (@TypeOf(MatchedRoute.getQuery) != GetterType) + @compileLog("Expected MatchedRoute.getQuery to be a getter"); + + if (!JSC.is_bindgen) { + @export(MatchedRoute.finalize, .{ .name = "MatchedRouteClass__finalize" }); + @export(MatchedRoute.getFilePath, .{ .name = "MatchedRoutePrototype__getFilePath" }); + @export(MatchedRoute.getKind, .{ .name = "MatchedRoutePrototype__getKind" }); + @export(MatchedRoute.getName, .{ .name = "MatchedRoutePrototype__getName" }); + @export(MatchedRoute.getParams, .{ .name = "MatchedRoutePrototype__getParams" }); + @export(MatchedRoute.getPathname, .{ .name = "MatchedRoutePrototype__getPathname" }); + @export(MatchedRoute.getQuery, .{ .name = "MatchedRoutePrototype__getQuery" }); + } + } +}; pub const JSExpect = struct { const Expect = Classes.Expect; const GetterType = fn (*Expect, *JSC.JSGlobalObject) callconv(.C) JSC.JSValue; @@ -2421,6 +2785,8 @@ comptime { _ = JSSHA256; _ = JSSHA512_256; _ = JSServerWebSocket; + _ = JSFileSystemRouter; + _ = JSMatchedRoute; _ = JSExpect; _ = JSTextDecoder; _ = JSRequest; diff --git a/src/bun.js/bindings/generated_classes_list.zig b/src/bun.js/bindings/generated_classes_list.zig index 25365940b..1dae06a3b 100644 --- a/src/bun.js/bindings/generated_classes_list.zig +++ b/src/bun.js/bindings/generated_classes_list.zig @@ -19,4 +19,6 @@ pub const Classes = struct { pub const TLSSocket = JSC.API.TLSSocket; pub const Listener = JSC.API.Listener; pub const Expect = JSC.Jest.Expect; + pub const FileSystemRouter = JSC.API.FileSystemRouter; + pub const MatchedRoute = JSC.API.MatchedRoute; }; diff --git a/src/bun.js/javascript.zig b/src/bun.js/javascript.zig index 4897ab562..7e4ae9ed5 100644 --- a/src/bun.js/javascript.zig +++ b/src/bun.js/javascript.zig @@ -40,7 +40,7 @@ const ImportKind = ast.ImportKind; const Analytics = @import("../analytics/analytics_thread.zig"); const ZigString = @import("../jsc.zig").ZigString; const Runtime = @import("../runtime.zig"); -const Router = @import("./api/router.zig"); +const Router = @import("./api/filesystem_router.zig"); const ImportRecord = ast.ImportRecord; const DotEnv = @import("../env_loader.zig"); const PackageJSON = @import("../resolver/package_json.zig").PackageJSON; diff --git a/src/bun.js/module_loader.zig b/src/bun.js/module_loader.zig index 290f3bf85..f991a9e30 100644 --- a/src/bun.js/module_loader.zig +++ b/src/bun.js/module_loader.zig @@ -40,7 +40,7 @@ const ImportKind = ast.ImportKind; const Analytics = @import("../analytics/analytics_thread.zig"); const ZigString = @import("../jsc.zig").ZigString; const Runtime = @import("../runtime.zig"); -const Router = @import("./api/router.zig"); +const Router = @import("./api/filesystem_router.zig"); const ImportRecord = ast.ImportRecord; const DotEnv = @import("../env_loader.zig"); const PackageJSON = @import("../resolver/package_json.zig").PackageJSON; diff --git a/src/bun.js/webcore/streams.classes.ts b/src/bun.js/webcore/streams.classes.ts new file mode 100644 index 000000000..0b070b857 --- /dev/null +++ b/src/bun.js/webcore/streams.classes.ts @@ -0,0 +1,5 @@ +// import { define } from "../scripts/class-definitions"; + +// export default [ +// define({}) +// ] diff --git a/src/jsc.zig b/src/jsc.zig index bd450b2a2..55935d246 100644 --- a/src/jsc.zig +++ b/src/jsc.zig @@ -33,7 +33,8 @@ pub const API = struct { pub const DebugServer = @import("./bun.js/api/server.zig").DebugServer; pub const DebugSSLServer = @import("./bun.js/api/server.zig").DebugSSLServer; pub const Bun = @import("./bun.js/api/bun.zig"); - pub const Router = @import("./bun.js/api/router.zig"); + pub const FileSystemRouter = @import("./bun.js/api/filesystem_router.zig").FileSystemRouter; + pub const MatchedRoute = @import("./bun.js/api/filesystem_router.zig").MatchedRoute; pub const TCPSocket = @import("./bun.js/api/bun/socket.zig").TCPSocket; pub const TLSSocket = @import("./bun.js/api/bun/socket.zig").TLSSocket; pub const Listener = @import("./bun.js/api/bun/socket.zig").Listener; diff --git a/src/resolver/resolver.zig b/src/resolver/resolver.zig index b88855c84..87928dd5f 100644 --- a/src/resolver/resolver.zig +++ b/src/resolver/resolver.zig @@ -2134,6 +2134,7 @@ pub const Resolver = struct { return try r.dirInfoCachedMaybeLog(path, true, true); } + /// The path must have a trailing slash and a sentinel 0 pub fn readDirInfo( r: *ThisResolver, path: string, diff --git a/src/router.zig b/src/router.zig index 2fbb53373..ee9d21d09 100644 --- a/src/router.zig +++ b/src/router.zig @@ -121,7 +121,7 @@ pub const Routes = struct { // We put this here to avoid loading the FrameworkConfig for the client, on the server. client_framework_enabled: bool = false, - pub fn matchPage(this: *Routes, _: string, url_path: URLPath, params: *Param.List) ?Match { + pub fn matchPageWithAllocator(this: *Routes, _: string, url_path: URLPath, params: *Param.List, allocator: std.mem.Allocator) ?Match { // Trim trailing slash var path = url_path.path; var redirect = false; @@ -181,7 +181,7 @@ pub const Routes = struct { var matcher = MatchContextType{ .params = params.* }; defer params.* = matcher.params; - if (this.match(this.allocator, path, *MatchContextType, &matcher)) |route| { + if (this.match(allocator, path, *MatchContextType, &matcher)) |route| { return Match{ .params = params, .name = route.name, @@ -198,6 +198,10 @@ pub const Routes = struct { return null; } + pub fn matchPage(this: *Routes, _: string, url_path: URLPath, params: *Param.List) ?Match { + return this.matchPageWithAllocator("", url_path, params, this.allocator); + } + fn matchDynamic(this: *Routes, allocator: std.mem.Allocator, path: string, comptime MatchContext: type, ctx: MatchContext) ?*Route { // its cleaned, so now we search the big list of strings var i: usize = 0; @@ -319,6 +323,13 @@ const RouteLoader = struct { } pub fn loadAll(allocator: std.mem.Allocator, config: Options.RouteConfig, log: *Logger.Log, comptime ResolverType: type, resolver: *ResolverType, root_dir_info: *const DirInfo) Routes { + var route_dirname_len: u16 = 0; + + const relative_dir = FileSystem.instance.relative(resolver.fs.top_level_dir, config.dir); + if (!strings.hasPrefixComptime(relative_dir, "..")) { + route_dirname_len = @truncate(u16, relative_dir.len + @as(usize, @boolToInt(config.dir[config.dir.len - 1] != std.fs.path.sep))); + } + var this = RouteLoader{ .allocator = allocator, .log = log, @@ -327,7 +338,7 @@ const RouteLoader = struct { .static_list = std.StringHashMap(*Route).init(allocator), .dedupe_dynamic = std.AutoArrayHashMap(u32, string).init(allocator), .all_routes = .{}, - .route_dirname_len = @truncate(u16, FileSystem.instance.relative(resolver.fs.top_level_dir, config.dir).len + @as(usize, @boolToInt(config.dir[config.dir.len - 1] != std.fs.path.sep))), + .route_dirname_len = route_dirname_len, }; defer this.dedupe_dynamic.deinit(); this.load(ResolverType, resolver, root_dir_info); @@ -436,10 +447,10 @@ const RouteLoader = struct { // length is extended by one // entry.dir is a string with a trailing slash if (comptime Environment.isDebug) { - std.debug.assert(entry.dir.ptr[fs.top_level_dir.len - 1] == '/'); + std.debug.assert(entry.dir.ptr[this.config.dir.len - 1] == '/'); } - const public_dir = entry.dir.ptr[fs.top_level_dir.len - 1 .. entry.dir.len]; + const public_dir = entry.dir.ptr[this.config.dir.len - 1 .. entry.dir.len]; if (Route.parse( entry.base(), @@ -636,15 +647,17 @@ pub const Route = struct { // the name we actually store will often be this one var public_path: string = brk: { if (base.len == 0) break :brk public_dir; - route_file_buf[0] = '/'; - - var buf: []u8 = route_file_buf[1..]; - - std.mem.copy( - u8, - buf, - public_dir, - ); + var buf: []u8 = &route_file_buf; + + if (public_dir.len > 0) { + route_file_buf[0] = '/'; + buf = buf[1..]; + std.mem.copy( + u8, + buf, + public_dir, + ); + } buf[public_dir.len] = '/'; buf = buf[public_dir.len + 1 ..]; std.mem.copy(u8, buf, base); @@ -755,6 +768,7 @@ pub const Route = struct { }; threadlocal var params_list: Param.List = undefined; + pub fn match(app: *Router, comptime Server: type, server: Server, comptime RequestContextType: type, ctx: *RequestContextType) !void { ctx.matched_route = null; diff --git a/src/url.zig b/src/url.zig index 34979df3f..4f6602a3f 100644 --- a/src/url.zig +++ b/src/url.zig @@ -445,15 +445,16 @@ pub const QueryStringMap = struct { threadlocal var _name_count: [8]string = undefined; pub fn getNameCount(this: *QueryStringMap) usize { - if (this.name_count == null) { - var count: usize = 0; - var iterate = this.iter(); - while (iterate.next(&_name_count) != null) { - count += 1; - } - this.name_count = count; - } - return this.name_count.?; + return this.list.len; + // if (this.name_count == null) { + // var count: usize = 0; + // var iterate = this.iter(); + // while (iterate.next(&_name_count) != null) { + // count += 1; + // } + // this.name_count = count; + // } + // return this.name_count.?; } pub fn iter(this: *const QueryStringMap) Iterator { @@ -484,7 +485,8 @@ pub const QueryStringMap = struct { var slice = this.map.list.slice(); const hash = slice.items(.name_hash)[this.i]; - var result = Result{ .name = this.map.str(slice.items(.name)[this.i]), .values = target[0..1] }; + const name_slice = slice.items(.name)[this.i]; + var result = Result{ .name = this.map.str(name_slice), .values = target[0..1] }; target[0] = this.map.str(slice.items(.value)[this.i]); this.visited.set(this.i); @@ -856,14 +858,25 @@ pub const CombinedScanner = struct { fn stringPointerFromStrings(parent: string, in: string) Api.StringPointer { if (in.len == 0 or parent.len == 0) return Api.StringPointer{}; - const end = @ptrToInt(parent.ptr) + parent.len; - const in_end = @ptrToInt(in.ptr) + in.len; - if (in_end < end) return Api.StringPointer{}; + if (bun.isSliceInBuffer(in, parent)) { + const end = @ptrToInt(parent.ptr) + parent.len; + const in_end = @ptrToInt(in.ptr) + in.len; + if (in_end < end) return Api.StringPointer{}; - return Api.StringPointer{ - .offset = @truncate(u32, @maximum(@ptrToInt(in.ptr), @ptrToInt(parent.ptr)) - @ptrToInt(parent.ptr)), - .length = @truncate(u32, in.len), - }; + return Api.StringPointer{ + .offset = @truncate(u32, @maximum(@ptrToInt(in.ptr), @ptrToInt(parent.ptr)) - @ptrToInt(parent.ptr)), + .length = @truncate(u32, in.len), + }; + } else { + if (strings.indexOf(parent, in)) |i| { + return Api.StringPointer{ + .offset = @truncate(u32, i), + .length = @truncate(u32, in.len), + }; + } + } + + return Api.StringPointer{}; } pub const PathnameScanner = struct { @@ -902,7 +915,7 @@ pub const PathnameScanner = struct { .name_needs_decoding = false, // TODO: fix this technical debt .value = stringPointerFromStrings(this.pathname, param.value), - .value_needs_decoding = std.mem.indexOfScalar(u8, param.value, '%') != null, + .value_needs_decoding = strings.containsChar(param.value, '%'), }; } }; diff --git a/test/bun.js/filesystem_router.test.ts b/test/bun.js/filesystem_router.test.ts new file mode 100644 index 000000000..c375cbb22 --- /dev/null +++ b/test/bun.js/filesystem_router.test.ts @@ -0,0 +1,85 @@ +import { FileSystemRouter } from "bun"; +import { it, expect } from "bun:test"; +import path, { dirname, resolve } from "path"; +import fs, { realpathSync, rmSync } from "fs"; +import { tmpdir } from "os"; + +function createTree(basedir, paths) { + for (const end of paths) { + const abs = path.join(basedir, end); + try { + const dir = dirname(abs); + if (dir.length > 0 && dir !== "/") fs.mkdirSync(dir, { recursive: true }); + } catch (e) {} + fs.writeFileSync(abs, "export default " + JSON.stringify(end) + ";\n"); + } +} + +it("should find files", () => { + const tempdir = realpathSync(tmpdir()) + "/"; + + rmSync(tempdir + "fs-router-test-01", { recursive: true, force: true }); + + createTree(tempdir + "fs-router-test-01", [ + "a.tsx", + "b.tsx", + "abc/[id].tsx", + "abc/index.tsx", + "abc/def/[id].tsx", + "abc/def/index.tsx", + "abc/def/ghi/[id].tsx", + "abc/def/ghi/index.tsx", + "abc/def/ghi/jkl/[id].tsx", + "abc/def/ghi/jkl/index.tsx", + "[id].tsx", + "index.tsx", + "foo/[id].tsx", + "catch-all/[...id].tsx", + ]); + + const router = new FileSystemRouter({ + dir: tempdir + "fs-router-test-01/", + fileExtensions: [".tsx"], + style: "nextjs", + }); + + const routes = router.routes; + const fixture = { + "/": `${tempdir}fs-router-test-01/index.tsx`, + "/[id]": `${tempdir}fs-router-test-01/[id].tsx`, + "/a": `${tempdir}fs-router-test-01/a.tsx`, + "/abc": `${tempdir}fs-router-test-01/abc/index.tsx`, + "/abc/[id]": `${tempdir}fs-router-test-01/abc/[id].tsx`, + "/abc/def/[id]": `${tempdir}fs-router-test-01/abc/def/[id].tsx`, + "/abc/def/ghi": `${tempdir}fs-router-test-01/abc/def/ghi/index.tsx`, + "/abc/def/ghi/[id]": `${tempdir}fs-router-test-01/abc/def/ghi/[id].tsx`, + "/abc/def/ghi/jkl": `${tempdir}fs-router-test-01/abc/def/ghi/jkl/index.tsx`, + "/abc/def/ghi/jkl/[id]": `${tempdir}fs-router-test-01/abc/def/ghi/jkl/[id].tsx`, + "/abc/def": `${tempdir}fs-router-test-01/abc/def/index.tsx`, + "/b": `${tempdir}fs-router-test-01/b.tsx`, + "/foo/[id]": `${tempdir}fs-router-test-01/foo/[id].tsx`, + "/catch-all/[...id]": `${tempdir}fs-router-test-01/catch-all/[...id].tsx`, + }; + for (const route in fixture) { + if (!(route in routes)) { + throw new Error(`Route ${route} not found`); + } + + expect(routes[route]).toBe(fixture[route]); + } + + expect(Object.keys(routes).length).toBe(Object.keys(fixture).length); + + expect(router.match("/never/gonna/give/you/up")).toBe(null); + expect( + router.match( + "/catch-all/we-are-no-strangers-to-love/you/know/the/rules/and/so/do/i", + ).params.id, + ).toBe("we-are-no-strangers-to-love/you/know/the/rules/and/so/do/i"); + expect(router.match("/").name).toBe("/"); + expect(router.match("/index").name).toBe("/"); + expect(router.match("/index/").name).toBe("/"); + expect(router.match("/a").name).toBe("/a"); + expect(router.match("/b").name).toBe("/b"); + expect(router.match("/abc/123").params.id).toBe("123"); +}); |