aboutsummaryrefslogtreecommitdiff
path: root/src/javascript/jsc/api/router.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/javascript/jsc/api/router.zig')
-rw-r--r--src/javascript/jsc/api/router.zig97
1 files changed, 84 insertions, 13 deletions
diff --git a/src/javascript/jsc/api/router.zig b/src/javascript/jsc/api/router.zig
index 500ce1853..ed2e0a9af 100644
--- a/src/javascript/jsc/api/router.zig
+++ b/src/javascript/jsc/api/router.zig
@@ -28,10 +28,15 @@ 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("../../../query_string_map.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 = .{},
+
script_src: ?string = null,
script_src_buf: [1024]u8 = undefined,
@@ -65,42 +70,101 @@ pub fn match(
return null;
}
- if (js.JSValueIsObjectOfClass(ctx, arguments[0], FetchEvent.Class.get().*)) {
+ if (FetchEvent.Class.loaded and js.JSValueIsObjectOfClass(ctx, arguments[0], FetchEvent.Class.get().*)) {
return matchFetchEvent(ctx, To.Zig.ptr(FetchEvent, arguments[0]), exception);
}
- // if (js.JSValueIsString(ctx, arguments[0])) {
- // return matchPathName(ctx, arguments[0], exception);
- // }
+ var router = JavaScript.VirtualMachine.vm.bundler.router orelse {
+ JSError(getAllocator(ctx), "Bun.match needs a framework configured with routes", .{}, ctx, exception);
+ return null;
+ };
+ var arg = JSC.JSValue.fromRef(arguments[0]);
+ 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 path_string = req.url;
+ path_ = path_string.toSlice(bun.default_allocator);
+ var url = URL.parse(path_.?.slice());
+ 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;
+ };
- if (js.JSValueIsObjectOfClass(ctx, arguments[0], Request.Class.get().*)) {
- return matchRequest(ctx, To.Zig.ptr(Request, arguments[0]), exception);
+ 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;
+ instance.script_src_buf_writer = ScriptSrcStream{ .pos = 0, .buffer = std.mem.span(&instance.script_src_buf) };
+
+ return Instance.make(ctx, instance);
}
+ // router.routes.matchPage
- return null;
+ return JSC.JSValue.jsNull().asObjectRef();
}
fn matchRequest(
ctx: js.JSContextRef,
request: *const Request,
- exception: js.ExceptionRef,
+ _: js.ExceptionRef,
) js.JSObjectRef {
- return createRouteObject(ctx, request.request_context, exception);
+ return createRouteObject(ctx, request.request_context);
}
fn matchFetchEvent(
ctx: js.JSContextRef,
fetch_event: *const FetchEvent,
- exception: js.ExceptionRef,
+ _: js.ExceptionRef,
) js.JSObjectRef {
- return createRouteObject(ctx, fetch_event.request_context, exception);
+ return createRouteObject(ctx, fetch_event.request_context);
}
-fn createRouteObject(ctx: js.JSContextRef, req: *const http.RequestContext, _: js.ExceptionRef) js.JSValueRef {
+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,
@@ -276,6 +340,13 @@ pub fn finalize(
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(