1+ /* eslint-disable max-lines */
12const { Buffer } = require ( 'node:buffer' )
23const { readdirSync, existsSync } = require ( 'node:fs' )
3- const { writeFile, mkdir, readFile } = require ( 'node:fs/promises' )
4+ const { writeFile, mkdir, readFile, copyFile } = require ( 'node:fs/promises' )
45const { join, relative, sep, posix } = require ( 'node:path' )
56const process = require ( 'node:process' )
67
@@ -64,7 +65,8 @@ const getPrerenderedRoutes = async (outputDir) => {
6465 return prerenderedRoutes
6566}
6667
67- const setUpEdgeFunction = async ( { angularJson, constants, failBuild } ) => {
68+ // eslint-disable-next-line max-lines-per-function
69+ const setUpEdgeFunction = async ( { angularJson, constants, failBuild, usedEngine } ) => {
6870 const project = getProject ( angularJson )
6971 const {
7072 architect : { build } ,
@@ -108,26 +110,93 @@ const setUpEdgeFunction = async ({ angularJson, constants, failBuild }) => {
108110 globalThis.Event = globalThis.DenoEvent
109111 `
110112
111- const ssrFunction = `
113+ let ssrFunctionContent = ''
114+
115+ if ( ! usedEngine ) {
116+ // eslint-disable-next-line no-inline-comments
117+ ssrFunctionContent = /* javascript */ `
118+ import { Buffer } from "node:buffer";
119+ import { renderApplication } from "${ toPosix ( relative ( edgeFunctionDir , serverDistRoot ) ) } /render-utils.server.mjs";
120+ import bootstrap from "${ toPosix ( relative ( edgeFunctionDir , serverDistRoot ) ) } /main.server.mjs";
121+ import "./fixup-event.mjs";
122+
123+ const document = Buffer.from(${ JSON . stringify (
124+ Buffer . from ( html , 'utf-8' ) . toString ( 'base64' ) ,
125+ ) } , 'base64').toString("utf-8");
126+
127+ export default async (request, context) => {
128+ const html = await renderApplication(bootstrap, {
129+ url: request.url,
130+ document,
131+ platformProviders: [{ provide: "netlify.request", useValue: request }, { provide: "netlify.context", useValue: context }],
132+ });
133+ return new Response(html, { headers: { "content-type": "text/html" } });
134+ };
135+ `
136+ } else if ( usedEngine === 'CommonEngine' ) {
137+ const cssAssetsManifest = { }
138+ const outputBrowserDir = join ( outputDir , 'browser' )
139+ const cssFiles = getAllFilesIn ( outputBrowserDir ) . filter ( ( file ) => file . endsWith ( '.css' ) )
140+
141+ for ( const cssFile of cssFiles ) {
142+ const content = await readFile ( cssFile )
143+ cssAssetsManifest [ `${ relative ( outputBrowserDir , cssFile ) } ` ] = content . toString ( 'base64' )
144+ }
145+
146+ // eslint-disable-next-line no-inline-comments
147+ ssrFunctionContent = /* javascript */ `
148+ import { Buffer } from "node:buffer";
149+ import { dirname, relative, resolve } from 'node:path';
150+ import { fileURLToPath } from 'node:url';
151+
152+ import Handler from "${ toPosix ( relative ( edgeFunctionDir , serverDistRoot ) ) } /server.mjs";
153+ import bootstrap from "${ toPosix ( relative ( edgeFunctionDir , serverDistRoot ) ) } /main.server.mjs";
154+ import "./fixup-event.mjs";
155+
156+ const document = Buffer.from(${ JSON . stringify (
157+ Buffer . from ( html , 'utf-8' ) . toString ( 'base64' ) ,
158+ ) } , 'base64').toString("utf-8");
159+
160+ const cssAssetsManifest = ${ JSON . stringify ( cssAssetsManifest ) } ;
161+
162+ const serverDistFolder = dirname(fileURLToPath(import.meta.url));
163+ const browserDistFolder = resolve(serverDistFolder, 'browser');
164+
165+ // fs.readFile is not supported in Edge Functions, so this is a workaround for CSS inlining
166+ // that will intercept readFile attempt and if it's a CSS file, return the content from the manifest
167+ const originalReadFile = globalThis.Deno.readFile
168+ globalThis.Deno.readFile = (...args) => {
169+ if (args.length > 0 && typeof args[0] === 'string') {
170+ const relPath = relative(browserDistFolder, args[0])
171+ if (relPath in cssAssetsManifest) {
172+ return Promise.resolve(Buffer.from(cssAssetsManifest[relPath], 'base64'))
173+ }
174+ }
175+
176+ return originalReadFile.apply(globalThis.Deno, args)
177+ }
178+
179+ export default async (request, context) => {
180+ const commonEngineRenderArgs = {
181+ bootstrap: bootstrap,
182+ document,
183+ url: request.url,
184+ publicPath: browserDistFolder,
185+ platformProviders: [{ provide: "netlify.request", useValue: request }, { provide: "netlify.context", useValue: context }],
186+ }
187+ return await Handler(request, context, commonEngineRenderArgs);
188+ }
189+ `
190+ }
191+
192+ if ( ! ssrFunctionContent ) {
193+ return failBuild ( 'no ssr function body' )
194+ }
195+
196+ // eslint-disable-next-line no-inline-comments
197+ const ssrFunction = /* javascript */ `
112198 import "./polyfill.mjs";
113- import { Buffer } from "node:buffer";
114- import { renderApplication } from "${ toPosix ( relative ( edgeFunctionDir , serverDistRoot ) ) } /render-utils.server.mjs";
115- import bootstrap from "${ toPosix ( relative ( edgeFunctionDir , serverDistRoot ) ) } /main.server.mjs";
116- import "./fixup-event.mjs";
117-
118- const document = Buffer.from(${ JSON . stringify (
119- Buffer . from ( html , 'utf-8' ) . toString ( 'base64' ) ,
120- ) } , 'base64').toString("utf-8");
121-
122- export default async (request, context) => {
123- const html = await renderApplication(bootstrap, {
124- url: request.url,
125- document,
126- platformProviders: [{ provide: "netlify.request", useValue: request }, { provide: "netlify.context", useValue: context }],
127- });
128- return new Response(html, { headers: { "content-type": "text/html" } });
129- };
130-
199+ ${ ssrFunctionContent }
131200 export const config = {
132201 path: "/*",
133202 excludedPath: ${ JSON . stringify ( excludedPaths ) } ,
@@ -142,3 +211,4 @@ const setUpEdgeFunction = async ({ angularJson, constants, failBuild }) => {
142211}
143212
144213module . exports . setUpEdgeFunction = setUpEdgeFunction
214+ /* eslint-enable max-lines */
0 commit comments