import __generated from 'generated-nextjs-renderers.js' ; import { pathToRegexp } from 'path-to-regexp' ; import { FABRuntime , NO_RESPONSE_STATUS_CODE , Priority } from '@fab/core' ; const { renderers , MockExpressResponse , MockReq } = __generated ; type Renderer = { render ? : Function ; default ? : Function ; } ; async function invokeRenderer ( renderer , request , route , protocol ) { try { const local_req = new MockReq ( { url : route , method : request . method , headers : request . headers , connection : { encrypted : protocol === 'https' , } , body : request . body , } ) ; const response = new MockExpressResponse ( { request : local_req , } ) ; console . log ( { renderer } ) ; if ( typeof renderer . render === 'function' ) { await renderer . render ( local_req , response ) ; } else if ( typeof renderer . default === 'function' ) { await renderer . default ( local_req , response ) ; } else { throw new Error ( `NextJS renderer doesn't export 'render' or 'default'` ) ; } return new Response ( response . _getString ( ) , { status : response . statusCode , headers : response . _headers , } ) ; } catch ( e ) { console . error ( e ) ; return new Response ( `ERROR: NextJS renderer crashed\n${ e }` , { status : 500 } ) ; } } export default function InputNextJsRuntime ( { Router } ) { const pathRenderers = { } ; const regexpRenderers = [ ] ; let errorRenderer ; Object . keys ( renderers ) . forEach ( ( path ) => { if ( path === '/_error' ) { errorRenderer = renderers [ path ] ; } else if ( path . match ( /{:/ ) ) { regexpRenderers . push ( { path_matcher : pathToRegexp ( path ) , renderer : renderers [ path ] , } ) ; } else { pathRenderers [ path ] = renderers [ path ] ; } } ) ; const getRenderer = ( request_path ) => { const exact_match = pathRenderers [ request_path ] ; if ( exact_match ) return exact_match ; for ( const { path_matcher , renderer } of regexpRenderers ) { if ( path_matcher . exec ( request_path ) ) return renderer ; } return undefined ; } ; Router . onAll ( async function responder ( { request , url } ) { const { pathname , protocol } = url ; const renderer = pathname === '/' ? getRenderer ( '/index' ) : getRenderer ( pathname ) ; if ( renderer ) { return await invokeRenderer ( renderer , request , pathname , protocol ) ; } if ( ! errorRenderer ) return undefined ; return { async interceptResponse ( response ) { return response . status === NO_RESPONSE_STATUS_CODE ? await invokeRenderer ( errorRenderer as Renderer , request , pathname , protocol ) : response ; } , } ; } , Priority . LATER ) ; }