diff --git a/packages/runtime/src/internal/matchRoutes.spec.ts b/packages/runtime/src/internal/matchRoutes.spec.ts index 97eddcfa4f..cfb95367c8 100644 --- a/packages/runtime/src/internal/matchRoutes.spec.ts +++ b/packages/runtime/src/internal/matchRoutes.spec.ts @@ -1,8 +1,9 @@ -import { matchRoutes } from "./matchRoutes.js"; +import type { RouteConf } from "@next-core/types"; +import { matchRoutes, matchRoute } from "./matchRoutes.js"; const consoleError = jest.spyOn(console, "error").mockImplementation(); -describe("matchStoryboard", () => { +describe("matchRoutes", () => { test("handle path not string", async () => { await expect(() => matchRoutes( @@ -25,3 +26,45 @@ describe("matchStoryboard", () => { ); }); }); + +describe("matchRoute", () => { + test("handle array path", () => { + const route: RouteConf = { + path: "${APP.homepage}[,/b/([^/]+)]", + exact: true, + bricks: [], + }; + const homepage = "/home"; + + expect(matchRoute(route, homepage, "/home/b/123")).toEqual({ + isExact: true, + params: { + "0": "123", + }, + path: "/home/b/([^/]+)", + url: "/home/b/123", + }); + + expect(matchRoute(route, homepage, "/home")).toEqual({ + isExact: true, + params: {}, + path: "/home", + url: "/home", + }); + + expect(matchRoute(route, homepage, "/home/c")).toEqual(null); + expect(matchRoute(route, homepage, "/home/b/123/x")).toEqual(null); + }); + + test("handle not started with ${APP.homepage}", () => { + const route: RouteConf = { + path: "/home[,/b/([^/]+)]", + exact: true, + bricks: [], + }; + const homepage = "/home"; + + expect(matchRoute(route, homepage, "/home")).toEqual(null); + expect(matchRoute(route, homepage, "/home/b/123")).toEqual(null); + }); +}); diff --git a/packages/runtime/src/internal/matchRoutes.ts b/packages/runtime/src/internal/matchRoutes.ts index 1468188440..3175a8e49c 100644 --- a/packages/runtime/src/internal/matchRoutes.ts +++ b/packages/runtime/src/internal/matchRoutes.ts @@ -4,6 +4,8 @@ import { asyncCheckIf } from "./compute/checkIf.js"; import type { RuntimeContext } from "./interfaces.js"; import { hooks } from "./Runtime.js"; +const HOMEPAGE_PREFIX = "${APP.homepage}"; + type MatchRoutesResult = | { match: MatchResult; @@ -49,9 +51,25 @@ export function matchRoute( homepage: string, pathname: string ) { - const routePath = route.path.replace(/^\$\{APP.homepage\}/, homepage); + const path = getRoutePath(route, homepage); return matchPath(pathname, { - path: routePath, + path, exact: route.exact, }); } + +function getRoutePath(route: RouteConf, homepage: string): string | string[] { + if (route.path.startsWith(HOMEPAGE_PREFIX)) { + const restPath = route.path.slice(HOMEPAGE_PREFIX.length); + if ( + restPath.startsWith("[") && + restPath.endsWith("]") && + restPath.includes(",") + ) { + const paths = restPath.slice(1, -1).split(","); + return paths.map((p) => `${homepage}${p}`); + } + return `${homepage}${restPath}`; + } + return route.path; +}