22// Adapted for cloudflare workers
33
44import fs from "node:fs" ;
5+ import { createRequire } from "node:module" ;
56import path from "node:path" ;
67
78import { loadMiddlewareManifest } from "@opennextjs/aws/adapters/config/util.js" ;
89import { bundleNextServer } from "@opennextjs/aws/build/bundleNextServer.js" ;
910import { compileCache } from "@opennextjs/aws/build/compileCache.js" ;
11+ import { copyAdapterFiles } from "@opennextjs/aws/build/copyAdapterFiles.js" ;
1012import { copyTracedFiles } from "@opennextjs/aws/build/copyTracedFiles.js" ;
1113import { copyMiddlewareResources , generateEdgeBundle } from "@opennextjs/aws/build/edge/createEdgeBundle.js" ;
1214import * as buildHelper from "@opennextjs/aws/build/helper.js" ;
@@ -16,7 +18,7 @@ import { applyCodePatches } from "@opennextjs/aws/build/patch/codePatcher.js";
1618import * as awsPatches from "@opennextjs/aws/build/patch/patches/index.js" ;
1719import logger from "@opennextjs/aws/logger.js" ;
1820import { minifyAll } from "@opennextjs/aws/minimize-js.js" ;
19- import type { ContentUpdater } from "@opennextjs/aws/plugins/content-updater.js" ;
21+ import { ContentUpdater } from "@opennextjs/aws/plugins/content-updater.js" ;
2022import { openNextEdgePlugins } from "@opennextjs/aws/plugins/edge.js" ;
2123import { openNextExternalMiddlewarePlugin } from "@opennextjs/aws/plugins/externalMiddleware.js" ;
2224import { openNextReplacementPlugin } from "@opennextjs/aws/plugins/replacement.js" ;
@@ -25,11 +27,10 @@ import type { FunctionOptions, SplittedFunctionOptions } from "@opennextjs/aws/t
2527import { getCrossPlatformPathRegex } from "@opennextjs/aws/utils/regex.js" ;
2628import type { Plugin } from "esbuild" ;
2729
28- import { getOpenNextConfig } from "../../../api/config .js" ;
30+ import type { BuildCompleteCtx } from "../../adapter .js" ;
2931import { patchResRevalidate } from "../patches/plugins/res-revalidate.js" ;
3032import { patchUseCacheIO } from "../patches/plugins/use-cache.js" ;
3133import { normalizePath } from "../utils/index.js" ;
32- import { copyWorkerdPackages } from "../utils/workerd.js" ;
3334
3435interface CodeCustomization {
3536 // These patches are meant to apply on user and next generated code
@@ -41,7 +42,9 @@ interface CodeCustomization {
4142
4243export async function createServerBundle (
4344 options : buildHelper . BuildOptions ,
44- codeCustomization ?: CodeCustomization
45+ codeCustomization ?: CodeCustomization ,
46+ /* TODO(vicb): optional to be backward compatible */
47+ buildCtx ?: BuildCompleteCtx
4548) {
4649 const { config } = options ;
4750 const foundRoutes = new Set < string > ( ) ;
@@ -60,7 +63,7 @@ export async function createServerBundle(
6063 if ( fnOptions . runtime === "edge" ) {
6164 await generateEdgeBundle ( name , options , fnOptions ) ;
6265 } else {
63- await generateBundle ( name , options , fnOptions , codeCustomization ) ;
66+ await generateBundle ( name , options , fnOptions , codeCustomization , buildCtx ) ;
6467 }
6568 } ) ;
6669
@@ -112,23 +115,32 @@ export async function createServerBundle(
112115 }
113116
114117 // Generate default function
115- await generateBundle ( "default" , options , {
116- ...defaultFn ,
117- // @ts -expect-error - Those string are RouteTemplate
118- routes : Array . from ( remainingRoutes ) ,
119- patterns : [ "*" ] ,
120- } ) ;
118+ await generateBundle (
119+ "default" ,
120+ options ,
121+ {
122+ ...defaultFn ,
123+ // @ts -expect-error - Those string are RouteTemplate
124+ routes : Array . from ( remainingRoutes ) ,
125+ patterns : [ "*" ] ,
126+ } ,
127+ codeCustomization ,
128+ buildCtx
129+ ) ;
121130}
122131
123132async function generateBundle (
124133 name : string ,
125134 options : buildHelper . BuildOptions ,
126135 fnOptions : SplittedFunctionOptions ,
127- codeCustomization ?: CodeCustomization
136+ codeCustomization ?: CodeCustomization ,
137+ buildCtx ?: BuildCompleteCtx
128138) {
129139 const { appPath, appBuildOutputPath, config, outputDir, monorepoRoot } = options ;
130140 logger . info ( `Building server function: ${ name } ...` ) ;
131141
142+ const require = createRequire ( import . meta. url ) ;
143+
132144 // Create output folder
133145 const outputPath = path . join ( outputDir , "server-functions" , name ) ;
134146
@@ -181,21 +193,37 @@ async function generateBundle(
181193 // Copy env files
182194 buildHelper . copyEnvFile ( appBuildOutputPath , packagePath , outputPath ) ;
183195
184- // Copy all necessary traced files
185- const { tracedFiles, manifests, nodePackages } = await copyTracedFiles ( {
186- buildOutputPath : appBuildOutputPath ,
187- packagePath,
188- outputDir : outputPath ,
189- routes : fnOptions . routes ?? [ "app/page.tsx" ] ,
190- bundledNextServer : isBundled ,
191- } ) ;
196+ let tracedFiles : string [ ] = [ ] ;
197+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
198+ let manifests : any = { } ;
192199
193- if ( getOpenNextConfig ( options ) . cloudflare ?. useWorkerdCondition !== false ) {
194- // Next does not trace the "workerd" build condition
195- // So we need to copy the whole packages using the condition
196- await copyWorkerdPackages ( options , nodePackages ) ;
200+ // Copy all necessary traced files
201+ if ( config . dangerous ?. useAdapterOutputs ) {
202+ if ( ! buildCtx ) {
203+ throw new Error ( "should not happen" ) ;
204+ }
205+ tracedFiles = await copyAdapterFiles ( options , name , buildCtx . outputs ) ;
206+ //TODO: we should load manifests here
207+ } else {
208+ const oldTracedFileOutput = await copyTracedFiles ( {
209+ buildOutputPath : appBuildOutputPath ,
210+ packagePath,
211+ outputDir : outputPath ,
212+ routes : fnOptions . routes ?? [ "app/page.tsx" ] ,
213+ bundledNextServer : isBundled ,
214+ skipServerFiles : options . config . dangerous ?. useAdapterOutputs === true ,
215+ } ) ;
216+ tracedFiles = oldTracedFileOutput . tracedFiles ;
217+ manifests = oldTracedFileOutput . manifests ;
197218 }
198219
220+ // TODO(vicb): what should `nodePackages` be for the adapter
221+ // if (getOpenNextConfig(options).cloudflare?.useWorkerdCondition !== false) {
222+ // // Next does not trace the "workerd" build condition
223+ // // So we need to copy the whole packages using the condition
224+ // await copyWorkerdPackages(options, nodePackages);
225+ // }
226+
199227 const additionalCodePatches = codeCustomization ?. additionalCodePatches ?? [ ] ;
200228
201229 await applyCodePatches ( options , tracedFiles , manifests , [
@@ -229,9 +257,16 @@ async function generateBundle(
229257 const isAfter142 = buildHelper . compareSemver ( options . nextVersion , ">=" , "14.2" ) ;
230258 const isAfter152 = buildHelper . compareSemver ( options . nextVersion , ">=" , "15.2.0" ) ;
231259 const isAfter154 = buildHelper . compareSemver ( options . nextVersion , ">=" , "15.4.0" ) ;
260+ const useAdapterHandler = config . dangerous ?. useAdapterOutputs === true ;
232261
233262 const disableRouting = isBefore13413 || config . middleware ?. external ;
234263
264+ const updater = new ContentUpdater ( options ) ;
265+
266+ const additionalPlugins = codeCustomization ?. additionalPlugins
267+ ? codeCustomization . additionalPlugins ( updater )
268+ : [ ] ;
269+
235270 const plugins = [
236271 openNextReplacementPlugin ( {
237272 name : `requestHandlerOverride ${ name } ` ,
@@ -242,6 +277,7 @@ async function generateBundle(
242277 ...( isAfter142 ? [ "patchAsyncStorage" ] : [ ] ) ,
243278 ...( isAfter141 ? [ "appendPrefetch" ] : [ ] ) ,
244279 ...( isAfter154 ? [ ] : [ "setInitialURL" ] ) ,
280+ ...( useAdapterHandler ? [ "useRequestHandler" ] : [ "useAdapterHandler" ] ) ,
245281 ] ,
246282 } ) ,
247283 openNextReplacementPlugin ( {
@@ -253,6 +289,8 @@ async function generateBundle(
253289 ...( isAfter141 ? [ "experimentalIncrementalCacheHandler" ] : [ "stableIncrementalCache" ] ) ,
254290 ...( isAfter152 ? [ "" ] : [ "composableCache" ] ) ,
255291 ] ,
292+ replacements : [ require . resolve ( "@opennextjs/aws/core/util.adapter.js" ) ] ,
293+ entireFile : useAdapterHandler ,
256294 } ) ,
257295
258296 openNextResolvePlugin ( {
@@ -269,6 +307,9 @@ async function generateBundle(
269307 nextDir : path . join ( options . appBuildOutputPath , ".next" ) ,
270308 isInCloudflare : true ,
271309 } ) ,
310+ ...additionalPlugins ,
311+ // The content updater plugin must be the last plugin
312+ updater . plugin ,
272313 ] ;
273314
274315 const outfileExt = fnOptions . runtime === "deno" ? "ts" : "mjs" ;
0 commit comments