From a0a5ea4d7b812339d28667c101cbd154a245d5e9 Mon Sep 17 00:00:00 2001 From: Mikel King Date: Thu, 9 Dec 2021 15:55:18 -0700 Subject: [PATCH] fix: support base64 encoded ids on nested routes (#8291) Modify the non-capturing group at the end of compilePath to include the proceeding / This is necessary for paths that include base64 included ids such as relay globalIds (e.x. users/RGFzaGJvYXJkOjE1Nzk=/edit) --- .../__tests__/matchRoutes-test.tsx | 21 ++++++++++++++++++- packages/react-router/index.tsx | 6 +++--- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/packages/react-router/__tests__/matchRoutes-test.tsx b/packages/react-router/__tests__/matchRoutes-test.tsx index 0d29d7405e..3e2ecfb569 100644 --- a/packages/react-router/__tests__/matchRoutes-test.tsx +++ b/packages/react-router/__tests__/matchRoutes-test.tsx @@ -12,9 +12,14 @@ function pickPaths( } describe("matchRoutes", () => { + let userEditRoute: RouteObject = { + path: "edit", + element:

User Edit

+ }; let userProfileRoute: RouteObject = { path: ":id", - element:

User Profile

+ element:

User Profile

, + children: [userEditRoute] }; let usersRoute: RouteObject = { path: "/users", @@ -88,6 +93,20 @@ describe("matchRoutes", () => { it("matches nested dynamic routes correctly", () => { expect(pickPaths(routes, "/users/mj")).toEqual(["/users", ":id"]); + expect(pickPaths(routes, "/users/mj/edit")).toEqual([ + "/users", + ":id", + "edit" + ]); + }); + + it("matches nested dynamic routes with params ending in = (e.x. base64 encoded Id)", () => { + expect(pickPaths(routes, "/users/VXNlcnM6MQ==")).toEqual(["/users", ":id"]); + expect(pickPaths(routes, "/users/VXNlcnM6MQ==/edit")).toEqual([ + "/users", + ":id", + "edit" + ]); }); it("matches nested * routes correctly", () => { diff --git a/packages/react-router/index.tsx b/packages/react-router/index.tsx index 34de7a6738..b787ac5d95 100644 --- a/packages/react-router/index.tsx +++ b/packages/react-router/index.tsx @@ -1203,10 +1203,10 @@ function compilePath( } else { regexpSource += end ? "\\/*$" // When matching to the end, ignore trailing slashes - : // Otherwise, at least match a word boundary. This restricts parent - // routes to matching only their own words and nothing more, e.g. parent + : // Otherwise, match a word boundary or a proceeding /. The word boundary restricts + // parent routes to matching only their own words and nothing more, e.g. parent // route "/home" should not match "/home2". - "(?:\\b|$)"; + "(?:\\b|\\/|$)"; } let matcher = new RegExp(regexpSource, caseSensitive ? undefined : "i");