Skip to content

Commit 0a6ee8d

Browse files
committed
handle multiple route
1 parent ea9d397 commit 0a6ee8d

File tree

7 files changed

+72
-55
lines changed

7 files changed

+72
-55
lines changed

packages/open-next/src/adapters/config/index.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import path from "node:path";
22

33
import { debug } from "../logger";
44
import {
5+
loadAppPathRoutesManifest,
56
loadAppPathsManifest,
67
loadAppPathsManifestKeys,
78
loadBuildId,
@@ -31,4 +32,6 @@ export const AppPathsManifestKeys =
3132
/* @__PURE__ */ loadAppPathsManifestKeys(NEXT_DIR);
3233
export const MiddlewareManifest =
3334
/* @__PURE__ */ loadMiddlewareManifest(NEXT_DIR);
34-
export const AppPathsManifest = loadAppPathsManifest(NEXT_DIR);
35+
export const AppPathsManifest = /* @__PURE__ */ loadAppPathsManifest(NEXT_DIR);
36+
export const AppPathRoutesManifest =
37+
/* @__PURE__ */ loadAppPathRoutesManifest(NEXT_DIR);

packages/open-next/src/adapters/config/util.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,17 @@ export function loadAppPathsManifest(nextDir: string) {
8989
return JSON.parse(appPathsManifestJson) as Record<string, string>;
9090
}
9191

92+
export function loadAppPathRoutesManifest(nextDir: string) {
93+
const appPathRoutesManifestPath = path.join(
94+
nextDir,
95+
"app-path-routes-manifest.json",
96+
);
97+
const appPathRoutesManifestJson = fs.existsSync(appPathRoutesManifestPath)
98+
? fs.readFileSync(appPathRoutesManifestPath, "utf-8")
99+
: "{}";
100+
return JSON.parse(appPathRoutesManifestJson) as Record<string, string>;
101+
}
102+
92103
export function loadAppPathsManifestKeys(nextDir: string) {
93104
const appPathsManifest = loadAppPathsManifest(nextDir);
94105
return Object.keys(appPathsManifest).map((key) => {

packages/open-next/src/adapters/middleware.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@ import {
1616
} from "../core/resolve";
1717
import routingHandler, {
1818
INTERNAL_HEADER_INITIAL_PATH,
19-
INTERNAL_HEADER_RESOLVED_ROUTE,
20-
INTERNAL_HEADER_ROUTE_TYPE,
19+
INTERNAL_HEADER_RESOLVED_ROUTES,
2120
} from "../core/routingHandler";
2221

2322
globalThis.internalFetch = fetch;
@@ -66,14 +65,15 @@ const defaultHandler = async (
6665
headers: {
6766
...result.internalEvent.headers,
6867
[INTERNAL_HEADER_INITIAL_PATH]: internalEvent.rawPath,
69-
[INTERNAL_HEADER_RESOLVED_ROUTE]: result.resolvedRoute ?? "",
70-
[INTERNAL_HEADER_ROUTE_TYPE]: result.routeType ?? "",
68+
[INTERNAL_HEADER_RESOLVED_ROUTES]:
69+
JSON.stringify(result.resolvedRoutes) ?? "[]",
7170
},
7271
},
7372
isExternalRewrite: result.isExternalRewrite,
7473
origin,
7574
isISR: result.isISR,
7675
initialPath: result.initialPath,
76+
resolvedRoutes: result.resolvedRoutes,
7777
};
7878
}
7979
try {
@@ -93,6 +93,7 @@ const defaultHandler = async (
9393
origin: false,
9494
isISR: result.isISR,
9595
initialPath: result.internalEvent.rawPath,
96+
resolvedRoutes: [{ route: "/500", type: "page" }],
9697
};
9798
}
9899
}

packages/open-next/src/core/requestHandler.ts

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { IncomingMessage } from "http/index.js";
55
import type {
66
InternalEvent,
77
InternalResult,
8-
RouteType,
8+
ResolvedRoute,
99
RoutingResult,
1010
StreamCreator,
1111
} from "types/open-next";
@@ -16,8 +16,7 @@ import { patchAsyncStorage } from "./patchAsyncStorage";
1616
import { convertRes, createServerResponse } from "./routing/util";
1717
import routingHandler, {
1818
INTERNAL_HEADER_INITIAL_PATH,
19-
INTERNAL_HEADER_RESOLVED_ROUTE,
20-
INTERNAL_HEADER_ROUTE_TYPE,
19+
INTERNAL_HEADER_RESOLVED_ROUTES,
2120
MIDDLEWARE_HEADER_PREFIX,
2221
MIDDLEWARE_HEADER_PREFIX_LEN,
2322
} from "./routingHandler";
@@ -41,15 +40,14 @@ export async function openNextHandler(
4140
}
4241
debug("internalEvent", internalEvent);
4342

44-
// These 3 will get overwritten by the routing handler if not using an external middleware
43+
// These 2 will get overwritten by the routing handler if not using an external middleware
4544
const internalHeaders = {
4645
initialPath:
4746
internalEvent.headers[INTERNAL_HEADER_INITIAL_PATH] ??
4847
internalEvent.rawPath,
49-
resolvedRoute: internalEvent.headers[INTERNAL_HEADER_RESOLVED_ROUTE],
50-
routeType: internalEvent.headers[INTERNAL_HEADER_ROUTE_TYPE] as
51-
| RouteType
52-
| undefined,
48+
resolvedRoutes: internalEvent.headers[INTERNAL_HEADER_RESOLVED_ROUTES]
49+
? JSON.parse(internalEvent.headers[INTERNAL_HEADER_RESOLVED_ROUTES])
50+
: ([] as ResolvedRoute[]),
5351
};
5452

5553
let routingResult: InternalResult | RoutingResult = {
@@ -111,7 +109,7 @@ export async function openNextHandler(
111109
isISR: false,
112110
origin: false,
113111
initialPath: internalEvent.rawPath,
114-
resolvedRoute: "/500",
112+
resolvedRoutes: [{ route: "/500", type: "page" }],
115113
};
116114
}
117115
}

