11/**
2- * Inline `loadManifest` as it relies on `readFileSync` that is not supported by workerd.
2+ * Inline `loadManifest` and `evalManifest` from `load-manifest.js`
3+ *
4+ * They rely on `readFileSync` that is not supported by workerd.
35 */
46
57import { readFile } from "node:fs/promises" ;
@@ -21,13 +23,17 @@ export function inlineLoadManifest(updater: ContentUpdater, buildOpts: BuildOpti
2123 escape : false ,
2224 } ) ,
2325 contentFilter : / f u n c t i o n l o a d M a n i f e s t \( / ,
24- callback : async ( { contents } ) => patchCode ( contents , await getRule ( buildOpts ) ) ,
26+ callback : async ( { contents } ) => {
27+ contents = await patchCode ( contents , await getLoadManifestRule ( buildOpts ) ) ;
28+ contents = await patchCode ( contents , await getEvalManifestRule ( buildOpts ) ) ;
29+ return contents ;
30+ } ,
2531 } ,
2632 } ,
2733 ] ) ;
2834}
2935
30- async function getRule ( buildOpts : BuildOptions ) {
36+ async function getLoadManifestRule ( buildOpts : BuildOptions ) {
3137 const { outputDir } = buildOpts ;
3238
3339 const baseDir = join ( outputDir , "server-functions/default" , getPackagePath ( buildOpts ) ) ;
@@ -39,10 +45,9 @@ async function getRule(buildOpts: BuildOptions) {
3945 await Promise . all (
4046 manifests . map (
4147 async ( manifest ) => `
42- if ($PATH.endsWith("${ normalizePath ( "/" + relative ( dotNextDir , manifest ) ) } ")) {
43- return ${ await readFile ( manifest , "utf-8" ) } ;
44- }
45- `
48+ if ($PATH.endsWith("${ normalizePath ( "/" + relative ( dotNextDir , manifest ) ) } ")) {
49+ return ${ await readFile ( manifest , "utf-8" ) } ;
50+ }`
4651 )
4752 )
4853 ) . join ( "\n" ) ;
@@ -62,3 +67,47 @@ function loadManifest($PATH, $$$ARGS) {
6267}` ,
6368 } satisfies RuleConfig ;
6469}
70+
71+ async function getEvalManifestRule ( buildOpts : BuildOptions ) {
72+ const { outputDir } = buildOpts ;
73+
74+ const baseDir = join ( outputDir , "server-functions/default" , getPackagePath ( buildOpts ) , ".next" ) ;
75+ const appDir = join ( baseDir , "server/app" ) ;
76+ const manifests = await glob ( join ( baseDir , "**/*_client-reference-manifest.js" ) , {
77+ windowsPathsNoEscape : true ,
78+ } ) ;
79+
80+ const returnManifests = manifests
81+ . map ( ( manifest ) => {
82+ const endsWith = normalizePath ( relative ( baseDir , manifest ) ) ;
83+ const key = normalizePath ( "/" + relative ( appDir , manifest ) ) . replace (
84+ "_client-reference-manifest.js" ,
85+ ""
86+ ) ;
87+ return `
88+ if ($PATH.endsWith("${ endsWith } ")) {
89+ require(${ JSON . stringify ( manifest ) } );
90+ return {
91+ __RSC_MANIFEST: {
92+ "${ key } ": globalThis.__RSC_MANIFEST["${ key } "],
93+ },
94+ };
95+ }` ;
96+ } )
97+ . join ( "\n" ) ;
98+
99+ return {
100+ rule : {
101+ pattern : `
102+ function evalManifest($PATH, $$$ARGS) {
103+ $$$_
104+ }` ,
105+ } ,
106+ fix : `
107+ function evalManifest($PATH, $$$ARGS) {
108+ $PATH = $PATH.replaceAll(${ JSON . stringify ( sep ) } , ${ JSON . stringify ( posix . sep ) } );
109+ ${ returnManifests }
110+ throw new Error(\`Unexpected evalManifest(\${$PATH}) call!\`);
111+ }` ,
112+ } satisfies RuleConfig ;
113+ }
0 commit comments