aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2022-11-22 02:13:03 -0800
committerGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2022-11-22 02:13:03 -0800
commitd21aee514375e12335c61936ae302cd67f1f73bf (patch)
treee4985c55d27f7d1bcb7c8fa56441bd4711e15433
parent65a56c2560a1ef7b036995a8eade45236f76f819 (diff)
downloadbun-d21aee514375e12335c61936ae302cd67f1f73bf.tar.gz
bun-d21aee514375e12335c61936ae302cd67f1f73bf.tar.zst
bun-d21aee514375e12335c61936ae302cd67f1f73bf.zip
Introduce `Bun.FileSystemRouter` API
-rw-r--r--src/bun.js/api/bun.zig23
-rw-r--r--src/bun.js/api/ffi.zig1
-rw-r--r--src/bun.js/api/filesystem_router.classes.ts69
-rw-r--r--src/bun.js/api/filesystem_router.zig701
-rw-r--r--src/bun.js/api/html_rewriter.zig1
-rw-r--r--src/bun.js/api/router.zig507
-rw-r--r--src/bun.js/api/server.zig1
-rw-r--r--src/bun.js/api/transpiler.zig1
-rw-r--r--src/bun.js/base.zig2
-rw-r--r--src/bun.js/bindings/ZigGeneratedClasses+DOMClientIsoSubspaces.h4
-rw-r--r--src/bun.js/bindings/ZigGeneratedClasses+DOMIsoSubspaces.h4
-rw-r--r--src/bun.js/bindings/ZigGeneratedClasses+lazyStructureHeader.h12
-rw-r--r--src/bun.js/bindings/ZigGeneratedClasses+lazyStructureImpl.h14
-rw-r--r--src/bun.js/bindings/ZigGeneratedClasses.cpp1137
-rw-r--r--src/bun.js/bindings/ZigGeneratedClasses.h119
-rw-r--r--src/bun.js/bindings/bindings.zig9
-rw-r--r--src/bun.js/bindings/generated_classes.zig366
-rw-r--r--src/bun.js/bindings/generated_classes_list.zig2
-rw-r--r--src/bun.js/javascript.zig2
-rw-r--r--src/bun.js/module_loader.zig2
-rw-r--r--src/bun.js/webcore/streams.classes.ts5
-rw-r--r--src/jsc.zig3
-rw-r--r--src/resolver/resolver.zig1
-rw-r--r--src/router.zig42
-rw-r--r--src/url.zig49
-rw-r--r--test/bun.js/filesystem_router.test.ts85
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,
+ &params,
+ 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");
+});