packages/open-next/src/core/routingHandler.ts

Lines changed: 33 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {
2-
AppPathsManifest,
2+
AppPathRoutesManifest,
33
BuildId,
44
ConfigHeaders,
55
PrerenderManifest,
@@ -9,6 +9,7 @@ import type { RouteDefinition } from "types/next-types";
99
import type {
1010
InternalEvent,
1111
InternalResult,
12+
ResolvedRoute,
1213
RouteType,
1314
RoutingResult,
1415
} from "types/open-next";
@@ -27,8 +28,7 @@ import { handleMiddleware } from "./routing/middleware";
2728
export const MIDDLEWARE_HEADER_PREFIX = "x-middleware-response-";
2829
export const INTERNAL_HEADER_PREFIX = "x-opennext-";
2930
export const INTERNAL_HEADER_INITIAL_PATH = `${INTERNAL_HEADER_PREFIX}initial-path`;
30-
export const INTERNAL_HEADER_RESOLVED_ROUTE = `${INTERNAL_HEADER_PREFIX}resolved-route`;
31-
export const INTERNAL_HEADER_ROUTE_TYPE = `${INTERNAL_HEADER_PREFIX}route-type`;
31+
export const INTERNAL_HEADER_RESOLVED_ROUTES = `${INTERNAL_HEADER_PREFIX}resolved-routes`;
3232
export const MIDDLEWARE_HEADER_PREFIX_LEN = MIDDLEWARE_HEADER_PREFIX.length;
3333

3434
// Add the locale prefix to the regex so we correctly match the rawPath
@@ -57,31 +57,35 @@ export function routeMatcher(routeDefinitions: RouteDefinition[]) {
5757
),
5858
};
5959
});
60+
61+
// We need to use AppPathRoutesManifest here
6062
const appPathsSet = new Set(
61-
Object.keys(AppPathsManifest)
62-
.filter((key) => key.endsWith("/page"))
63-
// Remove the /page suffix
64-
.map((key) => key.replace(/\/page$/, "")),
63+
Object.entries(AppPathRoutesManifest)
64+
.filter(([key, _]) => key.endsWith("page"))
65+
.map(([_, value]) => value),
6566
);
6667
const routePathsSet = new Set(
67-
Object.keys(AppPathsManifest)
68-
.filter((key) => key.endsWith("/route"))
69-
// Remove the /route suffix
70-
.map((key) => key.replace(/\/route$/, "")),
68+
Object.entries(AppPathRoutesManifest)
69+
.filter(([key, _]) => key.endsWith("route"))
70+
.map(([_, value]) => value),
7171
);
7272
return function matchRoute(path: string) {
73-
const foundRoute = regexp.find((route) => route.regexp.test(path));
74-
let routeType: RouteType | undefined = undefined;
75-
if (foundRoute) {
76-
routeType = appPathsSet.has(foundRoute.page)
77-
? "app"
78-
: routePathsSet.has(foundRoute.page)
79-
? "route"
80-
: "page";
81-
return {
82-
page: foundRoute.page,
83-
routeType,
84-
};
73+
const foundRoutes = regexp.filter((route) => route.regexp.test(path));
74+
75+
if (foundRoutes.length > 0) {
76+
return foundRoutes.map((foundRoute) => {
77+
const routeType: RouteType | undefined = appPathsSet.has(
78+
foundRoute.page,
79+
)
80+
? "app"
81+
: routePathsSet.has(foundRoute.page)
82+
? "route"
83+
: "page";
84+
return {
85+
route: foundRoute.page,
86+
type: routeType,
87+
};
88+
});
8589
}
8690
return false;
8791
};
@@ -265,27 +269,19 @@ export default async function routingHandler(
265269
...nextHeaders,
266270
});
267271

