@angular/ssr 19.0.0-next.9 → 19.0.0-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/node.mjs +2 -2
- package/fesm2022/node.mjs.map +1 -1
- package/fesm2022/ssr.mjs +131 -126
- package/fesm2022/ssr.mjs.map +1 -1
- package/fesm2022/tokens.mjs +20 -0
- package/fesm2022/tokens.mjs.map +1 -0
- package/index.d.ts +10 -29
- package/package.json +12 -7
- package/schematics/ng-add/schema.d.ts +5 -0
- package/schematics/ng-add/schema.json +4 -0
- package/third_party/{critters → beasties}/THIRD_PARTY_LICENSES.txt +221 -71
- package/third_party/{critters → beasties}/index.d.ts +1 -1
- package/third_party/beasties/index.js +11819 -0
- package/third_party/beasties/index.js.map +1 -0
- package/tokens/index.d.ts +21 -0
- package/third_party/critters/index.js +0 -13160
- package/third_party/critters/index.js.map +0 -7
package/fesm2022/node.mjs
CHANGED
|
@@ -9,7 +9,7 @@ import { argv } from 'node:process';
|
|
|
9
9
|
class CommonEngineInlineCriticalCssProcessor {
|
|
10
10
|
resourceCache = new Map();
|
|
11
11
|
async process(html, outputPath) {
|
|
12
|
-
const
|
|
12
|
+
const beasties = new _InlineCriticalCssProcessor(async (path) => {
|
|
13
13
|
let resourceContent = this.resourceCache.get(path);
|
|
14
14
|
if (resourceContent === undefined) {
|
|
15
15
|
resourceContent = await readFile(path, 'utf-8');
|
|
@@ -17,7 +17,7 @@ class CommonEngineInlineCriticalCssProcessor {
|
|
|
17
17
|
}
|
|
18
18
|
return resourceContent;
|
|
19
19
|
}, outputPath);
|
|
20
|
-
return
|
|
20
|
+
return beasties.process(html);
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
23
|
|
package/fesm2022/node.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node.mjs","sources":["../../../../../../k8-fastbuild-ST-70f2edae98f4/bin/packages/angular/ssr/node/src/common-engine/inline-css-processor.mjs","../../../../../../k8-fastbuild-ST-70f2edae98f4/bin/packages/angular/ssr/node/src/common-engine/peformance-profiler.mjs","../../../../../../k8-fastbuild-ST-70f2edae98f4/bin/packages/angular/ssr/node/src/common-engine/common-engine.mjs","../../../../../../k8-fastbuild-ST-70f2edae98f4/bin/packages/angular/ssr/node/src/request.mjs","../../../../../../k8-fastbuild-ST-70f2edae98f4/bin/packages/angular/ssr/node/src/app-engine.mjs","../../../../../../k8-fastbuild-ST-70f2edae98f4/bin/packages/angular/ssr/node/src/handler.mjs","../../../../../../k8-fastbuild-ST-70f2edae98f4/bin/packages/angular/ssr/node/src/response.mjs","../../../../../../k8-fastbuild-ST-70f2edae98f4/bin/packages/angular/ssr/node/src/module.mjs"],"sourcesContent":["/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\nimport { ɵInlineCriticalCssProcessor as InlineCriticalCssProcessor } from '@angular/ssr';\nimport { readFile } from 'node:fs/promises';\nexport class CommonEngineInlineCriticalCssProcessor {\n resourceCache = new Map();\n async process(html, outputPath) {\n const critters = new InlineCriticalCssProcessor(async (path) => {\n let resourceContent = this.resourceCache.get(path);\n if (resourceContent === undefined) {\n resourceContent = await readFile(path, 'utf-8');\n this.resourceCache.set(path, resourceContent);\n }\n return resourceContent;\n }, outputPath);\n return critters.process(html);\n }\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\nconst PERFORMANCE_MARK_PREFIX = '🅰️';\nexport function printPerformanceLogs() {\n let maxWordLength = 0;\n const benchmarks = [];\n for (const { name, duration } of performance.getEntriesByType('measure')) {\n if (!name.startsWith(PERFORMANCE_MARK_PREFIX)) {\n continue;\n }\n // `🅰️:Retrieve SSG Page` -> `Retrieve SSG Page:`\n const step = name.slice(PERFORMANCE_MARK_PREFIX.length + 1) + ':';\n if (step.length > maxWordLength) {\n maxWordLength = step.length;\n }\n benchmarks.push([step, `${duration.toFixed(1)}ms`]);\n performance.clearMeasures(name);\n }\n /* eslint-disable no-console */\n console.log('********** Performance results **********');\n for (const [step, value] of benchmarks) {\n const spaces = maxWordLength - step.length + 5;\n console.log(step + ' '.repeat(spaces) + value);\n }\n console.log('*****************************************');\n /* eslint-enable no-console */\n}\nexport async function runMethodAndMeasurePerf(label, asyncMethod) {\n const labelName = `${PERFORMANCE_MARK_PREFIX}:${label}`;\n const startLabel = `start:${labelName}`;\n const endLabel = `end:${labelName}`;\n try {\n performance.mark(startLabel);\n return await asyncMethod();\n }\n finally {\n performance.mark(endLabel);\n performance.measure(labelName, startLabel, endLabel);\n performance.clearMarks(startLabel);\n performance.clearMarks(endLabel);\n }\n}\nexport function noopRunMethodAndMeasurePerf(label, asyncMethod) {\n return asyncMethod();\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\nimport { renderApplication, renderModule, ɵSERVER_CONTEXT } from '@angular/platform-server';\nimport * as fs from 'node:fs';\nimport { dirname, join, normalize, resolve } from 'node:path';\nimport { URL } from 'node:url';\nimport { CommonEngineInlineCriticalCssProcessor } from './inline-css-processor';\nimport { noopRunMethodAndMeasurePerf, printPerformanceLogs, runMethodAndMeasurePerf, } from './peformance-profiler';\nconst SSG_MARKER_REGEXP = /ng-server-context=[\"']\\w*\\|?ssg\\|?\\w*[\"']/;\n/**\n * A common engine to use to server render an application.\n */\nexport class CommonEngine {\n options;\n templateCache = new Map();\n inlineCriticalCssProcessor = new CommonEngineInlineCriticalCssProcessor();\n pageIsSSG = new Map();\n constructor(options) {\n this.options = options;\n }\n /**\n * Render an HTML document for a specific URL with specified\n * render options\n */\n async render(opts) {\n const enablePerformanceProfiler = this.options?.enablePerformanceProfiler;\n const runMethod = enablePerformanceProfiler\n ? runMethodAndMeasurePerf\n : noopRunMethodAndMeasurePerf;\n let html = await runMethod('Retrieve SSG Page', () => this.retrieveSSGPage(opts));\n if (html === undefined) {\n html = await runMethod('Render Page', () => this.renderApplication(opts));\n if (opts.inlineCriticalCss !== false) {\n const content = await runMethod('Inline Critical CSS', () => \n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n this.inlineCriticalCss(html, opts));\n html = content;\n }\n }\n if (enablePerformanceProfiler) {\n printPerformanceLogs();\n }\n return html;\n }\n inlineCriticalCss(html, opts) {\n const outputPath = opts.publicPath ?? (opts.documentFilePath ? dirname(opts.documentFilePath) : '');\n return this.inlineCriticalCssProcessor.process(html, outputPath);\n }\n async retrieveSSGPage(opts) {\n const { publicPath, documentFilePath, url } = opts;\n if (!publicPath || !documentFilePath || url === undefined) {\n return undefined;\n }\n const { pathname } = new URL(url, 'resolve://');\n // Do not use `resolve` here as otherwise it can lead to path traversal vulnerability.\n // See: https://portswigger.net/web-security/file-path-traversal\n const pagePath = join(publicPath, pathname, 'index.html');\n if (this.pageIsSSG.get(pagePath)) {\n // Serve pre-rendered page.\n return fs.promises.readFile(pagePath, 'utf-8');\n }\n if (!pagePath.startsWith(normalize(publicPath))) {\n // Potential path traversal detected.\n return undefined;\n }\n if (pagePath === resolve(documentFilePath) || !(await exists(pagePath))) {\n // View matches with prerender path or file does not exist.\n this.pageIsSSG.set(pagePath, false);\n return undefined;\n }\n // Static file exists.\n const content = await fs.promises.readFile(pagePath, 'utf-8');\n const isSSG = SSG_MARKER_REGEXP.test(content);\n this.pageIsSSG.set(pagePath, isSSG);\n return isSSG ? content : undefined;\n }\n async renderApplication(opts) {\n const moduleOrFactory = this.options?.bootstrap ?? opts.bootstrap;\n if (!moduleOrFactory) {\n throw new Error('A module or bootstrap option must be provided.');\n }\n const extraProviders = [\n { provide: ɵSERVER_CONTEXT, useValue: 'ssr' },\n ...(opts.providers ?? []),\n ...(this.options?.providers ?? []),\n ];\n let document = opts.document;\n if (!document && opts.documentFilePath) {\n document = await this.getDocument(opts.documentFilePath);\n }\n const commonRenderingOptions = {\n url: opts.url,\n document,\n };\n return isBootstrapFn(moduleOrFactory)\n ? renderApplication(moduleOrFactory, {\n platformProviders: extraProviders,\n ...commonRenderingOptions,\n })\n : renderModule(moduleOrFactory, { extraProviders, ...commonRenderingOptions });\n }\n /** Retrieve the document from the cache or the filesystem */\n async getDocument(filePath) {\n let doc = this.templateCache.get(filePath);\n if (!doc) {\n doc = await fs.promises.readFile(filePath, 'utf-8');\n this.templateCache.set(filePath, doc);\n }\n return doc;\n }\n}\nasync function exists(path) {\n try {\n await fs.promises.access(path, fs.constants.F_OK);\n return true;\n }\n catch {\n return false;\n }\n}\nfunction isBootstrapFn(value) {\n // We can differentiate between a module and a bootstrap function by reading compiler-generated `ɵmod` static property:\n return typeof value === 'function' && !('ɵmod' in value);\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n/**\n * Converts a Node.js `IncomingMessage` into a Web Standard `Request`.\n *\n * @param nodeRequest - The Node.js `IncomingMessage` object to convert.\n * @returns A Web Standard `Request` object.\n * @developerPreview\n */\nexport function createWebRequestFromNodeRequest(nodeRequest) {\n const { headers, method = 'GET' } = nodeRequest;\n const withBody = method !== 'GET' && method !== 'HEAD';\n return new Request(createRequestUrl(nodeRequest), {\n method,\n headers: createRequestHeaders(headers),\n body: withBody ? nodeRequest : undefined,\n duplex: withBody ? 'half' : undefined,\n });\n}\n/**\n * Creates a `Headers` object from Node.js `IncomingHttpHeaders`.\n *\n * @param nodeHeaders - The Node.js `IncomingHttpHeaders` object to convert.\n * @returns A `Headers` object containing the converted headers.\n */\nfunction createRequestHeaders(nodeHeaders) {\n const headers = new Headers();\n for (const [name, value] of Object.entries(nodeHeaders)) {\n if (typeof value === 'string') {\n headers.append(name, value);\n }\n else if (Array.isArray(value)) {\n for (const item of value) {\n headers.append(name, item);\n }\n }\n }\n return headers;\n}\n/**\n * Creates a `URL` object from a Node.js `IncomingMessage`, taking into account the protocol, host, and port.\n *\n * @param nodeRequest - The Node.js `IncomingMessage` object to extract URL information from.\n * @returns A `URL` object representing the request URL.\n */\nfunction createRequestUrl(nodeRequest) {\n const { headers, socket, url = '' } = nodeRequest;\n const protocol = headers['x-forwarded-proto'] ?? ('encrypted' in socket && socket.encrypted ? 'https' : 'http');\n const hostname = headers['x-forwarded-host'] ?? headers.host ?? headers[':authority'];\n const port = headers['x-forwarded-port'] ?? socket.localPort;\n if (Array.isArray(hostname)) {\n throw new Error('host value cannot be an array.');\n }\n let hostnameWithPort = hostname;\n if (port && !hostname?.includes(':')) {\n hostnameWithPort += `:${port}`;\n }\n return new URL(url, `${protocol}://${hostnameWithPort}`);\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\nimport { AngularAppEngine } from '@angular/ssr';\nimport { createWebRequestFromNodeRequest } from './request';\n/**\n * Angular server application engine.\n * Manages Angular server applications (including localized ones), handles rendering requests,\n * and optionally transforms index HTML before rendering.\n *\n * @note This class should be instantiated once and used as a singleton across the server-side\n * application to ensure consistent handling of rendering requests and resource management.\n *\n * @developerPreview\n */\nexport class AngularNodeAppEngine {\n angularAppEngine = new AngularAppEngine();\n /**\n * Renders an HTTP response based on the incoming request using the Angular server application.\n *\n * The method processes the incoming request, determines the appropriate route, and prepares the\n * rendering context to generate a response. If the request URL corresponds to a static file (excluding `/index.html`),\n * the method returns `null`.\n *\n * Example: A request to `https://www.example.com/page/index.html` will render the Angular route\n * associated with `https://www.example.com/page`.\n *\n * @param request - The incoming HTTP request object to be rendered.\n * @param requestContext - Optional additional context for the request, such as metadata or custom settings.\n * @returns A promise that resolves to a `Response` object, or `null` if the request URL is for a static file\n * (e.g., `./logo.png`) rather than an application route.\n */\n render(request, requestContext) {\n return this.angularAppEngine.render(createWebRequestFromNodeRequest(request), requestContext);\n }\n /**\n * Retrieves HTTP headers for a request associated with statically generated (SSG) pages,\n * based on the URL pathname.\n *\n * @param request - The incoming request object.\n * @returns A `Map` containing the HTTP headers as key-value pairs.\n * @note This function should be used exclusively for retrieving headers of SSG pages.\n * @example\n * ```typescript\n * const angularAppEngine = new AngularNodeAppEngine();\n *\n * app.use(express.static('dist/browser', {\n * setHeaders: (res, path) => {\n * // Retrieve headers for the current request\n * const headers = angularAppEngine.getPrerenderHeaders(res.req);\n *\n * // Apply the retrieved headers to the response\n * for (const [key, value] of headers) {\n * res.setHeader(key, value);\n * }\n * }\n }));\n * ```\n */\n getPrerenderHeaders(request) {\n return this.angularAppEngine.getPrerenderHeaders(createWebRequestFromNodeRequest(request));\n }\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n/**\n * Attaches metadata to the handler function to mark it as a special handler for Node.js environments.\n *\n * @typeParam T - The type of the handler function.\n * @param handler - The handler function to be defined and annotated.\n * @returns The same handler function passed as an argument, with metadata attached.\n *\n * @example\n * Usage in an Express application:\n * ```ts\n * const app = express();\n * export default createNodeRequestHandler(app);\n * ```\n *\n * @example\n * Usage in a Hono application:\n * ```ts\n * const app = new Hono();\n * export default createNodeRequestHandler(async (req, res, next) => {\n * try {\n * const webRes = await app.fetch(createWebRequestFromNodeRequest(req));\n * if (webRes) {\n * await writeResponseToNodeResponse(webRes, res);\n * } else {\n * next();\n * }\n * } catch (error) {\n * next(error);\n * }\n * }));\n * ```\n *\n * @example\n * Usage in a Fastify application:\n * ```ts\n * const app = Fastify();\n * export default createNodeRequestHandler(async (req, res) => {\n * await app.ready();\n * app.server.emit('request', req, res);\n * res.send('Hello from Fastify with Node Next Handler!');\n * }));\n * ```\n * @developerPreview\n */\nexport function createNodeRequestHandler(handler) {\n handler['__ng_node_request_handler__'] = true;\n return handler;\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n/**\n * Streams a web-standard `Response` into a Node.js `ServerResponse`.\n *\n * @param source - The web-standard `Response` object to stream from.\n * @param destination - The Node.js `ServerResponse` object to stream into.\n * @returns A promise that resolves once the streaming operation is complete.\n * @developerPreview\n */\nexport async function writeResponseToNodeResponse(source, destination) {\n const { status, headers, body } = source;\n destination.statusCode = status;\n let cookieHeaderSet = false;\n for (const [name, value] of headers.entries()) {\n if (name === 'set-cookie') {\n if (cookieHeaderSet) {\n continue;\n }\n // Sets the 'set-cookie' header only once to ensure it is correctly applied.\n // Concatenating 'set-cookie' values can lead to incorrect behavior, so we use a single value from `headers.getSetCookie()`.\n destination.setHeader(name, headers.getSetCookie());\n cookieHeaderSet = true;\n }\n else {\n destination.setHeader(name, value);\n }\n }\n if (!body) {\n destination.end();\n return;\n }\n try {\n const reader = body.getReader();\n destination.on('close', () => {\n reader.cancel().catch((error) => {\n // eslint-disable-next-line no-console\n console.error(`An error occurred while writing the response body for: ${destination.req.url}.`, error);\n });\n });\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const { done, value } = await reader.read();\n if (done) {\n destination.end();\n break;\n }\n destination.write(value);\n }\n }\n catch {\n destination.end('Internal server error.');\n }\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\nimport { argv } from 'node:process';\nimport { fileURLToPath } from 'node:url';\n/**\n * Determines whether the provided URL represents the main entry point module.\n *\n * This function checks if the provided URL corresponds to the main ESM module being executed directly.\n * It's useful for conditionally executing code that should only run when a module is the entry point,\n * such as starting a server or initializing an application.\n *\n * It performs two key checks:\n * 1. Verifies if the URL starts with 'file:', ensuring it is a local file.\n * 2. Compares the URL's resolved file path with the first command-line argument (`process.argv[1]`),\n * which points to the file being executed.\n *\n * @param url The URL of the module to check. This should typically be `import.meta.url`.\n * @returns `true` if the provided URL represents the main entry point, otherwise `false`.\n * @developerPreview\n */\nexport function isMainModule(url) {\n return url.startsWith('file:') && argv[1] === fileURLToPath(url);\n}\n"],"names":["InlineCriticalCssProcessor","URL","ɵSERVER_CONTEXT"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"node.mjs","sources":["../../../../../../darwin_arm64-fastbuild-ST-70f2edae98f4/bin/packages/angular/ssr/node/src/common-engine/inline-css-processor.mjs","../../../../../../darwin_arm64-fastbuild-ST-70f2edae98f4/bin/packages/angular/ssr/node/src/common-engine/peformance-profiler.mjs","../../../../../../darwin_arm64-fastbuild-ST-70f2edae98f4/bin/packages/angular/ssr/node/src/common-engine/common-engine.mjs","../../../../../../darwin_arm64-fastbuild-ST-70f2edae98f4/bin/packages/angular/ssr/node/src/request.mjs","../../../../../../darwin_arm64-fastbuild-ST-70f2edae98f4/bin/packages/angular/ssr/node/src/app-engine.mjs","../../../../../../darwin_arm64-fastbuild-ST-70f2edae98f4/bin/packages/angular/ssr/node/src/handler.mjs","../../../../../../darwin_arm64-fastbuild-ST-70f2edae98f4/bin/packages/angular/ssr/node/src/response.mjs","../../../../../../darwin_arm64-fastbuild-ST-70f2edae98f4/bin/packages/angular/ssr/node/src/module.mjs"],"sourcesContent":["/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\nimport { ɵInlineCriticalCssProcessor as InlineCriticalCssProcessor } from '@angular/ssr';\nimport { readFile } from 'node:fs/promises';\nexport class CommonEngineInlineCriticalCssProcessor {\n resourceCache = new Map();\n async process(html, outputPath) {\n const beasties = new InlineCriticalCssProcessor(async (path) => {\n let resourceContent = this.resourceCache.get(path);\n if (resourceContent === undefined) {\n resourceContent = await readFile(path, 'utf-8');\n this.resourceCache.set(path, resourceContent);\n }\n return resourceContent;\n }, outputPath);\n return beasties.process(html);\n }\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\nconst PERFORMANCE_MARK_PREFIX = '🅰️';\nexport function printPerformanceLogs() {\n let maxWordLength = 0;\n const benchmarks = [];\n for (const { name, duration } of performance.getEntriesByType('measure')) {\n if (!name.startsWith(PERFORMANCE_MARK_PREFIX)) {\n continue;\n }\n // `🅰️:Retrieve SSG Page` -> `Retrieve SSG Page:`\n const step = name.slice(PERFORMANCE_MARK_PREFIX.length + 1) + ':';\n if (step.length > maxWordLength) {\n maxWordLength = step.length;\n }\n benchmarks.push([step, `${duration.toFixed(1)}ms`]);\n performance.clearMeasures(name);\n }\n /* eslint-disable no-console */\n console.log('********** Performance results **********');\n for (const [step, value] of benchmarks) {\n const spaces = maxWordLength - step.length + 5;\n console.log(step + ' '.repeat(spaces) + value);\n }\n console.log('*****************************************');\n /* eslint-enable no-console */\n}\nexport async function runMethodAndMeasurePerf(label, asyncMethod) {\n const labelName = `${PERFORMANCE_MARK_PREFIX}:${label}`;\n const startLabel = `start:${labelName}`;\n const endLabel = `end:${labelName}`;\n try {\n performance.mark(startLabel);\n return await asyncMethod();\n }\n finally {\n performance.mark(endLabel);\n performance.measure(labelName, startLabel, endLabel);\n performance.clearMarks(startLabel);\n performance.clearMarks(endLabel);\n }\n}\nexport function noopRunMethodAndMeasurePerf(label, asyncMethod) {\n return asyncMethod();\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\nimport { renderApplication, renderModule, ɵSERVER_CONTEXT } from '@angular/platform-server';\nimport * as fs from 'node:fs';\nimport { dirname, join, normalize, resolve } from 'node:path';\nimport { URL } from 'node:url';\nimport { CommonEngineInlineCriticalCssProcessor } from './inline-css-processor';\nimport { noopRunMethodAndMeasurePerf, printPerformanceLogs, runMethodAndMeasurePerf, } from './peformance-profiler';\nconst SSG_MARKER_REGEXP = /ng-server-context=[\"']\\w*\\|?ssg\\|?\\w*[\"']/;\n/**\n * A common engine to use to server render an application.\n */\nexport class CommonEngine {\n options;\n templateCache = new Map();\n inlineCriticalCssProcessor = new CommonEngineInlineCriticalCssProcessor();\n pageIsSSG = new Map();\n constructor(options) {\n this.options = options;\n }\n /**\n * Render an HTML document for a specific URL with specified\n * render options\n */\n async render(opts) {\n const enablePerformanceProfiler = this.options?.enablePerformanceProfiler;\n const runMethod = enablePerformanceProfiler\n ? runMethodAndMeasurePerf\n : noopRunMethodAndMeasurePerf;\n let html = await runMethod('Retrieve SSG Page', () => this.retrieveSSGPage(opts));\n if (html === undefined) {\n html = await runMethod('Render Page', () => this.renderApplication(opts));\n if (opts.inlineCriticalCss !== false) {\n const content = await runMethod('Inline Critical CSS', () => \n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n this.inlineCriticalCss(html, opts));\n html = content;\n }\n }\n if (enablePerformanceProfiler) {\n printPerformanceLogs();\n }\n return html;\n }\n inlineCriticalCss(html, opts) {\n const outputPath = opts.publicPath ?? (opts.documentFilePath ? dirname(opts.documentFilePath) : '');\n return this.inlineCriticalCssProcessor.process(html, outputPath);\n }\n async retrieveSSGPage(opts) {\n const { publicPath, documentFilePath, url } = opts;\n if (!publicPath || !documentFilePath || url === undefined) {\n return undefined;\n }\n const { pathname } = new URL(url, 'resolve://');\n // Do not use `resolve` here as otherwise it can lead to path traversal vulnerability.\n // See: https://portswigger.net/web-security/file-path-traversal\n const pagePath = join(publicPath, pathname, 'index.html');\n if (this.pageIsSSG.get(pagePath)) {\n // Serve pre-rendered page.\n return fs.promises.readFile(pagePath, 'utf-8');\n }\n if (!pagePath.startsWith(normalize(publicPath))) {\n // Potential path traversal detected.\n return undefined;\n }\n if (pagePath === resolve(documentFilePath) || !(await exists(pagePath))) {\n // View matches with prerender path or file does not exist.\n this.pageIsSSG.set(pagePath, false);\n return undefined;\n }\n // Static file exists.\n const content = await fs.promises.readFile(pagePath, 'utf-8');\n const isSSG = SSG_MARKER_REGEXP.test(content);\n this.pageIsSSG.set(pagePath, isSSG);\n return isSSG ? content : undefined;\n }\n async renderApplication(opts) {\n const moduleOrFactory = this.options?.bootstrap ?? opts.bootstrap;\n if (!moduleOrFactory) {\n throw new Error('A module or bootstrap option must be provided.');\n }\n const extraProviders = [\n { provide: ɵSERVER_CONTEXT, useValue: 'ssr' },\n ...(opts.providers ?? []),\n ...(this.options?.providers ?? []),\n ];\n let document = opts.document;\n if (!document && opts.documentFilePath) {\n document = await this.getDocument(opts.documentFilePath);\n }\n const commonRenderingOptions = {\n url: opts.url,\n document,\n };\n return isBootstrapFn(moduleOrFactory)\n ? renderApplication(moduleOrFactory, {\n platformProviders: extraProviders,\n ...commonRenderingOptions,\n })\n : renderModule(moduleOrFactory, { extraProviders, ...commonRenderingOptions });\n }\n /** Retrieve the document from the cache or the filesystem */\n async getDocument(filePath) {\n let doc = this.templateCache.get(filePath);\n if (!doc) {\n doc = await fs.promises.readFile(filePath, 'utf-8');\n this.templateCache.set(filePath, doc);\n }\n return doc;\n }\n}\nasync function exists(path) {\n try {\n await fs.promises.access(path, fs.constants.F_OK);\n return true;\n }\n catch {\n return false;\n }\n}\nfunction isBootstrapFn(value) {\n // We can differentiate between a module and a bootstrap function by reading compiler-generated `ɵmod` static property:\n return typeof value === 'function' && !('ɵmod' in value);\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n/**\n * Converts a Node.js `IncomingMessage` into a Web Standard `Request`.\n *\n * @param nodeRequest - The Node.js `IncomingMessage` object to convert.\n * @returns A Web Standard `Request` object.\n * @developerPreview\n */\nexport function createWebRequestFromNodeRequest(nodeRequest) {\n const { headers, method = 'GET' } = nodeRequest;\n const withBody = method !== 'GET' && method !== 'HEAD';\n return new Request(createRequestUrl(nodeRequest), {\n method,\n headers: createRequestHeaders(headers),\n body: withBody ? nodeRequest : undefined,\n duplex: withBody ? 'half' : undefined,\n });\n}\n/**\n * Creates a `Headers` object from Node.js `IncomingHttpHeaders`.\n *\n * @param nodeHeaders - The Node.js `IncomingHttpHeaders` object to convert.\n * @returns A `Headers` object containing the converted headers.\n */\nfunction createRequestHeaders(nodeHeaders) {\n const headers = new Headers();\n for (const [name, value] of Object.entries(nodeHeaders)) {\n if (typeof value === 'string') {\n headers.append(name, value);\n }\n else if (Array.isArray(value)) {\n for (const item of value) {\n headers.append(name, item);\n }\n }\n }\n return headers;\n}\n/**\n * Creates a `URL` object from a Node.js `IncomingMessage`, taking into account the protocol, host, and port.\n *\n * @param nodeRequest - The Node.js `IncomingMessage` object to extract URL information from.\n * @returns A `URL` object representing the request URL.\n */\nfunction createRequestUrl(nodeRequest) {\n const { headers, socket, url = '' } = nodeRequest;\n const protocol = headers['x-forwarded-proto'] ?? ('encrypted' in socket && socket.encrypted ? 'https' : 'http');\n const hostname = headers['x-forwarded-host'] ?? headers.host ?? headers[':authority'];\n const port = headers['x-forwarded-port'] ?? socket.localPort;\n if (Array.isArray(hostname)) {\n throw new Error('host value cannot be an array.');\n }\n let hostnameWithPort = hostname;\n if (port && !hostname?.includes(':')) {\n hostnameWithPort += `:${port}`;\n }\n return new URL(url, `${protocol}://${hostnameWithPort}`);\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\nimport { AngularAppEngine } from '@angular/ssr';\nimport { createWebRequestFromNodeRequest } from './request';\n/**\n * Angular server application engine.\n * Manages Angular server applications (including localized ones), handles rendering requests,\n * and optionally transforms index HTML before rendering.\n *\n * @note This class should be instantiated once and used as a singleton across the server-side\n * application to ensure consistent handling of rendering requests and resource management.\n *\n * @developerPreview\n */\nexport class AngularNodeAppEngine {\n angularAppEngine = new AngularAppEngine();\n /**\n * Renders an HTTP response based on the incoming request using the Angular server application.\n *\n * The method processes the incoming request, determines the appropriate route, and prepares the\n * rendering context to generate a response. If the request URL corresponds to a static file (excluding `/index.html`),\n * the method returns `null`.\n *\n * Example: A request to `https://www.example.com/page/index.html` will render the Angular route\n * associated with `https://www.example.com/page`.\n *\n * @param request - The incoming HTTP request object to be rendered.\n * @param requestContext - Optional additional context for the request, such as metadata or custom settings.\n * @returns A promise that resolves to a `Response` object, or `null` if the request URL is for a static file\n * (e.g., `./logo.png`) rather than an application route.\n */\n render(request, requestContext) {\n return this.angularAppEngine.render(createWebRequestFromNodeRequest(request), requestContext);\n }\n /**\n * Retrieves HTTP headers for a request associated with statically generated (SSG) pages,\n * based on the URL pathname.\n *\n * @param request - The incoming request object.\n * @returns A `Map` containing the HTTP headers as key-value pairs.\n * @note This function should be used exclusively for retrieving headers of SSG pages.\n * @example\n * ```typescript\n * const angularAppEngine = new AngularNodeAppEngine();\n *\n * app.use(express.static('dist/browser', {\n * setHeaders: (res, path) => {\n * // Retrieve headers for the current request\n * const headers = angularAppEngine.getPrerenderHeaders(res.req);\n *\n * // Apply the retrieved headers to the response\n * for (const [key, value] of headers) {\n * res.setHeader(key, value);\n * }\n * }\n }));\n * ```\n */\n getPrerenderHeaders(request) {\n return this.angularAppEngine.getPrerenderHeaders(createWebRequestFromNodeRequest(request));\n }\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n/**\n * Attaches metadata to the handler function to mark it as a special handler for Node.js environments.\n *\n * @typeParam T - The type of the handler function.\n * @param handler - The handler function to be defined and annotated.\n * @returns The same handler function passed as an argument, with metadata attached.\n *\n * @example\n * Usage in an Express application:\n * ```ts\n * const app = express();\n * export default createNodeRequestHandler(app);\n * ```\n *\n * @example\n * Usage in a Hono application:\n * ```ts\n * const app = new Hono();\n * export default createNodeRequestHandler(async (req, res, next) => {\n * try {\n * const webRes = await app.fetch(createWebRequestFromNodeRequest(req));\n * if (webRes) {\n * await writeResponseToNodeResponse(webRes, res);\n * } else {\n * next();\n * }\n * } catch (error) {\n * next(error);\n * }\n * }));\n * ```\n *\n * @example\n * Usage in a Fastify application:\n * ```ts\n * const app = Fastify();\n * export default createNodeRequestHandler(async (req, res) => {\n * await app.ready();\n * app.server.emit('request', req, res);\n * res.send('Hello from Fastify with Node Next Handler!');\n * }));\n * ```\n * @developerPreview\n */\nexport function createNodeRequestHandler(handler) {\n handler['__ng_node_request_handler__'] = true;\n return handler;\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n/**\n * Streams a web-standard `Response` into a Node.js `ServerResponse`.\n *\n * @param source - The web-standard `Response` object to stream from.\n * @param destination - The Node.js `ServerResponse` object to stream into.\n * @returns A promise that resolves once the streaming operation is complete.\n * @developerPreview\n */\nexport async function writeResponseToNodeResponse(source, destination) {\n const { status, headers, body } = source;\n destination.statusCode = status;\n let cookieHeaderSet = false;\n for (const [name, value] of headers.entries()) {\n if (name === 'set-cookie') {\n if (cookieHeaderSet) {\n continue;\n }\n // Sets the 'set-cookie' header only once to ensure it is correctly applied.\n // Concatenating 'set-cookie' values can lead to incorrect behavior, so we use a single value from `headers.getSetCookie()`.\n destination.setHeader(name, headers.getSetCookie());\n cookieHeaderSet = true;\n }\n else {\n destination.setHeader(name, value);\n }\n }\n if (!body) {\n destination.end();\n return;\n }\n try {\n const reader = body.getReader();\n destination.on('close', () => {\n reader.cancel().catch((error) => {\n // eslint-disable-next-line no-console\n console.error(`An error occurred while writing the response body for: ${destination.req.url}.`, error);\n });\n });\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const { done, value } = await reader.read();\n if (done) {\n destination.end();\n break;\n }\n destination.write(value);\n }\n }\n catch {\n destination.end('Internal server error.');\n }\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\nimport { argv } from 'node:process';\nimport { fileURLToPath } from 'node:url';\n/**\n * Determines whether the provided URL represents the main entry point module.\n *\n * This function checks if the provided URL corresponds to the main ESM module being executed directly.\n * It's useful for conditionally executing code that should only run when a module is the entry point,\n * such as starting a server or initializing an application.\n *\n * It performs two key checks:\n * 1. Verifies if the URL starts with 'file:', ensuring it is a local file.\n * 2. Compares the URL's resolved file path with the first command-line argument (`process.argv[1]`),\n * which points to the file being executed.\n *\n * @param url The URL of the module to check. This should typically be `import.meta.url`.\n * @returns `true` if the provided URL represents the main entry point, otherwise `false`.\n * @developerPreview\n */\nexport function isMainModule(url) {\n return url.startsWith('file:') && argv[1] === fileURLToPath(url);\n}\n"],"names":["InlineCriticalCssProcessor","URL","ɵSERVER_CONTEXT"],"mappings":"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,CAAC,EAAE,IAAI,CAAC,CAAC;AACtC;AACA,IAAI,OAAO,IAAI,GAAG,CAAC,GAAG,EAAE,CAAC,EAAE,QAAQ,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAC,CAAC;AAC5D;;ACtDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAM,oBAAoB,CAAC;AAClC,IAAI,gBAAgB,GAAG,IAAI,gBAAgB,EAAE;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,MAAM,CAAC,OAAO,EAAE,cAAc,EAAE;AACpC,QAAQ,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,+BAA+B,CAAC,OAAO,CAAC,EAAE,cAAc,CAAC;AACrG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,mBAAmB,CAAC,OAAO,EAAE;AACjC,QAAQ,OAAO,IAAI,CAAC,gBAAgB,CAAC,mBAAmB,CAAC,+BAA+B,CAAC,OAAO,CAAC,CAAC;AAClG;AACA;;AC3DA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,wBAAwB,CAAC,OAAO,EAAE;AAClD,IAAI,OAAO,CAAC,6BAA6B,CAAC,GAAG,IAAI;AACjD,IAAI,OAAO,OAAO;AAClB;;AC/CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,eAAe,2BAA2B,CAAC,MAAM,EAAE,WAAW,EAAE;AACvE,IAAI,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,MAAM;AAC5C,IAAI,WAAW,CAAC,UAAU,GAAG,MAAM;AACnC,IAAI,IAAI,eAAe,GAAG,KAAK;AAC/B,IAAI,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE,EAAE;AACnD,QAAQ,IAAI,IAAI,KAAK,YAAY,EAAE;AACnC,YAAY,IAAI,eAAe,EAAE;AACjC,gBAAgB;AAChB;AACA;AACA;AACA,YAAY,WAAW,CAAC,SAAS,CAAC,IAAI,EAAE,OAAO,CAAC,YAAY,EAAE,CAAC;AAC/D,YAAY,eAAe,GAAG,IAAI;AAClC;AACA,aAAa;AACb,YAAY,WAAW,CAAC,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC;AAC9C;AACA;AACA,IAAI,IAAI,CAAC,IAAI,EAAE;AACf,QAAQ,WAAW,CAAC,GAAG,EAAE;AACzB,QAAQ;AACR;AACA,IAAI,IAAI;AACR,QAAQ,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE;AACvC,QAAQ,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM;AACtC,YAAY,MAAM,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,KAAK;AAC7C;AACA,gBAAgB,OAAO,CAAC,KAAK,CAAC,CAAC,uDAAuD,EAAE,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC;AACtH,aAAa,CAAC;AACd,SAAS,CAAC;AACV;AACA,QAAQ,OAAO,IAAI,EAAE;AACrB,YAAY,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE;AACvD,YAAY,IAAI,IAAI,EAAE;AACtB,gBAAgB,WAAW,CAAC,GAAG,EAAE;AACjC,gBAAgB;AAChB;AACA,YAAY,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC;AACpC;AACA;AACA,IAAI,MAAM;AACV,QAAQ,WAAW,CAAC,GAAG,CAAC,wBAAwB,CAAC;AACjD;AACA;;ACjDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,YAAY,CAAC,GAAG,EAAE;AAClC,IAAI,OAAO,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,aAAa,CAAC,GAAG,CAAC;AACpE;;;;"}
|
package/fesm2022/ssr.mjs
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { APP_BASE_HREF, PlatformLocation } from '@angular/common';
|
|
2
|
-
import { ɵConsole as _Console, InjectionToken, makeEnvironmentProviders, runInInjectionContext,
|
|
3
|
-
import { ɵSERVER_CONTEXT as _SERVER_CONTEXT, renderModule, renderApplication,
|
|
2
|
+
import { ɵConsole as _Console, InjectionToken, makeEnvironmentProviders, runInInjectionContext, ApplicationRef, ɵwhenStable as _whenStable, Compiler, LOCALE_ID, ɵresetCompiledComponents as _resetCompiledComponents } from '@angular/core';
|
|
3
|
+
import { ɵSERVER_CONTEXT as _SERVER_CONTEXT, renderModule, renderApplication, platformServer, INITIAL_CONFIG } from '@angular/platform-server';
|
|
4
4
|
import { ɵloadChildren as _loadChildren, Router } from '@angular/router';
|
|
5
|
-
import
|
|
5
|
+
import { REQUEST, REQUEST_CONTEXT, RESPONSE_INIT } from '@angular/ssr/tokens';
|
|
6
|
+
import Beasties from '../third_party/beasties/index.js';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* Manages server-side assets.
|
|
9
10
|
*/
|
|
10
11
|
class ServerAssets {
|
|
12
|
+
manifest;
|
|
11
13
|
/**
|
|
12
14
|
* Creates an instance of ServerAsset.
|
|
13
15
|
*
|
|
@@ -48,13 +50,10 @@ class ServerAssets {
|
|
|
48
50
|
* It overrides the `log` method to suppress logs that match certain predefined messages.
|
|
49
51
|
*/
|
|
50
52
|
class Console extends _Console {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
*/
|
|
56
|
-
this.ignoredLogs = new Set(['Angular is running in development mode.']);
|
|
57
|
-
}
|
|
53
|
+
/**
|
|
54
|
+
* A set of log messages that should be ignored and not printed to the console.
|
|
55
|
+
*/
|
|
56
|
+
ignoredLogs = new Set(['Angular is running in development mode.']);
|
|
58
57
|
/**
|
|
59
58
|
* Logs a message to the console if it is not in the set of ignored messages.
|
|
60
59
|
*
|
|
@@ -367,19 +366,17 @@ function provideServerRoutesConfig(routes) {
|
|
|
367
366
|
* @typeParam AdditionalMetadata - Type of additional metadata that can be associated with route nodes.
|
|
368
367
|
*/
|
|
369
368
|
class RouteTree {
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
this.insertionIndexCounter = 0;
|
|
382
|
-
}
|
|
369
|
+
/**
|
|
370
|
+
* The root node of the route tree.
|
|
371
|
+
* All routes are stored and accessed relative to this root node.
|
|
372
|
+
*/
|
|
373
|
+
root = this.createEmptyRouteTreeNode('');
|
|
374
|
+
/**
|
|
375
|
+
* A counter that tracks the order of route insertion.
|
|
376
|
+
* This ensures that routes are matched in the order they were defined,
|
|
377
|
+
* with earlier routes taking precedence.
|
|
378
|
+
*/
|
|
379
|
+
insertionIndexCounter = 0;
|
|
383
380
|
/**
|
|
384
381
|
* Inserts a new route into the route tree.
|
|
385
382
|
* The route is broken down into segments, and each segment is added to the tree.
|
|
@@ -766,7 +763,7 @@ function buildServerConfigRouteTree(serverRoutesConfig) {
|
|
|
766
763
|
async function getRoutesFromAngularRouterConfig(bootstrap, document, url, invokeGetPrerenderParams = false, includePrerenderFallbackRoutes = true) {
|
|
767
764
|
const { protocol, host } = url;
|
|
768
765
|
// Create and initialize the Angular platform for server-side rendering.
|
|
769
|
-
const platformRef =
|
|
766
|
+
const platformRef = platformServer([
|
|
770
767
|
{
|
|
771
768
|
provide: INITIAL_CONFIG,
|
|
772
769
|
useValue: { document, url: `${protocol}//${host}/` },
|
|
@@ -775,8 +772,7 @@ async function getRoutesFromAngularRouterConfig(bootstrap, document, url, invoke
|
|
|
775
772
|
provide: _Console,
|
|
776
773
|
useFactory: () => new Console(),
|
|
777
774
|
},
|
|
778
|
-
|
|
779
|
-
])();
|
|
775
|
+
]);
|
|
780
776
|
try {
|
|
781
777
|
let applicationRef;
|
|
782
778
|
if (isNgModule(bootstrap)) {
|
|
@@ -794,22 +790,22 @@ async function getRoutesFromAngularRouterConfig(bootstrap, document, url, invoke
|
|
|
794
790
|
const errors = [];
|
|
795
791
|
const baseHref = injector.get(APP_BASE_HREF, null, { optional: true }) ??
|
|
796
792
|
injector.get(PlatformLocation).getBaseHrefFromDOM();
|
|
793
|
+
const compiler = injector.get(Compiler);
|
|
794
|
+
const serverRoutesConfig = injector.get(SERVER_ROUTES_CONFIG, null, { optional: true });
|
|
795
|
+
let serverConfigRouteTree;
|
|
796
|
+
if (serverRoutesConfig) {
|
|
797
|
+
const result = buildServerConfigRouteTree(serverRoutesConfig);
|
|
798
|
+
serverConfigRouteTree = result.serverConfigRouteTree;
|
|
799
|
+
errors.push(...result.errors);
|
|
800
|
+
}
|
|
801
|
+
if (errors.length) {
|
|
802
|
+
return {
|
|
803
|
+
baseHref,
|
|
804
|
+
routes: routesResults,
|
|
805
|
+
errors,
|
|
806
|
+
};
|
|
807
|
+
}
|
|
797
808
|
if (router.config.length) {
|
|
798
|
-
const compiler = injector.get(Compiler);
|
|
799
|
-
const serverRoutesConfig = injector.get(SERVER_ROUTES_CONFIG, null, { optional: true });
|
|
800
|
-
let serverConfigRouteTree;
|
|
801
|
-
if (serverRoutesConfig) {
|
|
802
|
-
const result = buildServerConfigRouteTree(serverRoutesConfig);
|
|
803
|
-
serverConfigRouteTree = result.serverConfigRouteTree;
|
|
804
|
-
errors.push(...result.errors);
|
|
805
|
-
}
|
|
806
|
-
if (errors.length) {
|
|
807
|
-
return {
|
|
808
|
-
baseHref,
|
|
809
|
-
routes: routesResults,
|
|
810
|
-
errors,
|
|
811
|
-
};
|
|
812
|
-
}
|
|
813
809
|
// Retrieve all routes from the Angular router configuration.
|
|
814
810
|
const traverseRoutes = traverseRoutesConfig({
|
|
815
811
|
routes: router.config,
|
|
@@ -850,7 +846,11 @@ async function getRoutesFromAngularRouterConfig(bootstrap, document, url, invoke
|
|
|
850
846
|
}
|
|
851
847
|
}
|
|
852
848
|
else {
|
|
853
|
-
|
|
849
|
+
const renderMode = serverConfigRouteTree?.match('')?.renderMode ?? RenderMode.Prerender;
|
|
850
|
+
routesResults.push({
|
|
851
|
+
route: '',
|
|
852
|
+
renderMode,
|
|
853
|
+
});
|
|
854
854
|
}
|
|
855
855
|
return {
|
|
856
856
|
baseHref,
|
|
@@ -904,13 +904,11 @@ async function extractRoutesAndCreateRouteTree(url, manifest = getAngularAppMani
|
|
|
904
904
|
* Hooks are functions that can be invoked with specific arguments to allow modifications or enhancements.
|
|
905
905
|
*/
|
|
906
906
|
class Hooks {
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
this.store = new Map();
|
|
913
|
-
}
|
|
907
|
+
/**
|
|
908
|
+
* A map of hook names to arrays of hook functions.
|
|
909
|
+
* Each hook name can have multiple associated functions, which are executed in sequence.
|
|
910
|
+
*/
|
|
911
|
+
store = new Map();
|
|
914
912
|
/**
|
|
915
913
|
* Executes all hooks associated with the specified name, passing the given argument to each hook function.
|
|
916
914
|
* The hooks are invoked sequentially, and the argument may be modified by each hook.
|
|
@@ -996,6 +994,7 @@ class Hooks {
|
|
|
996
994
|
* configuration and using it to match incoming requests to the appropriate routes.
|
|
997
995
|
*/
|
|
998
996
|
class ServerRouter {
|
|
997
|
+
routeTree;
|
|
999
998
|
/**
|
|
1000
999
|
* Creates an instance of the `ServerRouter`.
|
|
1001
1000
|
*
|
|
@@ -1061,22 +1060,6 @@ class ServerRouter {
|
|
|
1061
1060
|
}
|
|
1062
1061
|
}
|
|
1063
1062
|
|
|
1064
|
-
/**
|
|
1065
|
-
* Injection token for the current request.
|
|
1066
|
-
* @developerPreview
|
|
1067
|
-
*/
|
|
1068
|
-
const REQUEST = new InjectionToken('REQUEST');
|
|
1069
|
-
/**
|
|
1070
|
-
* Injection token for the response initialization options.
|
|
1071
|
-
* @developerPreview
|
|
1072
|
-
*/
|
|
1073
|
-
const RESPONSE_INIT = new InjectionToken('RESPONSE_INIT');
|
|
1074
|
-
/**
|
|
1075
|
-
* Injection token for additional request context.
|
|
1076
|
-
* @developerPreview
|
|
1077
|
-
*/
|
|
1078
|
-
const REQUEST_CONTEXT = new InjectionToken('REQUEST_CONTEXT');
|
|
1079
|
-
|
|
1080
1063
|
/**
|
|
1081
1064
|
* Generates a SHA-256 hash of the provided string.
|
|
1082
1065
|
*
|
|
@@ -1085,12 +1068,6 @@ const REQUEST_CONTEXT = new InjectionToken('REQUEST_CONTEXT');
|
|
|
1085
1068
|
* represented as a hexadecimal string.
|
|
1086
1069
|
*/
|
|
1087
1070
|
async function sha256(data) {
|
|
1088
|
-
if (typeof crypto === 'undefined') {
|
|
1089
|
-
// TODO(alanagius): remove once Node.js version 18 is no longer supported.
|
|
1090
|
-
throw new Error(`The global 'crypto' module is unavailable. ` +
|
|
1091
|
-
`If you are running on Node.js, please ensure you are using version 20 or later, ` +
|
|
1092
|
-
`which includes built-in support for the Web Crypto module.`);
|
|
1093
|
-
}
|
|
1094
1071
|
const encodedData = new TextEncoder().encode(data);
|
|
1095
1072
|
const hashBuffer = await crypto.subtle.digest('SHA-256', encodedData);
|
|
1096
1073
|
const hashParts = [];
|
|
@@ -1101,11 +1078,11 @@ async function sha256(data) {
|
|
|
1101
1078
|
}
|
|
1102
1079
|
|
|
1103
1080
|
/**
|
|
1104
|
-
* Pattern used to extract the media query set by
|
|
1081
|
+
* Pattern used to extract the media query set by Beasties in an `onload` handler.
|
|
1105
1082
|
*/
|
|
1106
1083
|
const MEDIA_SET_HANDLER_PATTERN = /^this\.media=["'](.*)["'];?$/;
|
|
1107
1084
|
/**
|
|
1108
|
-
* Name of the attribute used to save the
|
|
1085
|
+
* Name of the attribute used to save the Beasties media query so it can be re-assigned on load.
|
|
1109
1086
|
*/
|
|
1110
1087
|
const CSP_MEDIA_ATTR = 'ngCspMedia';
|
|
1111
1088
|
/**
|
|
@@ -1147,12 +1124,15 @@ const LINK_LOAD_SCRIPT_CONTENT = `
|
|
|
1147
1124
|
};
|
|
1148
1125
|
|
|
1149
1126
|
documentElement.addEventListener('load', listener, true);
|
|
1150
|
-
})()
|
|
1151
|
-
|
|
1152
|
-
class CrittersBase extends Critters {
|
|
1127
|
+
})();`;
|
|
1128
|
+
class BeastiesBase extends Beasties {
|
|
1153
1129
|
}
|
|
1154
1130
|
/* eslint-enable @typescript-eslint/no-unsafe-declaration-merging */
|
|
1155
|
-
class InlineCriticalCssProcessor extends
|
|
1131
|
+
class InlineCriticalCssProcessor extends BeastiesBase {
|
|
1132
|
+
readFile;
|
|
1133
|
+
outputPath;
|
|
1134
|
+
addedCspScriptsDocuments = new WeakSet();
|
|
1135
|
+
documentNonces = new WeakMap();
|
|
1156
1136
|
constructor(readFile, outputPath) {
|
|
1157
1137
|
super({
|
|
1158
1138
|
logger: {
|
|
@@ -1177,11 +1157,9 @@ class InlineCriticalCssProcessor extends CrittersBase {
|
|
|
1177
1157
|
});
|
|
1178
1158
|
this.readFile = readFile;
|
|
1179
1159
|
this.outputPath = outputPath;
|
|
1180
|
-
this.addedCspScriptsDocuments = new WeakSet();
|
|
1181
|
-
this.documentNonces = new WeakMap();
|
|
1182
1160
|
}
|
|
1183
1161
|
/**
|
|
1184
|
-
* Override of the
|
|
1162
|
+
* Override of the Beasties `embedLinkedStylesheet` method
|
|
1185
1163
|
* that makes it work with Angular's CSP APIs.
|
|
1186
1164
|
*/
|
|
1187
1165
|
async embedLinkedStylesheet(link, document) {
|
|
@@ -1198,17 +1176,17 @@ class InlineCriticalCssProcessor extends CrittersBase {
|
|
|
1198
1176
|
const returnValue = await super.embedLinkedStylesheet(link, document);
|
|
1199
1177
|
const cspNonce = this.findCspNonce(document);
|
|
1200
1178
|
if (cspNonce) {
|
|
1201
|
-
const
|
|
1202
|
-
if (
|
|
1203
|
-
// If there's a
|
|
1179
|
+
const beastiesMedia = link.getAttribute('onload')?.match(MEDIA_SET_HANDLER_PATTERN);
|
|
1180
|
+
if (beastiesMedia) {
|
|
1181
|
+
// If there's a Beasties-generated `onload` handler and the file has an Angular CSP nonce,
|
|
1204
1182
|
// we have to remove the handler, because it's incompatible with CSP. We save the value
|
|
1205
1183
|
// in a different attribute and we generate a script tag with the nonce that uses
|
|
1206
1184
|
// `addEventListener` to apply the media query instead.
|
|
1207
1185
|
link.removeAttribute('onload');
|
|
1208
|
-
link.setAttribute(CSP_MEDIA_ATTR,
|
|
1186
|
+
link.setAttribute(CSP_MEDIA_ATTR, beastiesMedia[1]);
|
|
1209
1187
|
this.conditionallyInsertCspLoadingScript(document, cspNonce, link);
|
|
1210
1188
|
}
|
|
1211
|
-
// Ideally we would hook in at the time
|
|
1189
|
+
// Ideally we would hook in at the time Beasties inserts the `style` tags, but there isn't
|
|
1212
1190
|
// a way of doing that at the moment so we fall back to doing it any time a `link` tag is
|
|
1213
1191
|
// inserted. We mitigate it by only iterating the direct children of the `<head>` which
|
|
1214
1192
|
// should be pretty shallow.
|
|
@@ -1228,7 +1206,7 @@ class InlineCriticalCssProcessor extends CrittersBase {
|
|
|
1228
1206
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
1229
1207
|
return this.documentNonces.get(document);
|
|
1230
1208
|
}
|
|
1231
|
-
// HTML attribute are case-insensitive, but the parser used by
|
|
1209
|
+
// HTML attribute are case-insensitive, but the parser used by Beasties is case-sensitive.
|
|
1232
1210
|
const nonceElement = document.querySelector('[ngCspNonce], [ngcspnonce]');
|
|
1233
1211
|
const cspNonce = nonceElement?.getAttribute('ngCspNonce') || nonceElement?.getAttribute('ngcspnonce') || null;
|
|
1234
1212
|
this.documentNonces.set(document, cspNonce);
|
|
@@ -1267,15 +1245,27 @@ class InlineCriticalCssProcessor extends CrittersBase {
|
|
|
1267
1245
|
* @template Value - The type of the cache values.
|
|
1268
1246
|
*/
|
|
1269
1247
|
class LRUCache {
|
|
1248
|
+
/**
|
|
1249
|
+
* The maximum number of items the cache can hold.
|
|
1250
|
+
*/
|
|
1251
|
+
capacity;
|
|
1252
|
+
/**
|
|
1253
|
+
* Internal storage for the cache, mapping keys to their associated nodes in the linked list.
|
|
1254
|
+
*/
|
|
1255
|
+
cache = new Map();
|
|
1256
|
+
/**
|
|
1257
|
+
* Head of the doubly linked list, representing the most recently used item.
|
|
1258
|
+
*/
|
|
1259
|
+
head;
|
|
1260
|
+
/**
|
|
1261
|
+
* Tail of the doubly linked list, representing the least recently used item.
|
|
1262
|
+
*/
|
|
1263
|
+
tail;
|
|
1270
1264
|
/**
|
|
1271
1265
|
* Creates a new LRUCache instance.
|
|
1272
1266
|
* @param capacity The maximum number of items the cache can hold.
|
|
1273
1267
|
*/
|
|
1274
1268
|
constructor(capacity) {
|
|
1275
|
-
/**
|
|
1276
|
-
* Internal storage for the cache, mapping keys to their associated nodes in the linked list.
|
|
1277
|
-
*/
|
|
1278
|
-
this.cache = new Map();
|
|
1279
1269
|
this.capacity = capacity;
|
|
1280
1270
|
}
|
|
1281
1271
|
/**
|
|
@@ -1401,29 +1391,39 @@ const SERVER_CONTEXT_VALUE = {
|
|
|
1401
1391
|
* The `AngularServerApp` class handles server-side rendering and asset management for a specific locale.
|
|
1402
1392
|
*/
|
|
1403
1393
|
class AngularServerApp {
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1394
|
+
/**
|
|
1395
|
+
* Hooks for extending or modifying the behavior of the server application.
|
|
1396
|
+
* This instance can be used to attach custom functionality to various events in the server application lifecycle.
|
|
1397
|
+
*/
|
|
1398
|
+
hooks = new Hooks();
|
|
1399
|
+
/**
|
|
1400
|
+
* The manifest associated with this server application.
|
|
1401
|
+
*/
|
|
1402
|
+
manifest = getAngularAppManifest();
|
|
1403
|
+
/**
|
|
1404
|
+
* An instance of ServerAsset that handles server-side asset.
|
|
1405
|
+
*/
|
|
1406
|
+
assets = new ServerAssets(this.manifest);
|
|
1407
|
+
/**
|
|
1408
|
+
* The router instance used for route matching and handling.
|
|
1409
|
+
*/
|
|
1410
|
+
router;
|
|
1411
|
+
/**
|
|
1412
|
+
* The `inlineCriticalCssProcessor` is responsible for handling critical CSS inlining.
|
|
1413
|
+
*/
|
|
1414
|
+
inlineCriticalCssProcessor;
|
|
1415
|
+
/**
|
|
1416
|
+
* The bootstrap mechanism for the server application.
|
|
1417
|
+
*/
|
|
1418
|
+
boostrap;
|
|
1419
|
+
/**
|
|
1420
|
+
* Cache for storing critical CSS for pages.
|
|
1421
|
+
* Stores a maximum of MAX_INLINE_CSS_CACHE_ENTRIES entries.
|
|
1422
|
+
*
|
|
1423
|
+
* Uses an LRU (Least Recently Used) eviction policy, meaning that when the cache is full,
|
|
1424
|
+
* the least recently accessed page's critical CSS will be removed to make space for new entries.
|
|
1425
|
+
*/
|
|
1426
|
+
criticalCssLRUCache = new LRUCache(MAX_INLINE_CSS_CACHE_ENTRIES);
|
|
1427
1427
|
/**
|
|
1428
1428
|
* Renders a response for the given HTTP request using the server application.
|
|
1429
1429
|
*
|
|
@@ -1547,7 +1547,14 @@ class AngularServerApp {
|
|
|
1547
1547
|
const fileName = path.split('/').pop() ?? path;
|
|
1548
1548
|
return this.assets.getServerAsset(fileName);
|
|
1549
1549
|
});
|
|
1550
|
-
|
|
1550
|
+
// TODO(alanagius): remove once Node.js version 18 is no longer supported.
|
|
1551
|
+
if (isSsrMode && typeof crypto === 'undefined') {
|
|
1552
|
+
// eslint-disable-next-line no-console
|
|
1553
|
+
console.error(`The global 'crypto' module is unavailable. ` +
|
|
1554
|
+
`If you are running on Node.js, please ensure you are using version 20 or later, ` +
|
|
1555
|
+
`which includes built-in support for the Web Crypto module.`);
|
|
1556
|
+
}
|
|
1557
|
+
if (isSsrMode && typeof crypto !== 'undefined') {
|
|
1551
1558
|
// Only cache if we are running in SSR Mode.
|
|
1552
1559
|
const cacheKey = await sha256(html);
|
|
1553
1560
|
let htmlWithCriticalCss = this.criticalCssLRUCache.get(cacheKey);
|
|
@@ -1639,16 +1646,6 @@ function getPotentialLocaleIdFromUrl(url, basePath) {
|
|
|
1639
1646
|
* @developerPreview
|
|
1640
1647
|
*/
|
|
1641
1648
|
class AngularAppEngine {
|
|
1642
|
-
constructor() {
|
|
1643
|
-
/**
|
|
1644
|
-
* The manifest for the server application.
|
|
1645
|
-
*/
|
|
1646
|
-
this.manifest = getAngularAppEngineManifest();
|
|
1647
|
-
/**
|
|
1648
|
-
* A cache that holds entry points, keyed by their potential locale string.
|
|
1649
|
-
*/
|
|
1650
|
-
this.entryPointsCache = new Map();
|
|
1651
|
-
}
|
|
1652
1649
|
/**
|
|
1653
1650
|
* Hooks for extending or modifying the behavior of the server application.
|
|
1654
1651
|
* These hooks are used by the Angular CLI when running the development server and
|
|
@@ -1656,7 +1653,7 @@ class AngularAppEngine {
|
|
|
1656
1653
|
*
|
|
1657
1654
|
* @private
|
|
1658
1655
|
*/
|
|
1659
|
-
static
|
|
1656
|
+
static ɵhooks = /* #__PURE__*/ new Hooks();
|
|
1660
1657
|
/**
|
|
1661
1658
|
* Provides access to the hooks for extending or modifying the server application's behavior.
|
|
1662
1659
|
* This allows attaching custom functionality to various server application lifecycle events.
|
|
@@ -1666,6 +1663,14 @@ class AngularAppEngine {
|
|
|
1666
1663
|
get hooks() {
|
|
1667
1664
|
return AngularAppEngine.ɵhooks;
|
|
1668
1665
|
}
|
|
1666
|
+
/**
|
|
1667
|
+
* The manifest for the server application.
|
|
1668
|
+
*/
|
|
1669
|
+
manifest = getAngularAppEngineManifest();
|
|
1670
|
+
/**
|
|
1671
|
+
* A cache that holds entry points, keyed by their potential locale string.
|
|
1672
|
+
*/
|
|
1673
|
+
entryPointsCache = new Map();
|
|
1669
1674
|
/**
|
|
1670
1675
|
* Renders a response for the given HTTP request using the server application.
|
|
1671
1676
|
*
|
|
@@ -1781,5 +1786,5 @@ function createRequestHandler(handler) {
|
|
|
1781
1786
|
return handler;
|
|
1782
1787
|
}
|
|
1783
1788
|
|
|
1784
|
-
export { AngularAppEngine,
|
|
1789
|
+
export { AngularAppEngine, RenderMode, createRequestHandler, provideServerRoutesConfig, InlineCriticalCssProcessor as ɵInlineCriticalCssProcessor, destroyAngularServerApp as ɵdestroyAngularServerApp, extractRoutesAndCreateRouteTree as ɵextractRoutesAndCreateRouteTree, getOrCreateAngularServerApp as ɵgetOrCreateAngularServerApp, getRoutesFromAngularRouterConfig as ɵgetRoutesFromAngularRouterConfig, setAngularAppEngineManifest as ɵsetAngularAppEngineManifest, setAngularAppManifest as ɵsetAngularAppManifest };
|
|
1785
1790
|
//# sourceMappingURL=ssr.mjs.map
|