Skip to content

Commit f6a29a9

Browse files
committed
update to use initialPath when needed
1 parent 67a6102 commit f6a29a9

File tree

6 files changed

+89
-44
lines changed

6 files changed

+89
-44
lines changed

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

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -447,9 +447,15 @@ export default class Cache {
447447
if (uniquePaths.length > 0) {
448448
await globalThis.cdnInvalidationHandler.invalidatePaths(
449449
uniquePaths.map((path) => ({
450-
path,
451-
// Here we can be sure that the path is from app router
452-
isAppRouter: true,
450+
initialPath: path,
451+
rawPath: path,
452+
resolvedRoutes: [
453+
{
454+
route: path,
455+
// TODO: ideally here we should check if it's an app router page or route
456+
type: "app",
457+
},
458+
],
453459
})),
454460
);
455461
}

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

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,14 @@ export async function openNextHandler(
118118
// response is used only in the streaming case
119119
if (responseStreaming) {
120120
const response = createServerResponse(
121-
internalEvent,
121+
{
122+
internalEvent,
123+
isExternalRewrite: false,
124+
isISR: false,
125+
resolvedRoutes: [],
126+
origin: false,
127+
initialPath: internalEvent.rawPath,
128+
},
122129
headers,
123130
responseStreaming,
124131
);
@@ -162,7 +169,7 @@ export async function openNextHandler(
162169

163170
const req = new IncomingMessage(reqProps);
164171
const res = createServerResponse(
165-
preprocessedEvent,
172+
routingResult,
166173
overwrittenResponseHeaders,
167174
responseStreaming,
168175
);

packages/open-next/src/core/routing/util.ts

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ import { OpenNextNodeResponse } from "http/openNextResponse.js";
88
import { parseHeaders } from "http/util.js";
99
import type { MiddlewareManifest } from "types/next-types";
1010
import type {
11-
InternalEvent,
1211
InternalResult,
12+
RoutingResult,
1313
StreamCreator,
1414
} from "types/open-next.js";
1515

@@ -401,10 +401,11 @@ export function fixISRHeaders(headers: OutgoingHttpHeaders) {
401401
* @__PURE__
402402
*/
403403
export function createServerResponse(
404-
internalEvent: InternalEvent,
404+
routingResult: RoutingResult,
405405
headers: Record<string, string | string[] | undefined>,
406406
responseStream?: StreamCreator,
407407
) {
408+
const internalEvent = routingResult.internalEvent;
408409
return new OpenNextNodeResponse(
409410
(_headers) => {
410411
fixCacheHeaderForHtmlPages(internalEvent.rawPath, _headers);
@@ -418,34 +419,29 @@ export function createServerResponse(
418419
internalEvent.rawPath,
419420
_headers,
420421
);
421-
await invalidateCDNOnRequest({
422-
rawPath: internalEvent.rawPath,
423-
isIsrRevalidation: internalEvent.headers["x-isr"] === "1",
424-
headers: _headers,
425-
});
422+
await invalidateCDNOnRequest(routingResult, _headers);
426423
},
427424
responseStream,
428425
headers,
429426
);
430427
}
431428

432429
// This function is used only for `res.revalidate()`
433-
export async function invalidateCDNOnRequest(params: {
434-
//TODO: use the initialPath instead of rawPath, a rewrite could have happened and would make cdn invalidation fail
435-
rawPath: string;
436-
isIsrRevalidation?: boolean;
437-
headers: OutgoingHttpHeaders;
438-
}) {
439-
const { rawPath, isIsrRevalidation, headers } = params;
430+
export async function invalidateCDNOnRequest(
431+
params: RoutingResult,
432+
headers: OutgoingHttpHeaders,
433+
) {
434+
const { internalEvent, initialPath, resolvedRoutes } = params;
435+
const isIsrRevalidation = internalEvent.headers["x-isr"] === "1";
440436
if (
441437
!isIsrRevalidation &&
442438
headers[CommonHeaders.NEXT_CACHE] === "REVALIDATED"
443439
) {
444440
await globalThis.cdnInvalidationHandler.invalidatePaths([
445441
{
446-
path: rawPath,
447-
//TODO: Here we assume that the path is for page router, this might not be the case
448-
isAppRouter: false,
442+
initialPath,
443+
rawPath: internalEvent.rawPath,
444+
resolvedRoutes,
449445
},
450446
]);
451447
}

packages/open-next/src/overrides/cdnInvalidation/cloudfront.ts

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,20 @@ const cloudfront = new CloudFrontClient({});
88
export default {
99
name: "cloudfront",
1010
invalidatePaths: async (paths) => {
11-
//TODO: test the constructed paths
12-
const constructedPaths = paths.flatMap(({ path, isAppRouter }) =>
13-
isAppRouter
14-
? [`${path}`, `${path}?_rsc=*`]
15-
: [
16-
`${path}`,
17-
`/_next/data/${process.env.NEXT_BUILD_ID}${path === "/" ? "/index" : path}.json*`,
18-
],
11+
const constructedPaths = paths.flatMap(
12+
({ initialPath, resolvedRoutes }) => {
13+
const isAppRouter = resolvedRoutes.some(
14+
(route) => route.type === "app",
15+
);
16+
// revalidateTag doesn't have any leading slash, remove it just to be sure
17+
const path = initialPath.replace(/^\//, "");
18+
return isAppRouter
19+
? [`/${path}`, `/${path}?_rsc=*`]
20+
: [
21+
`/${path}`,
22+
`/_next/data/${process.env.NEXT_BUILD_ID}${path === "/" ? "/index" : `/${path}`}.json*`,
23+
];
24+
},
1925
);
2026
await cloudfront.send(
2127
new CreateInvalidationCommand({

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import type {
88
InternalEvent,
99
InternalResult,
1010
Origin,
11+
ResolvedRoute,
1112
StreamCreator,
1213
} from "./open-next";
1314

@@ -141,8 +142,9 @@ export type ProxyExternalRequest = BaseOverride & {
141142
};
142143

143144
type CDNPath = {
144-
path: string;
145-
isAppRouter: boolean;
145+
initialPath: string;
146+
rawPath: string;
147+
resolvedRoutes: ResolvedRoute[];
146148
};
147149

148150
export type CDNInvalidationHandler = BaseOverride & {

packages/tests-unit/tests/core/routing/util.test.ts

Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -687,10 +687,14 @@ describe("invalidateCDNOnRequest", () => {
687687
const headers: Record<string, string> = {
688688
"x-nextjs-cache": "HIT",
689689
};
690-
await invalidateCDNOnRequest({
691-
rawPath: "/path",
690+
await invalidateCDNOnRequest(
691+
{
692+
internalEvent: {
693+
headers: {},
694+
},
695+
},
692696
headers,
693-
});
697+
);
694698

695699
expect(
696700
globalThis.cdnInvalidationHandler.invalidatePaths,
@@ -701,11 +705,17 @@ describe("invalidateCDNOnRequest", () => {
701705
const headers: Record<string, string> = {
702706
"x-nextjs-cache": "REVALIDATED",
703707
};
704-
await invalidateCDNOnRequest({
705-
rawPath: "/path",
708+
await invalidateCDNOnRequest(
709+
{
710+
internalEvent: {
711+
rawPath: "/path",
712+
headers: {
713+
"x-isr": "1",
714+
},
715+
},
716+
},
706717
headers,
707-
isIsrRevalidation: true,
708-
});
718+
);
709719

710720
expect(
711721
globalThis.cdnInvalidationHandler.invalidatePaths,
@@ -716,17 +726,35 @@ describe("invalidateCDNOnRequest", () => {
716726
const headers: Record<string, string> = {
717727
"x-nextjs-cache": "REVALIDATED",
718728
};
719-
await invalidateCDNOnRequest({
720-
rawPath: "/path",
729+
await invalidateCDNOnRequest(
730+
{
731+
initialPath: "/path",
732+
internalEvent: {
733+
rawPath: "/path",
734+
headers: {},
735+
},
736+
resolvedRoutes: [
737+
{
738+
type: "app",
739+
route: "/path",
740+
},
741+
],
742+
},
721743
headers,
722-
});
744+
);
723745

724746
expect(
725747
globalThis.cdnInvalidationHandler.invalidatePaths,
726748
).toHaveBeenCalledWith([
727749
{
728-
path: "/path",
729-
isAppRouter: false,
750+
initialPath: "/path",
751+
rawPath: "/path",
752+
resolvedRoutes: [
753+
{
754+
type: "app",
755+
route: "/path",
756+
},
757+
],
730758
},
731759
]);
732760
});

0 commit comments

Comments
 (0)