268-
let resolvedRoute: string | undefined;
269-
let routeType: RouteType | undefined;
272+
const resolvedRoutes: ResolvedRoute[] = [
273+
...(Array.isArray(foundStaticRoute) ? foundStaticRoute : []),
274+
...(Array.isArray(foundDynamicRoute) ? foundDynamicRoute : []),
275+
];
270276

271-
if (foundStaticRoute) {
272-
resolvedRoute = foundStaticRoute.page;
273-
routeType = foundStaticRoute.routeType;
274-
} else if (foundDynamicRoute) {
275-
resolvedRoute = foundDynamicRoute.page;
276-
routeType = foundDynamicRoute.routeType;
277-
} else if (isApiRoute) {
278-
// For /api paths we assume that they're route types
279-
routeType = "route";
280-
}
277+
console.log("resolvedRoutes", resolvedRoutes);
281278

282279
return {
283280
internalEvent,
284281
isExternalRewrite,
285282
origin: false,
286283
isISR,
287284
initialPath: event.rawPath,
288-
resolvedRoute,
289-
routeType,
285+
resolvedRoutes,
290286
};
291287
}

packages/open-next/src/plugins/edge.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import type { Plugin } from "esbuild";
66
import type { MiddlewareInfo } from "types/next-types.js";
77

88
import {
9+
loadAppPathRoutesManifest,
910
loadAppPathsManifest,
1011
loadAppPathsManifestKeys,
1112
loadBuildId,
@@ -169,6 +170,7 @@ ${contents}
169170
const AppPathsManifestKeys = loadAppPathsManifestKeys(nextDir);
170171
const MiddlewareManifest = loadMiddlewareManifest(nextDir);
171172
const AppPathsManifest = loadAppPathsManifest(nextDir);
173+
const AppPathRoutesManifest = loadAppPathRoutesManifest(nextDir);
172174

173175
const contents = `
174176
import path from "node:path";
@@ -191,6 +193,8 @@ ${contents}
191193
export const AppPathsManifestKeys = ${JSON.stringify(AppPathsManifestKeys)};
192194
export const MiddlewareManifest = ${JSON.stringify(MiddlewareManifest)};
193195
export const AppPathsManifest = ${JSON.stringify(AppPathsManifest)};
196+
export const AppPathRoutesManifest = ${JSON.stringify(AppPathRoutesManifest)};
197+
194198
195199
process.env.NEXT_BUILD_ID = BuildId;
196200
`;

packages/open-next/src/types/open-next.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,11 @@ export type IncludedConverter =
109109

110110
export type RouteType = "route" | "page" | "app";
111111

112+
export interface ResolvedRoute {
113+
route: string;
114+
type: RouteType;
115+
}
116+
112117
export interface RoutingResult {
113118
internalEvent: InternalEvent;
114119
// If the request is an external rewrite, if used with an external middleware will be false on every server function
@@ -119,10 +124,9 @@ export interface RoutingResult {
119124
isISR: boolean;
120125
// The initial rawPath of the request before applying rewrites, if used with an external middleware will be defined in x-opennext-initial-path header
121126
initialPath: string;
122-
// The resolved route after applying rewrites, if used with an external middleware will be defined in x-opennext-resolved-route header
123-
resolvedRoute?: string;
124-
// The type of the resolved route, if used with an external middleware will be defined in x-opennext-route-type header
125-
routeType?: RouteType;
127+
128+
// The resolved route after applying rewrites, if used with an external middleware will be defined in x-opennext-resolved-routes header as a json encoded array
129+
resolvedRoutes: ResolvedRoute[];
126130
}
127131

128132
export interface MiddlewareResult

0 commit comments

Comments
 (0)