1- import { cp , mkdir , writeFile } from 'node:fs/promises'
1+ import { cp , mkdir , readFile , writeFile } from 'node:fs/promises'
22import { join , relative } from 'node:path/posix'
33
44import type { InSourceConfig } from '@netlify/zip-it-and-ship-it/dist/runtimes/node/in_source_config/index.js'
@@ -41,7 +41,7 @@ export async function onBuildComplete(
4141 netlifyAdapterContext : NetlifyAdapterContext ,
4242) {
4343 const requiredFiles = new Set < string > ( )
44- const pathnameToEntry : Record < string , string > = { }
44+ const { isrGroups , endpoints } = netlifyAdapterContext . preparedOutputs
4545
4646 for ( const outputs of [
4747 nextAdapterContext . outputs . pages ,
@@ -59,31 +59,59 @@ export async function onBuildComplete(
5959 }
6060
6161 requiredFiles . add ( output . filePath )
62- pathnameToEntry [ normalizeIndex ( output . pathname ) ] = relative (
63- nextAdapterContext . repoRoot ,
64- output . filePath ,
65- )
62+ endpoints [ normalizeIndex ( output . pathname ) ] = {
63+ entry : relative ( nextAdapterContext . repoRoot , output . filePath ) ,
64+ id : normalizeIndex ( output . pathname ) ,
65+ type : 'function' ,
66+ }
6667 }
6768 }
6869
6970 for ( const prerender of nextAdapterContext . outputs . prerenders ) {
7071 const normalizedPathname = normalizeIndex ( prerender . pathname )
7172 const normalizedParentOutputId = normalizeIndex ( prerender . parentOutputId )
7273
73- if ( normalizedPathname in pathnameToEntry ) {
74- // console.log('Skipping prerender, already have route:', normalizedPathname)
75- } else if ( normalizedParentOutputId in pathnameToEntry ) {
76- // if we don't have routing for this route yet, add it
77- // console.log('prerender mapping', {
78- // from: normalizedPathname,
79- // to: normalizedParentOutputId,
80- // })
81- pathnameToEntry [ normalizedPathname ] = pathnameToEntry [ normalizedParentOutputId ]
74+ const existingEntryForParent = endpoints [ normalizedParentOutputId ]
75+
76+ if ( existingEntryForParent ) {
77+ endpoints [ normalizedPathname ] = {
78+ ...existingEntryForParent ,
79+ id : normalizedPathname ,
80+ type : 'isr' ,
81+ isrGroup : prerender . groupId ,
82+ }
83+
84+ if ( ! isrGroups [ prerender . groupId ] ) {
85+ isrGroups [ prerender . groupId ] = [ ]
86+ }
87+ const isrGroup : ( typeof isrGroups ) [ number ] [ number ] = {
88+ pathname : normalizedPathname ,
89+ queryParams : prerender . config . allowQuery ?? [ ] ,
90+ }
91+
92+ if ( prerender . fallback ) {
93+ isrGroup . fallback = {
94+ content : await readFile ( prerender . fallback . filePath , 'utf-8' ) ,
95+ status : prerender . fallback . initialStatus ,
96+ headers : prerender . fallback . initialHeaders
97+ ? Object . fromEntries (
98+ Object . entries ( prerender . fallback . initialHeaders ) . map ( ( [ key , value ] ) => [
99+ key ,
100+ Array . isArray ( value ) ? value . join ( ',' ) : value ,
101+ ] ) ,
102+ )
103+ : undefined ,
104+ expiration : prerender . fallback . initialExpiration ,
105+ revalidate : prerender . fallback . initialRevalidate ,
106+ }
107+ }
108+
109+ isrGroups [ prerender . groupId ] . push ( isrGroup )
82110 } else {
83- // console.warn('Could not find parent output for prerender:', {
84- // pathname: normalizedPathname,
85- // parentOutputId: normalizedParentOutputId,
86- // })
111+ console . warn ( 'Could not find parent output for prerender:' , {
112+ pathname : normalizedPathname ,
113+ parentOutputId : normalizedParentOutputId ,
114+ } )
87115 }
88116 }
89117
@@ -99,12 +127,14 @@ export async function onBuildComplete(
99127 )
100128 }
101129
102- // copy needed runtime files
103-
104130 await copyRuntime ( join ( PAGES_AND_APP_FUNCTION_DIR , RUNTIME_DIR ) )
105131
132+ const normalizedPathsForFunctionConfig = Object . keys ( endpoints ) . map ( ( pathname ) =>
133+ pathname . toLowerCase ( ) ,
134+ )
135+
106136 const functionConfig = {
107- path : Object . keys ( pathnameToEntry ) . map ( ( pathname ) => pathname . toLowerCase ( ) ) ,
137+ path : normalizedPathsForFunctionConfig ,
108138 nodeBundler : 'none' ,
109139 includedFiles : [ '**' ] ,
110140 generator : GENERATOR ,
@@ -113,45 +143,18 @@ export async function onBuildComplete(
113143
114144 // generate needed runtime files
115145 const entrypoint = /* javascript */ `
116- import { AsyncLocalStorage } from 'node:async_hooks'
117146 import { createRequire } from 'node:module'
118- import { runNextHandler } from './${ RUNTIME_DIR } /dist/adapter/run/pages-and-app-handler.js'
119147
120- globalThis.AsyncLocalStorage = AsyncLocalStorage
148+ import { runHandler } from './ ${ RUNTIME_DIR } /dist/adapter/run/pages-and-app-handler.js'
121149
122- const RouterServerContextSymbol = Symbol.for(
123- '@next/router-server-methods'
124- );
150+ const pickedOutputs = ${ JSON . stringify ( { isrGroups, endpoints } , null , 2 ) }
125151
126- if (!globalThis[RouterServerContextSymbol]) {
127- globalThis[RouterServerContextSymbol] = {};
128- }
129-
130- globalThis[RouterServerContextSymbol]['.'] = {
131- revalidate: (...args) => {
132- console.log('revalidate called with args:', ...args);
133- }
134- }
135-
136152 const require = createRequire(import.meta.url)
137153
138- const pathnameToEntry = ${ JSON . stringify ( pathnameToEntry , null , 2 ) }
139-
140154 export default async function handler(request, context) {
141- const url = new URL(request.url)
142-
143- const entry = pathnameToEntry[url.pathname]
144- if (!entry) {
145- return new Response('Not Found', { status: 404 })
146- }
147-
148- const nextHandler = await require('./' + entry)
149-
150- if (typeof nextHandler.handler !== 'function') {
151- console.log('.handler is not a function', { nextHandler })
152- }
153-
154- return runNextHandler(request, context, nextHandler.handler)
155+ const response = await runHandler(request, context, pickedOutputs, require)
156+ console.log('Serving response with status:', response.status)
157+ return response
155158 }
156159
157160 export const config = ${ JSON . stringify ( functionConfig , null , 2 ) }
@@ -161,7 +164,7 @@ export async function onBuildComplete(
161164 entrypoint ,
162165 )
163166
164- netlifyAdapterContext . preparedOutputs . endpoints . push ( ...functionConfig . path )
167+ // netlifyAdapterContext.preparedOutputs.endpoints.push(...functionConfig.path)
165168}
166169
167170const copyRuntime = async ( handlerDirectory : string ) : Promise < void > => {
0 commit comments