@angular/platform-server 20.3.23 → 20.3.25
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/init.mjs +47 -17
- package/fesm2022/init.mjs.map +1 -1
- package/fesm2022/platform-server.mjs +6 -4
- package/fesm2022/platform-server.mjs.map +1 -1
- package/fesm2022/server.mjs +187 -67
- package/fesm2022/server.mjs.map +1 -1
- package/fesm2022/testing.mjs +5 -5
- package/fesm2022/testing.mjs.map +1 -1
- package/index.d.ts +16 -2
- package/init/index.d.ts +1 -1
- package/package.json +5 -5
- package/testing/index.d.ts +1 -1
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @license Angular v20.3.
|
|
2
|
+
* @license Angular v20.3.25
|
|
3
3
|
* (c) 2010-2025 Google LLC. https://angular.dev/
|
|
4
4
|
* License: MIT
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import { PLATFORM_SERVER_PROVIDERS, PlatformState, BEFORE_APP_SERIALIZED, parseUrl, platformServer, INITIAL_CONFIG, createScript } from './server.mjs';
|
|
8
8
|
export { ServerModule, DominoAdapter as ɵDominoAdapter, ENABLE_DOM_EMULATION as ɵENABLE_DOM_EMULATION, INTERNAL_SERVER_PLATFORM_PROVIDERS as ɵINTERNAL_SERVER_PLATFORM_PROVIDERS, SERVER_RENDER_PROVIDERS as ɵSERVER_RENDER_PROVIDERS } from './server.mjs';
|
|
9
|
-
import { makeEnvironmentProviders, InjectionToken, ApplicationRef, ɵstartMeasuring as _startMeasuring, ɵstopMeasuring as _stopMeasuring, ɵIS_HYDRATION_DOM_REUSE_ENABLED as _IS_HYDRATION_DOM_REUSE_ENABLED, ɵannotateForHydration as _annotateForHydration, CSP_NONCE, APP_ID, ɵSSR_CONTENT_INTEGRITY_MARKER as _SSR_CONTENT_INTEGRITY_MARKER, Renderer2, Version } from '@angular/core';
|
|
9
|
+
import { makeEnvironmentProviders, InjectionToken, ApplicationRef, ɵstartMeasuring as _startMeasuring, ɵstopMeasuring as _stopMeasuring, ɵRuntimeError as _RuntimeError, ɵIS_HYDRATION_DOM_REUSE_ENABLED as _IS_HYDRATION_DOM_REUSE_ENABLED, ɵannotateForHydration as _annotateForHydration, CSP_NONCE, APP_ID, ɵSSR_CONTENT_INTEGRITY_MARKER as _SSR_CONTENT_INTEGRITY_MARKER, Renderer2, Version } from '@angular/core';
|
|
10
10
|
import '@angular/common';
|
|
11
11
|
import '@angular/platform-browser';
|
|
12
12
|
import '@angular/common/http';
|
|
@@ -320,7 +320,9 @@ function validateAllowedHosts(url, allowedHosts) {
|
|
|
320
320
|
const hostname = parsedUrl.hostname;
|
|
321
321
|
const allowedHostsSet = new Set(allowedHosts);
|
|
322
322
|
if (!isHostAllowed(hostname, allowedHostsSet)) {
|
|
323
|
-
throw new
|
|
323
|
+
throw new _RuntimeError(5706 /* RuntimeErrorCode.HOST_NOT_ALLOWED */, typeof ngDevMode === 'undefined' || ngDevMode
|
|
324
|
+
? `Host ${url} is not allowed. You can configure \`allowedHosts\` option.`
|
|
325
|
+
: url);
|
|
324
326
|
}
|
|
325
327
|
}
|
|
326
328
|
}
|
|
@@ -357,7 +359,7 @@ function isHostAllowed(hostname, allowedHosts) {
|
|
|
357
359
|
/**
|
|
358
360
|
* @publicApi
|
|
359
361
|
*/
|
|
360
|
-
const VERSION = /* @__PURE__ */ new Version('20.3.
|
|
362
|
+
const VERSION = /* @__PURE__ */ new Version('20.3.25');
|
|
361
363
|
|
|
362
364
|
export { BEFORE_APP_SERIALIZED, INITIAL_CONFIG, PlatformState, VERSION, platformServer, provideServerRendering, renderApplication, renderModule, SERVER_CONTEXT as ɵSERVER_CONTEXT, isHostAllowed as ɵisHostAllowed, renderInternal as ɵrenderInternal };
|
|
363
365
|
//# sourceMappingURL=platform-server.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"platform-server.mjs","sources":["../../../../../darwin_arm64-fastbuild-ST-199a4f3c4e20/bin/packages/platform-server/src/provide_server.ts","../../../../../darwin_arm64-fastbuild-ST-199a4f3c4e20/bin/packages/platform-server/src/utils.ts","../../../../../darwin_arm64-fastbuild-ST-199a4f3c4e20/bin/packages/platform-server/src/version.ts"],"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 */\n\nimport {EnvironmentProviders, makeEnvironmentProviders} from '@angular/core';\n\nimport {PLATFORM_SERVER_PROVIDERS} from './server';\n\n/**\n * Sets up providers necessary to enable server rendering functionality for the application.\n *\n * @usageNotes\n *\n * Basic example of how you can add server support to your application:\n * ```ts\n * bootstrapApplication(AppComponent, {\n * providers: [provideServerRendering()]\n * });\n * ```\n *\n * @publicApi\n * @returns A set of providers to setup the server.\n */\nexport function provideServerRendering(): EnvironmentProviders {\n if (typeof ngServerMode === 'undefined') {\n globalThis['ngServerMode'] = true;\n }\n\n return makeEnvironmentProviders([...PLATFORM_SERVER_PROVIDERS]);\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\nimport {\n APP_ID,\n ApplicationRef,\n CSP_NONCE,\n InjectionToken,\n PlatformRef,\n Provider,\n Renderer2,\n StaticProvider,\n Type,\n ɵannotateForHydration as annotateForHydration,\n ɵIS_HYDRATION_DOM_REUSE_ENABLED as IS_HYDRATION_DOM_REUSE_ENABLED,\n ɵSSR_CONTENT_INTEGRITY_MARKER as SSR_CONTENT_INTEGRITY_MARKER,\n ɵstartMeasuring as startMeasuring,\n ɵstopMeasuring as stopMeasuring,\n} from '@angular/core';\nimport {BootstrapContext} from '@angular/platform-browser';\n\nimport {platformServer} from './server';\nimport {PlatformState} from './platform_state';\nimport {BEFORE_APP_SERIALIZED, INITIAL_CONFIG, PlatformConfig} from './tokens';\nimport {createScript} from './transfer_state';\nimport {parseUrl} from './url';\n\n/**\n * Event dispatch (JSAction) script is inlined into the HTML by the build\n * process to avoid extra blocking request on a page. The script looks like this:\n * ```html\n * <script type=\"text/javascript\" id=\"ng-event-dispatch-contract\">...</script>\n * ```\n * This const represents the \"id\" attribute value.\n */\nexport const EVENT_DISPATCH_SCRIPT_ID = 'ng-event-dispatch-contract';\n\ninterface PlatformOptions extends Omit<PlatformConfig, 'document'> {\n document?: string | Document;\n platformProviders?: Provider[];\n}\n\n/**\n * Creates an instance of a server platform (with or without JIT compiler support\n * depending on the `ngJitMode` global const value), using provided options.\n */\nfunction createServerPlatform(options: PlatformOptions): PlatformRef {\n const extraProviders = options.platformProviders ?? [];\n const measuringLabel = 'createServerPlatform';\n startMeasuring(measuringLabel);\n const {document, url} = options;\n\n const platform = platformServer([\n {\n provide: INITIAL_CONFIG,\n useValue: {\n document,\n url,\n },\n },\n extraProviders,\n ]);\n\n stopMeasuring(measuringLabel);\n return platform;\n}\n\n/**\n * Finds and returns inlined event dispatch script if it exists.\n * See the `EVENT_DISPATCH_SCRIPT_ID` const docs for additional info.\n */\nfunction findEventDispatchScript(doc: Document) {\n return doc.getElementById(EVENT_DISPATCH_SCRIPT_ID);\n}\n\n/**\n * Removes inlined event dispatch script if it exists.\n * See the `EVENT_DISPATCH_SCRIPT_ID` const docs for additional info.\n */\nfunction removeEventDispatchScript(doc: Document) {\n findEventDispatchScript(doc)?.remove();\n}\n\n/**\n * Annotate nodes for hydration and remove event dispatch script when not needed.\n */\nfunction prepareForHydration(platformState: PlatformState, applicationRef: ApplicationRef): void {\n const measuringLabel = 'prepareForHydration';\n startMeasuring(measuringLabel);\n const environmentInjector = applicationRef.injector;\n const doc = platformState.getDocument();\n\n if (!environmentInjector.get(IS_HYDRATION_DOM_REUSE_ENABLED, false)) {\n // Hydration is diabled, remove inlined event dispatch script.\n // (which was injected by the build process) from the HTML.\n removeEventDispatchScript(doc);\n\n return;\n }\n\n appendSsrContentIntegrityMarker(doc);\n\n const eventTypesToReplay = annotateForHydration(applicationRef, doc);\n if (eventTypesToReplay.regular.size || eventTypesToReplay.capture.size) {\n insertEventRecordScript(\n environmentInjector.get(APP_ID),\n doc,\n eventTypesToReplay,\n environmentInjector.get(CSP_NONCE, null),\n );\n } else {\n // No events to replay, we should remove inlined event dispatch script\n // (which was injected by the build process) from the HTML.\n removeEventDispatchScript(doc);\n }\n stopMeasuring(measuringLabel);\n}\n\n/**\n * Creates a marker comment node and append it into the `<body>`.\n * Some CDNs have mechanisms to remove all comment node from HTML.\n * This behaviour breaks hydration, so we'll detect on the client side if this\n * marker comment is still available or else throw an error\n */\nfunction appendSsrContentIntegrityMarker(doc: Document) {\n // Adding a ng hydration marker comment\n const comment = doc.createComment(SSR_CONTENT_INTEGRITY_MARKER);\n doc.body.firstChild\n ? doc.body.insertBefore(comment, doc.body.firstChild)\n : doc.body.append(comment);\n}\n\n/**\n * Adds the `ng-server-context` attribute to host elements of all bootstrapped components\n * within a given application.\n */\nfunction appendServerContextInfo(applicationRef: ApplicationRef) {\n const injector = applicationRef.injector;\n let serverContext = sanitizeServerContext(injector.get(SERVER_CONTEXT, DEFAULT_SERVER_CONTEXT));\n applicationRef.components.forEach((componentRef) => {\n const renderer = componentRef.injector.get(Renderer2);\n const element = componentRef.location.nativeElement;\n if (element) {\n renderer.setAttribute(element, 'ng-server-context', serverContext);\n }\n });\n}\n\nfunction insertEventRecordScript(\n appId: string,\n doc: Document,\n eventTypesToReplay: {regular: Set<string>; capture: Set<string>},\n nonce: string | null,\n): void {\n const measuringLabel = 'insertEventRecordScript';\n startMeasuring(measuringLabel);\n const {regular, capture} = eventTypesToReplay;\n const eventDispatchScript = findEventDispatchScript(doc);\n\n // Note: this is only true when build with the CLI tooling, which inserts the script in the HTML\n if (eventDispatchScript) {\n // This is defined in packages/core/primitives/event-dispatch/contract_binary.ts\n const replayScriptContents =\n `window.__jsaction_bootstrap(` +\n `document.body,` +\n `\"${appId}\",` +\n `${JSON.stringify(Array.from(regular))},` +\n `${JSON.stringify(Array.from(capture))}` +\n `);`;\n\n const replayScript = createScript(doc, replayScriptContents, nonce);\n\n // Insert replay script right after inlined event dispatch script, since it\n // relies on `__jsaction_bootstrap` to be defined in the global scope.\n eventDispatchScript.after(replayScript);\n }\n stopMeasuring(measuringLabel);\n}\n\n/**\n * Renders an Angular application to a string.\n *\n * @private\n *\n * @param platformRef - Reference to the Angular platform.\n * @param applicationRef - Reference to the Angular application.\n * @returns A promise that resolves to the rendered string.\n */\nexport async function renderInternal(\n platformRef: PlatformRef,\n applicationRef: ApplicationRef,\n): Promise<string> {\n const platformState = platformRef.injector.get(PlatformState);\n prepareForHydration(platformState, applicationRef);\n appendServerContextInfo(applicationRef);\n\n // Run any BEFORE_APP_SERIALIZED callbacks just before rendering to string.\n const environmentInjector = applicationRef.injector;\n const callbacks = environmentInjector.get(BEFORE_APP_SERIALIZED, null);\n if (callbacks) {\n const asyncCallbacks: Promise<void>[] = [];\n for (const callback of callbacks) {\n try {\n const callbackResult = callback();\n if (callbackResult) {\n asyncCallbacks.push(callbackResult);\n }\n } catch (e) {\n // Ignore exceptions.\n console.warn('Ignoring BEFORE_APP_SERIALIZED Exception: ', e);\n }\n }\n\n if (asyncCallbacks.length) {\n for (const result of await Promise.allSettled(asyncCallbacks)) {\n if (result.status === 'rejected') {\n console.warn('Ignoring BEFORE_APP_SERIALIZED Exception: ', result.reason);\n }\n }\n }\n }\n\n return platformState.renderToString();\n}\n\n/**\n * Destroy the application in a macrotask, this allows pending promises to be settled and errors\n * to be surfaced to the users.\n */\nfunction asyncDestroyPlatform(platformRef: PlatformRef): Promise<void> {\n return new Promise<void>((resolve) => {\n setTimeout(() => {\n platformRef.destroy();\n resolve();\n }, 0);\n });\n}\n\n/**\n * Specifies the value that should be used if no server context value has been provided.\n */\nconst DEFAULT_SERVER_CONTEXT = 'other';\n\n/**\n * An internal token that allows providing extra information about the server context\n * (e.g. whether SSR or SSG was used). The value is a string and characters other\n * than [a-zA-Z0-9\\-] are removed. See the default value in `DEFAULT_SERVER_CONTEXT` const.\n */\nexport const SERVER_CONTEXT = new InjectionToken<string>('SERVER_CONTEXT');\n\n/**\n * Sanitizes provided server context:\n * - removes all characters other than a-z, A-Z, 0-9 and `-`\n * - returns `other` if nothing is provided or the string is empty after sanitization\n */\nfunction sanitizeServerContext(serverContext: string): string {\n const context = serverContext.replace(/[^a-zA-Z0-9\\-]/g, '');\n return context.length > 0 ? context : DEFAULT_SERVER_CONTEXT;\n}\n\n/**\n * Bootstraps an application using provided NgModule and serializes the page content to string.\n *\n * @param moduleType A reference to an NgModule that should be used for bootstrap.\n * @param options Additional configuration for the render operation:\n * - `document` - the document of the page to render, either as an HTML string or\n * as a reference to the `document` instance.\n * - `url` - the URL for the current render request.\n * - `extraProviders` - set of platform level providers for the current render request.\n * - `allowedHosts` - the allowed hosts list for host validation in server-side rendering.\n * @publicApi\n */\nexport async function renderModule<T>(\n moduleType: Type<T>,\n options: {\n document?: string | Document;\n url?: string;\n extraProviders?: StaticProvider[];\n allowedHosts?: Readonly<string>[];\n },\n): Promise<string> {\n const {document, url, extraProviders: platformProviders, allowedHosts} = options;\n validateAllowedHosts(url, allowedHosts);\n const platformRef = createServerPlatform({document, url, platformProviders});\n try {\n const moduleRef = await platformRef.bootstrapModule(moduleType);\n const applicationRef = moduleRef.injector.get(ApplicationRef);\n\n const measuringLabel = 'whenStable';\n startMeasuring(measuringLabel);\n // Block until application is stable.\n await applicationRef.whenStable();\n stopMeasuring(measuringLabel);\n\n return await renderInternal(platformRef, applicationRef);\n } finally {\n await asyncDestroyPlatform(platformRef);\n }\n}\n\n/**\n * Bootstraps an instance of an Angular application and renders it to a string.\n *\n * @usageNotes\n *\n * ```ts\n * import { BootstrapContext, bootstrapApplication } from '@angular/platform-browser';\n * import { renderApplication } from '@angular/platform-server';\n * import { ApplicationConfig } from '@angular/core';\n * import { AppComponent } from './app.component';\n *\n * const appConfig: ApplicationConfig = { providers: [...] };\n * const bootstrap = (context: BootstrapContext) =>\n * bootstrapApplication(AppComponent, config, context);\n * const output = await renderApplication(bootstrap);\n * ```\n *\n * @param bootstrap A method that when invoked returns a promise that returns an `ApplicationRef`\n * instance once resolved. The method is invoked with an `Injector` instance that\n * provides access to the platform-level dependency injection context.\n * @param options Additional configuration for the render operation:\n * - `document` - the document of the page to render, either as an HTML string or\n * as a reference to the `document` instance.\n * - `url` - the URL for the current render request.\n * - `platformProviders` - the platform level providers for the current render request.\n * - `allowedHosts` - the allowed hosts list for host validation in server-side rendering.\n *\n * @returns A Promise, that returns serialized (to a string) rendered page, once resolved.\n *\n * @publicApi\n */\nexport async function renderApplication(\n bootstrap: (context: BootstrapContext) => Promise<ApplicationRef>,\n options: {\n document?: string | Document;\n url?: string;\n platformProviders?: Provider[];\n allowedHosts?: Readonly<string>[];\n },\n): Promise<string> {\n const renderAppLabel = 'renderApplication';\n const bootstrapLabel = 'bootstrap';\n const _renderLabel = '_render';\n const {url, allowedHosts} = options;\n\n validateAllowedHosts(url, allowedHosts);\n\n startMeasuring(renderAppLabel);\n const platformRef = createServerPlatform(options);\n try {\n startMeasuring(bootstrapLabel);\n const applicationRef = await bootstrap({platformRef});\n stopMeasuring(bootstrapLabel);\n\n startMeasuring(_renderLabel);\n\n const measuringLabel = 'whenStable';\n startMeasuring(measuringLabel);\n // Block until application is stable.\n await applicationRef.whenStable();\n stopMeasuring(measuringLabel);\n\n const rendered = await renderInternal(platformRef, applicationRef);\n stopMeasuring(_renderLabel);\n return rendered;\n } finally {\n await asyncDestroyPlatform(platformRef);\n stopMeasuring(renderAppLabel);\n }\n}\n\nfunction validateAllowedHosts(url: string | undefined, allowedHosts: string[] | undefined) {\n if (typeof url === 'string') {\n const parsedUrl = parseUrl(url);\n if (parsedUrl !== null) {\n const hostname = parsedUrl.hostname;\n const allowedHostsSet: ReadonlySet<string> = new Set(allowedHosts);\n if (!isHostAllowed(hostname, allowedHostsSet)) {\n throw new Error(`Host ${url} is not allowed. You can configure \\`allowedHosts\\` option.`);\n }\n }\n }\n}\n\n/**\n * Checks if the hostname is allowed.\n * @param hostname - The hostname to check.\n * @param allowedHosts - A set of allowed hostnames.\n * @returns `true` if the hostname is allowed, `false` otherwise.\n * @note Used also in `@angular/ssr`.\n * @private\n */\nexport function isHostAllowed(hostname: string, allowedHosts: ReadonlySet<string>): boolean {\n if (allowedHosts.has('*') || allowedHosts.has(hostname)) {\n return true;\n }\n\n for (const allowedHost of allowedHosts) {\n if (!allowedHost.startsWith('*.')) {\n continue;\n }\n\n const domain = allowedHost.slice(1);\n if (hostname.endsWith(domain)) {\n return true;\n }\n }\n\n return false;\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/**\n * @module\n * @description\n * Entry point for all public APIs of the platform-server package.\n */\n\nimport {Version} from '@angular/core';\n\n/**\n * @publicApi\n */\nexport const VERSION = /* @__PURE__ */ new Version('20.3.23');\n"],"names":["startMeasuring","stopMeasuring","IS_HYDRATION_DOM_REUSE_ENABLED","annotateForHydration","SSR_CONTENT_INTEGRITY_MARKER"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"platform-server.mjs","sources":["../../../../../k8-fastbuild-ST-199a4f3c4e20/bin/packages/platform-server/src/provide_server.ts","../../../../../k8-fastbuild-ST-199a4f3c4e20/bin/packages/platform-server/src/utils.ts","../../../../../k8-fastbuild-ST-199a4f3c4e20/bin/packages/platform-server/src/version.ts"],"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 */\n\nimport {EnvironmentProviders, makeEnvironmentProviders} from '@angular/core';\n\nimport {PLATFORM_SERVER_PROVIDERS} from './server';\n\n/**\n * Sets up providers necessary to enable server rendering functionality for the application.\n *\n * @usageNotes\n *\n * Basic example of how you can add server support to your application:\n * ```ts\n * bootstrapApplication(AppComponent, {\n * providers: [provideServerRendering()]\n * });\n * ```\n *\n * @publicApi\n * @returns A set of providers to setup the server.\n */\nexport function provideServerRendering(): EnvironmentProviders {\n if (typeof ngServerMode === 'undefined') {\n globalThis['ngServerMode'] = true;\n }\n\n return makeEnvironmentProviders([...PLATFORM_SERVER_PROVIDERS]);\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\nimport {\n APP_ID,\n ApplicationRef,\n CSP_NONCE,\n InjectionToken,\n PlatformRef,\n Provider,\n Renderer2,\n StaticProvider,\n Type,\n ɵannotateForHydration as annotateForHydration,\n ɵIS_HYDRATION_DOM_REUSE_ENABLED as IS_HYDRATION_DOM_REUSE_ENABLED,\n ɵSSR_CONTENT_INTEGRITY_MARKER as SSR_CONTENT_INTEGRITY_MARKER,\n ɵstartMeasuring as startMeasuring,\n ɵstopMeasuring as stopMeasuring,\n ɵRuntimeError as RuntimeError,\n} from '@angular/core';\nimport {BootstrapContext} from '@angular/platform-browser';\n\nimport {RuntimeErrorCode} from './errors';\nimport {platformServer} from './server';\nimport {PlatformState} from './platform_state';\nimport {BEFORE_APP_SERIALIZED, INITIAL_CONFIG, PlatformConfig} from './tokens';\nimport {createScript} from './transfer_state';\nimport {parseUrl} from './url';\n\n/**\n * Event dispatch (JSAction) script is inlined into the HTML by the build\n * process to avoid extra blocking request on a page. The script looks like this:\n * ```html\n * <script type=\"text/javascript\" id=\"ng-event-dispatch-contract\">...</script>\n * ```\n * This const represents the \"id\" attribute value.\n */\nexport const EVENT_DISPATCH_SCRIPT_ID = 'ng-event-dispatch-contract';\n\ninterface PlatformOptions extends Omit<PlatformConfig, 'document'> {\n document?: string | Document;\n platformProviders?: Provider[];\n}\n\n/**\n * Creates an instance of a server platform (with or without JIT compiler support\n * depending on the `ngJitMode` global const value), using provided options.\n */\nfunction createServerPlatform(options: PlatformOptions): PlatformRef {\n const extraProviders = options.platformProviders ?? [];\n const measuringLabel = 'createServerPlatform';\n startMeasuring(measuringLabel);\n const {document, url} = options;\n\n const platform = platformServer([\n {\n provide: INITIAL_CONFIG,\n useValue: {\n document,\n url,\n },\n },\n extraProviders,\n ]);\n\n stopMeasuring(measuringLabel);\n return platform;\n}\n\n/**\n * Finds and returns inlined event dispatch script if it exists.\n * See the `EVENT_DISPATCH_SCRIPT_ID` const docs for additional info.\n */\nfunction findEventDispatchScript(doc: Document) {\n return doc.getElementById(EVENT_DISPATCH_SCRIPT_ID);\n}\n\n/**\n * Removes inlined event dispatch script if it exists.\n * See the `EVENT_DISPATCH_SCRIPT_ID` const docs for additional info.\n */\nfunction removeEventDispatchScript(doc: Document) {\n findEventDispatchScript(doc)?.remove();\n}\n\n/**\n * Annotate nodes for hydration and remove event dispatch script when not needed.\n */\nfunction prepareForHydration(platformState: PlatformState, applicationRef: ApplicationRef): void {\n const measuringLabel = 'prepareForHydration';\n startMeasuring(measuringLabel);\n const environmentInjector = applicationRef.injector;\n const doc = platformState.getDocument();\n\n if (!environmentInjector.get(IS_HYDRATION_DOM_REUSE_ENABLED, false)) {\n // Hydration is diabled, remove inlined event dispatch script.\n // (which was injected by the build process) from the HTML.\n removeEventDispatchScript(doc);\n\n return;\n }\n\n appendSsrContentIntegrityMarker(doc);\n\n const eventTypesToReplay = annotateForHydration(applicationRef, doc);\n if (eventTypesToReplay.regular.size || eventTypesToReplay.capture.size) {\n insertEventRecordScript(\n environmentInjector.get(APP_ID),\n doc,\n eventTypesToReplay,\n environmentInjector.get(CSP_NONCE, null),\n );\n } else {\n // No events to replay, we should remove inlined event dispatch script\n // (which was injected by the build process) from the HTML.\n removeEventDispatchScript(doc);\n }\n stopMeasuring(measuringLabel);\n}\n\n/**\n * Creates a marker comment node and append it into the `<body>`.\n * Some CDNs have mechanisms to remove all comment node from HTML.\n * This behaviour breaks hydration, so we'll detect on the client side if this\n * marker comment is still available or else throw an error\n */\nfunction appendSsrContentIntegrityMarker(doc: Document) {\n // Adding a ng hydration marker comment\n const comment = doc.createComment(SSR_CONTENT_INTEGRITY_MARKER);\n doc.body.firstChild\n ? doc.body.insertBefore(comment, doc.body.firstChild)\n : doc.body.append(comment);\n}\n\n/**\n * Adds the `ng-server-context` attribute to host elements of all bootstrapped components\n * within a given application.\n */\nfunction appendServerContextInfo(applicationRef: ApplicationRef) {\n const injector = applicationRef.injector;\n let serverContext = sanitizeServerContext(injector.get(SERVER_CONTEXT, DEFAULT_SERVER_CONTEXT));\n applicationRef.components.forEach((componentRef) => {\n const renderer = componentRef.injector.get(Renderer2);\n const element = componentRef.location.nativeElement;\n if (element) {\n renderer.setAttribute(element, 'ng-server-context', serverContext);\n }\n });\n}\n\nfunction insertEventRecordScript(\n appId: string,\n doc: Document,\n eventTypesToReplay: {regular: Set<string>; capture: Set<string>},\n nonce: string | null,\n): void {\n const measuringLabel = 'insertEventRecordScript';\n startMeasuring(measuringLabel);\n const {regular, capture} = eventTypesToReplay;\n const eventDispatchScript = findEventDispatchScript(doc);\n\n // Note: this is only true when build with the CLI tooling, which inserts the script in the HTML\n if (eventDispatchScript) {\n // This is defined in packages/core/primitives/event-dispatch/contract_binary.ts\n const replayScriptContents =\n `window.__jsaction_bootstrap(` +\n `document.body,` +\n `\"${appId}\",` +\n `${JSON.stringify(Array.from(regular))},` +\n `${JSON.stringify(Array.from(capture))}` +\n `);`;\n\n const replayScript = createScript(doc, replayScriptContents, nonce);\n\n // Insert replay script right after inlined event dispatch script, since it\n // relies on `__jsaction_bootstrap` to be defined in the global scope.\n eventDispatchScript.after(replayScript);\n }\n stopMeasuring(measuringLabel);\n}\n\n/**\n * Renders an Angular application to a string.\n *\n * @private\n *\n * @param platformRef - Reference to the Angular platform.\n * @param applicationRef - Reference to the Angular application.\n * @returns A promise that resolves to the rendered string.\n */\nexport async function renderInternal(\n platformRef: PlatformRef,\n applicationRef: ApplicationRef,\n): Promise<string> {\n const platformState = platformRef.injector.get(PlatformState);\n prepareForHydration(platformState, applicationRef);\n appendServerContextInfo(applicationRef);\n\n // Run any BEFORE_APP_SERIALIZED callbacks just before rendering to string.\n const environmentInjector = applicationRef.injector;\n const callbacks = environmentInjector.get(BEFORE_APP_SERIALIZED, null);\n if (callbacks) {\n const asyncCallbacks: Promise<void>[] = [];\n for (const callback of callbacks) {\n try {\n const callbackResult = callback();\n if (callbackResult) {\n asyncCallbacks.push(callbackResult);\n }\n } catch (e) {\n // Ignore exceptions.\n console.warn('Ignoring BEFORE_APP_SERIALIZED Exception: ', e);\n }\n }\n\n if (asyncCallbacks.length) {\n for (const result of await Promise.allSettled(asyncCallbacks)) {\n if (result.status === 'rejected') {\n console.warn('Ignoring BEFORE_APP_SERIALIZED Exception: ', result.reason);\n }\n }\n }\n }\n\n return platformState.renderToString();\n}\n\n/**\n * Destroy the application in a macrotask, this allows pending promises to be settled and errors\n * to be surfaced to the users.\n */\nfunction asyncDestroyPlatform(platformRef: PlatformRef): Promise<void> {\n return new Promise<void>((resolve) => {\n setTimeout(() => {\n platformRef.destroy();\n resolve();\n }, 0);\n });\n}\n\n/**\n * Specifies the value that should be used if no server context value has been provided.\n */\nconst DEFAULT_SERVER_CONTEXT = 'other';\n\n/**\n * An internal token that allows providing extra information about the server context\n * (e.g. whether SSR or SSG was used). The value is a string and characters other\n * than [a-zA-Z0-9\\-] are removed. See the default value in `DEFAULT_SERVER_CONTEXT` const.\n */\nexport const SERVER_CONTEXT = new InjectionToken<string>('SERVER_CONTEXT');\n\n/**\n * Sanitizes provided server context:\n * - removes all characters other than a-z, A-Z, 0-9 and `-`\n * - returns `other` if nothing is provided or the string is empty after sanitization\n */\nfunction sanitizeServerContext(serverContext: string): string {\n const context = serverContext.replace(/[^a-zA-Z0-9\\-]/g, '');\n return context.length > 0 ? context : DEFAULT_SERVER_CONTEXT;\n}\n\n/**\n * Bootstraps an application using provided NgModule and serializes the page content to string.\n *\n * @param moduleType A reference to an NgModule that should be used for bootstrap.\n * @param options Additional configuration for the render operation:\n * - `document` - the document of the page to render, either as an HTML string or\n * as a reference to the `document` instance.\n * - `url` - the URL for the current render request.\n * - `extraProviders` - set of platform level providers for the current render request.\n * - `allowedHosts` - the allowed hosts list for host validation in server-side rendering.\n * @publicApi\n */\nexport async function renderModule<T>(\n moduleType: Type<T>,\n options: {\n document?: string | Document;\n url?: string;\n extraProviders?: StaticProvider[];\n allowedHosts?: Readonly<string>[];\n },\n): Promise<string> {\n const {document, url, extraProviders: platformProviders, allowedHosts} = options;\n validateAllowedHosts(url, allowedHosts);\n const platformRef = createServerPlatform({document, url, platformProviders});\n try {\n const moduleRef = await platformRef.bootstrapModule(moduleType);\n const applicationRef = moduleRef.injector.get(ApplicationRef);\n\n const measuringLabel = 'whenStable';\n startMeasuring(measuringLabel);\n // Block until application is stable.\n await applicationRef.whenStable();\n stopMeasuring(measuringLabel);\n\n return await renderInternal(platformRef, applicationRef);\n } finally {\n await asyncDestroyPlatform(platformRef);\n }\n}\n\n/**\n * Bootstraps an instance of an Angular application and renders it to a string.\n *\n * @usageNotes\n *\n * ```ts\n * import { BootstrapContext, bootstrapApplication } from '@angular/platform-browser';\n * import { renderApplication } from '@angular/platform-server';\n * import { ApplicationConfig } from '@angular/core';\n * import { AppComponent } from './app.component';\n *\n * const appConfig: ApplicationConfig = { providers: [...] };\n * const bootstrap = (context: BootstrapContext) =>\n * bootstrapApplication(AppComponent, config, context);\n * const output = await renderApplication(bootstrap);\n * ```\n *\n * @param bootstrap A method that when invoked returns a promise that returns an `ApplicationRef`\n * instance once resolved. The method is invoked with an `Injector` instance that\n * provides access to the platform-level dependency injection context.\n * @param options Additional configuration for the render operation:\n * - `document` - the document of the page to render, either as an HTML string or\n * as a reference to the `document` instance.\n * - `url` - the URL for the current render request.\n * - `platformProviders` - the platform level providers for the current render request.\n * - `allowedHosts` - the allowed hosts list for host validation in server-side rendering.\n *\n * @returns A Promise, that returns serialized (to a string) rendered page, once resolved.\n *\n * @publicApi\n */\nexport async function renderApplication(\n bootstrap: (context: BootstrapContext) => Promise<ApplicationRef>,\n options: {\n document?: string | Document;\n url?: string;\n platformProviders?: Provider[];\n allowedHosts?: Readonly<string>[];\n },\n): Promise<string> {\n const renderAppLabel = 'renderApplication';\n const bootstrapLabel = 'bootstrap';\n const _renderLabel = '_render';\n const {url, allowedHosts} = options;\n\n validateAllowedHosts(url, allowedHosts);\n\n startMeasuring(renderAppLabel);\n const platformRef = createServerPlatform(options);\n try {\n startMeasuring(bootstrapLabel);\n const applicationRef = await bootstrap({platformRef});\n stopMeasuring(bootstrapLabel);\n\n startMeasuring(_renderLabel);\n\n const measuringLabel = 'whenStable';\n startMeasuring(measuringLabel);\n // Block until application is stable.\n await applicationRef.whenStable();\n stopMeasuring(measuringLabel);\n\n const rendered = await renderInternal(platformRef, applicationRef);\n stopMeasuring(_renderLabel);\n return rendered;\n } finally {\n await asyncDestroyPlatform(platformRef);\n stopMeasuring(renderAppLabel);\n }\n}\n\nfunction validateAllowedHosts(url: string | undefined, allowedHosts: string[] | undefined) {\n if (typeof url === 'string') {\n const parsedUrl = parseUrl(url);\n if (parsedUrl !== null) {\n const hostname = parsedUrl.hostname;\n const allowedHostsSet: ReadonlySet<string> = new Set(allowedHosts);\n if (!isHostAllowed(hostname, allowedHostsSet)) {\n throw new RuntimeError(\n RuntimeErrorCode.HOST_NOT_ALLOWED,\n typeof ngDevMode === 'undefined' || ngDevMode\n ? `Host ${url} is not allowed. You can configure \\`allowedHosts\\` option.`\n : url,\n );\n }\n }\n }\n}\n\n/**\n * Checks if the hostname is allowed.\n * @param hostname - The hostname to check.\n * @param allowedHosts - A set of allowed hostnames.\n * @returns `true` if the hostname is allowed, `false` otherwise.\n * @note Used also in `@angular/ssr`.\n * @private\n */\nexport function isHostAllowed(hostname: string, allowedHosts: ReadonlySet<string>): boolean {\n if (allowedHosts.has('*') || allowedHosts.has(hostname)) {\n return true;\n }\n\n for (const allowedHost of allowedHosts) {\n if (!allowedHost.startsWith('*.')) {\n continue;\n }\n\n const domain = allowedHost.slice(1);\n if (hostname.endsWith(domain)) {\n return true;\n }\n }\n\n return false;\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/**\n * @module\n * @description\n * Entry point for all public APIs of the platform-server package.\n */\n\nimport {Version} from '@angular/core';\n\n/**\n * @publicApi\n */\nexport const VERSION = /* @__PURE__ */ new Version('20.3.25');\n"],"names":["startMeasuring","stopMeasuring","IS_HYDRATION_DOM_REUSE_ENABLED","annotateForHydration","SSR_CONTENT_INTEGRITY_MARKER","RuntimeError"],"mappings":"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"}
|
package/fesm2022/server.mjs
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @license Angular v20.3.
|
|
2
|
+
* @license Angular v20.3.25
|
|
3
3
|
* (c) 2010-2025 Google LLC. https://angular.dev/
|
|
4
4
|
* License: MIT
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import { ɵsetRootDomAdapter as _setRootDomAdapter, DOCUMENT, XhrFactory, PlatformLocation, ɵgetDOM as _getDOM, ɵPLATFORM_SERVER_ID as _PLATFORM_SERVER_ID, ViewportScroller, ɵNullViewportScroller as _NullViewportScroller } from '@angular/common';
|
|
8
8
|
import * as i0 from '@angular/core';
|
|
9
|
-
import { InjectionToken, inject, Injector, ɵstartMeasuring as _startMeasuring, ɵstopMeasuring as _stopMeasuring, Injectable, Inject, Optional, APP_ID, TransferState, PLATFORM_ID, PLATFORM_INITIALIZER, NgModule, ɵsetDocument as _setDocument, createPlatformFactory, platformCore, Testability, ɵTESTABILITY as _TESTABILITY } from '@angular/core';
|
|
9
|
+
import { ɵRuntimeError as _RuntimeError, InjectionToken, inject, Injector, ɵstartMeasuring as _startMeasuring, ɵstopMeasuring as _stopMeasuring, Injectable, Inject, Optional, APP_ID, TransferState, PLATFORM_ID, PLATFORM_INITIALIZER, NgModule, ɵsetDocument as _setDocument, createPlatformFactory, platformCore, Testability, ɵTESTABILITY as _TESTABILITY } from '@angular/core';
|
|
10
10
|
import { ɵBrowserDomAdapter as _BrowserDomAdapter, EventManagerPlugin, EVENT_MANAGER_PLUGINS, BrowserModule } from '@angular/platform-browser';
|
|
11
11
|
import { ɵHTTP_ROOT_INTERCEPTOR_FNS as _HTTP_ROOT_INTERCEPTOR_FNS } from '@angular/common/http';
|
|
12
12
|
import { Subject } from 'rxjs';
|
|
@@ -757,6 +757,7 @@ function requireNodeUtils () {
|
|
|
757
757
|
XMP: true,
|
|
758
758
|
IFRAME: true,
|
|
759
759
|
NOEMBED: true,
|
|
760
|
+
NOSCRIPT: true,
|
|
760
761
|
NOFRAMES: true,
|
|
761
762
|
PLAINTEXT: true
|
|
762
763
|
};
|
|
@@ -865,12 +866,15 @@ function requireNodeUtils () {
|
|
|
865
866
|
if (!rawText.toLowerCase().includes(parentClosingTag)) {
|
|
866
867
|
return rawText; // fast path
|
|
867
868
|
}
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
return
|
|
869
|
+
// Replace via String.prototype.replace so we don't have to reconcile
|
|
870
|
+
// UTF-16 code-unit offsets (match.index) with code-point indexing
|
|
871
|
+
// (`[...rawText]`). Astral characters (e.g. emoji) before the match
|
|
872
|
+
// would otherwise shift the replacement and leave a real `</tag>`
|
|
873
|
+
// break-out in the output.
|
|
874
|
+
return rawText.replace(
|
|
875
|
+
new RegExp(parentClosingTag, 'ig'),
|
|
876
|
+
(m) => '<' + m.slice(1)
|
|
877
|
+
);
|
|
874
878
|
}
|
|
875
879
|
|
|
876
880
|
const CLOSING_COMMENT_REGEXP = /--!?>/;
|
|
@@ -919,7 +923,8 @@ function requireNodeUtils () {
|
|
|
919
923
|
var ss = kid.serialize();
|
|
920
924
|
// If an element can have raw content, this content may
|
|
921
925
|
// potentially require escaping to avoid XSS.
|
|
922
|
-
|
|
926
|
+
var upperTag = tagname.toUpperCase();
|
|
927
|
+
if (hasRawContent[upperTag]) {
|
|
923
928
|
ss = escapeMatchingClosingTag(ss, tagname);
|
|
924
929
|
}
|
|
925
930
|
if (html && extraNewLine[tagname] && ss.charAt(0)==='\n') s += '\n';
|
|
@@ -937,8 +942,7 @@ function requireNodeUtils () {
|
|
|
937
942
|
else
|
|
938
943
|
parenttag = '';
|
|
939
944
|
|
|
940
|
-
if (hasRawContent[parenttag]
|
|
941
|
-
(parenttag==='NOSCRIPT' && parent.ownerDocument._scripting_enabled)) {
|
|
945
|
+
if (hasRawContent[parenttag]) {
|
|
942
946
|
s += kid.data;
|
|
943
947
|
} else {
|
|
944
948
|
s += escape(kid.data);
|
|
@@ -3618,9 +3622,9 @@ function requireElement () {
|
|
|
3618
3622
|
ContainerNode.call(this);
|
|
3619
3623
|
this.nodeType = Node.ELEMENT_NODE;
|
|
3620
3624
|
this.ownerDocument = doc;
|
|
3621
|
-
this.
|
|
3625
|
+
this._localName = localName;
|
|
3622
3626
|
this.namespaceURI = namespaceURI;
|
|
3623
|
-
this.
|
|
3627
|
+
this._prefix = prefix;
|
|
3624
3628
|
this._tagName = undefined;
|
|
3625
3629
|
|
|
3626
3630
|
// These properties maintain the set of attributes
|
|
@@ -3640,6 +3644,14 @@ function requireElement () {
|
|
|
3640
3644
|
}
|
|
3641
3645
|
|
|
3642
3646
|
Element.prototype = Object.create(ContainerNode.prototype, {
|
|
3647
|
+
localName: {
|
|
3648
|
+
get: function () { return this._localName; },
|
|
3649
|
+
set: function () { /* no-op per spec */ }
|
|
3650
|
+
},
|
|
3651
|
+
prefix: {
|
|
3652
|
+
get: function () { return this._prefix; },
|
|
3653
|
+
set: function () { /* no-op per spec */ }
|
|
3654
|
+
},
|
|
3643
3655
|
isHTML: { get: function isHTML() {
|
|
3644
3656
|
return this.namespaceURI === NAMESPACE.HTML && this.ownerDocument.isHTML;
|
|
3645
3657
|
}},
|
|
@@ -3662,7 +3674,9 @@ function requireElement () {
|
|
|
3662
3674
|
this._tagName = tn;
|
|
3663
3675
|
}
|
|
3664
3676
|
return this._tagName;
|
|
3665
|
-
|
|
3677
|
+
},
|
|
3678
|
+
set: function () { /* no-op per spec */ }
|
|
3679
|
+
},
|
|
3666
3680
|
nodeName: { get: function() { return this.tagName; }},
|
|
3667
3681
|
nodeValue: {
|
|
3668
3682
|
get: function() {
|
|
@@ -4568,8 +4582,8 @@ function requireElement () {
|
|
|
4568
4582
|
function Attr(elt, lname, prefix, namespace, value) {
|
|
4569
4583
|
// localName and namespace are constant for any attr object.
|
|
4570
4584
|
// But value may change. And so can prefix, and so, therefore can name.
|
|
4571
|
-
this.
|
|
4572
|
-
this.
|
|
4585
|
+
this._localName = lname;
|
|
4586
|
+
this._prefix = (prefix===null || prefix==='') ? null : ('' + prefix);
|
|
4573
4587
|
this.namespaceURI = (namespace===null || namespace==='') ? null : ('' + namespace);
|
|
4574
4588
|
this.data = value;
|
|
4575
4589
|
// Set ownerElement last to ensure it is hooked up to onchange handler
|
|
@@ -4578,6 +4592,14 @@ function requireElement () {
|
|
|
4578
4592
|
|
|
4579
4593
|
// In DOM 3 Attr was supposed to extend Node; in DOM 4 that was abandoned.
|
|
4580
4594
|
Attr.prototype = Object.create(Object.prototype, {
|
|
4595
|
+
localName: {
|
|
4596
|
+
get: function () { return this._localName; },
|
|
4597
|
+
set: function () { /* no-op per spec */ }
|
|
4598
|
+
},
|
|
4599
|
+
prefix: {
|
|
4600
|
+
get: function () { return this._prefix; },
|
|
4601
|
+
set: function () { /* no-op per spec */ }
|
|
4602
|
+
},
|
|
4581
4603
|
ownerElement: {
|
|
4582
4604
|
get: function() { return this._ownerElement; },
|
|
4583
4605
|
},
|
|
@@ -5210,7 +5232,7 @@ function requireProcessingInstruction () {
|
|
|
5210
5232
|
CharacterData.call(this);
|
|
5211
5233
|
this.nodeType = Node.PROCESSING_INSTRUCTION_NODE;
|
|
5212
5234
|
this.ownerDocument = doc;
|
|
5213
|
-
this.
|
|
5235
|
+
this._target = target;
|
|
5214
5236
|
this._data = data;
|
|
5215
5237
|
}
|
|
5216
5238
|
|
|
@@ -5224,6 +5246,10 @@ function requireProcessingInstruction () {
|
|
|
5224
5246
|
};
|
|
5225
5247
|
|
|
5226
5248
|
ProcessingInstruction.prototype = Object.create(CharacterData.prototype, {
|
|
5249
|
+
target: {
|
|
5250
|
+
get: function () { return this._target; },
|
|
5251
|
+
set: function () { /* no-op per spec */ }
|
|
5252
|
+
},
|
|
5227
5253
|
nodeName: { get: function() { return this.target; }},
|
|
5228
5254
|
nodeValue: nodeValue,
|
|
5229
5255
|
textContent: nodeValue,
|
|
@@ -9389,12 +9415,16 @@ function requireDocumentType () {
|
|
|
9389
9415
|
Leaf.call(this);
|
|
9390
9416
|
this.nodeType = Node.DOCUMENT_TYPE_NODE;
|
|
9391
9417
|
this.ownerDocument = ownerDocument || null;
|
|
9392
|
-
this.
|
|
9418
|
+
this._name = name;
|
|
9393
9419
|
this.publicId = publicId || "";
|
|
9394
9420
|
this.systemId = systemId || "";
|
|
9395
9421
|
}
|
|
9396
9422
|
|
|
9397
9423
|
DocumentType.prototype = Object.create(Leaf.prototype, {
|
|
9424
|
+
name: {
|
|
9425
|
+
get: function() { return this._name; },
|
|
9426
|
+
set: function() { /* no-op per spec */ }
|
|
9427
|
+
},
|
|
9398
9428
|
nodeName: { get: function() { return this.name; }},
|
|
9399
9429
|
nodeValue: {
|
|
9400
9430
|
get: function() { return null; },
|
|
@@ -17154,7 +17184,7 @@ class DominoAdapter extends _BrowserDomAdapter {
|
|
|
17154
17184
|
return 'Fake user agent';
|
|
17155
17185
|
}
|
|
17156
17186
|
getCookie(name) {
|
|
17157
|
-
throw new
|
|
17187
|
+
throw new _RuntimeError(5700 /* RuntimeErrorCode.GET_COOKIE_NOT_IMPLEMENTED */, (typeof ngDevMode === 'undefined' || ngDevMode) && 'getCookie has not been implemented');
|
|
17158
17188
|
}
|
|
17159
17189
|
}
|
|
17160
17190
|
|
|
@@ -17190,7 +17220,8 @@ class PlatformState {
|
|
|
17190
17220
|
*/
|
|
17191
17221
|
renderToString() {
|
|
17192
17222
|
if (ngDevMode && !this._enableDomEmulation && !window?.document) {
|
|
17193
|
-
throw new
|
|
17223
|
+
throw new _RuntimeError(5704 /* RuntimeErrorCode.DISABLED_DOM_EMULATION_IN_NON_BROWSER */, (typeof ngDevMode === 'undefined' || ngDevMode) &&
|
|
17224
|
+
'Disabled DOM emulation should only run in browser environments');
|
|
17194
17225
|
}
|
|
17195
17226
|
const measuringLabel = 'renderToString';
|
|
17196
17227
|
_startMeasuring(measuringLabel);
|
|
@@ -17207,10 +17238,10 @@ class PlatformState {
|
|
|
17207
17238
|
getDocument() {
|
|
17208
17239
|
return this._doc;
|
|
17209
17240
|
}
|
|
17210
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
17211
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.
|
|
17241
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: PlatformState, deps: [{ token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
17242
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: PlatformState });
|
|
17212
17243
|
}
|
|
17213
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
17244
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: PlatformState, decorators: [{
|
|
17214
17245
|
type: Injectable
|
|
17215
17246
|
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
|
17216
17247
|
type: Inject,
|
|
@@ -17220,6 +17251,89 @@ function enableDomEmulation(injector) {
|
|
|
17220
17251
|
return injector.get(ENABLE_DOM_EMULATION, true);
|
|
17221
17252
|
}
|
|
17222
17253
|
|
|
17254
|
+
/**
|
|
17255
|
+
* Matches http: or https:
|
|
17256
|
+
*/
|
|
17257
|
+
const HTTP_OR_HTTPS_PROTOCOL_REGEX = /^https?:/i;
|
|
17258
|
+
function parseUrl(urlStr, origin, options = {}) {
|
|
17259
|
+
const originUrl = typeof origin === 'string' ? new URL('/', origin) : origin;
|
|
17260
|
+
if (!urlStr) {
|
|
17261
|
+
return originUrl || null;
|
|
17262
|
+
}
|
|
17263
|
+
urlStr = urlStr.trim();
|
|
17264
|
+
// Fast-path: if the URL is a valid, standard absolute URL, parse and return it immediately.
|
|
17265
|
+
let resolved;
|
|
17266
|
+
try {
|
|
17267
|
+
resolved = new URL(urlStr);
|
|
17268
|
+
}
|
|
17269
|
+
catch { }
|
|
17270
|
+
const { allowProtocolRelative = false, allowOriginChange = true } = options;
|
|
17271
|
+
if (resolved) {
|
|
17272
|
+
if (originUrl && !isSafeOriginChange(resolved, originUrl, urlStr, allowOriginChange)) {
|
|
17273
|
+
throwSuspiciousUrlError(urlStr);
|
|
17274
|
+
}
|
|
17275
|
+
return resolved;
|
|
17276
|
+
}
|
|
17277
|
+
// We identify and throw on malformed absolute URLs (like double port).
|
|
17278
|
+
// Per the WHATWG URL standard, parsing an input starting with a scheme (like 'http:') against
|
|
17279
|
+
// a standard base (like 'http://fake') ignores the base argument and parses strictly as an
|
|
17280
|
+
// absolute URL. Since it is malformed, the native URL constructor will throw a validation
|
|
17281
|
+
// error. Standard relative/protocol-relative paths parse successfully, allowing the flow to continue.
|
|
17282
|
+
if (!URL.canParse(urlStr, 'http://fake')) {
|
|
17283
|
+
throw new _RuntimeError(5701 /* RuntimeErrorCode.INVALID_URL */, typeof ngDevMode === 'undefined' || ngDevMode ? `Invalid URL: ${urlStr}` : urlStr);
|
|
17284
|
+
}
|
|
17285
|
+
if (!originUrl) {
|
|
17286
|
+
return null;
|
|
17287
|
+
}
|
|
17288
|
+
// Check if we have a legitimate protocol-relative URL (starts with '//' and not a duplicate/backslash bypass)
|
|
17289
|
+
// and we are configured to allow and preserve standard cross-origin protocol-relative requests.
|
|
17290
|
+
if (urlStr.startsWith('//')) {
|
|
17291
|
+
if (!allowProtocolRelative) {
|
|
17292
|
+
throw new _RuntimeError(5702 /* RuntimeErrorCode.PROTOCOL_RELATIVE_URL_NOT_ALLOWED */, typeof ngDevMode === 'undefined' || ngDevMode
|
|
17293
|
+
? `Protocol relative URLs are not allowed in this context. URL: ${urlStr}`
|
|
17294
|
+
: urlStr);
|
|
17295
|
+
}
|
|
17296
|
+
return new URL(urlStr, origin);
|
|
17297
|
+
}
|
|
17298
|
+
resolved = new URL(urlStr, origin);
|
|
17299
|
+
if (!isSafeOriginChange(resolved, originUrl, urlStr, allowOriginChange)) {
|
|
17300
|
+
throwSuspiciousUrlError(urlStr);
|
|
17301
|
+
}
|
|
17302
|
+
return resolved;
|
|
17303
|
+
}
|
|
17304
|
+
/**
|
|
17305
|
+
* Throws a suspicious URL error indicating a security bypass attempt.
|
|
17306
|
+
*/
|
|
17307
|
+
function throwSuspiciousUrlError(urlStr) {
|
|
17308
|
+
throw new _RuntimeError(5703 /* RuntimeErrorCode.SUSPICIOUS_URL_CHANGE_ORIGIN */, typeof ngDevMode === 'undefined' || ngDevMode
|
|
17309
|
+
? `URL ${urlStr} changed origin unexpectedly. This is suspicious and may indicate a security bypass attempt.`
|
|
17310
|
+
: urlStr);
|
|
17311
|
+
}
|
|
17312
|
+
/**
|
|
17313
|
+
* Checks if the origin has changed in a safe way.
|
|
17314
|
+
*
|
|
17315
|
+
* @param resolved The resolved URL.
|
|
17316
|
+
* @param origin The origin URL.
|
|
17317
|
+
* @param urlStr The URL string.
|
|
17318
|
+
* @param allowOriginChange Whether to allow origin changes.
|
|
17319
|
+
* @returns True if the origin has changed in a safe way, false otherwise.
|
|
17320
|
+
*/
|
|
17321
|
+
function isSafeOriginChange(resolved, origin, urlStr, allowOriginChange) {
|
|
17322
|
+
if (origin.origin === resolved.origin) {
|
|
17323
|
+
return true;
|
|
17324
|
+
}
|
|
17325
|
+
if (!allowOriginChange) {
|
|
17326
|
+
return false;
|
|
17327
|
+
}
|
|
17328
|
+
return HTTP_OR_HTTPS_PROTOCOL_REGEX.test(urlStr);
|
|
17329
|
+
}
|
|
17330
|
+
|
|
17331
|
+
/**
|
|
17332
|
+
* @deprecated Use the HttpClient fetch backend (by enabling `withFetch()`) instead.
|
|
17333
|
+
* XHR support in `@angular/platform-server` is deprecated because the underlying `xhr2`
|
|
17334
|
+
* library does not safely handle redirects (e.g. it can forward `Authorization` headers
|
|
17335
|
+
* on cross-origin redirects and is susceptible to denial-of-service (DoS) via redirect loops).
|
|
17336
|
+
*/
|
|
17223
17337
|
class ServerXhr {
|
|
17224
17338
|
xhrImpl;
|
|
17225
17339
|
// The `xhr2` dependency has a side-effect of accessing and modifying a
|
|
@@ -17228,6 +17342,13 @@ class ServerXhr {
|
|
|
17228
17342
|
// server platform (via shims, etc).
|
|
17229
17343
|
async ɵloadImpl() {
|
|
17230
17344
|
if (!this.xhrImpl) {
|
|
17345
|
+
if (typeof ngDevMode === 'undefined' || ngDevMode) {
|
|
17346
|
+
console.warn('XHR support in `@angular/platform-server` is deprecated and will be removed ' +
|
|
17347
|
+
'in a future version of Angular. It has known security and performance issues in server ' +
|
|
17348
|
+
'environments, such as forwarding `Authorization` headers on cross-origin ' +
|
|
17349
|
+
'redirects and susceptibility to denial-of-service (DoS) via redirect loops. ' +
|
|
17350
|
+
'Please enable the HttpClient fetch backend instead by using `withFetch()`.');
|
|
17351
|
+
}
|
|
17231
17352
|
const { default: xhr } = await import('xhr2');
|
|
17232
17353
|
this.xhrImpl = xhr;
|
|
17233
17354
|
}
|
|
@@ -17235,17 +17356,27 @@ class ServerXhr {
|
|
|
17235
17356
|
build() {
|
|
17236
17357
|
const impl = this.xhrImpl;
|
|
17237
17358
|
if (!impl) {
|
|
17238
|
-
throw new
|
|
17359
|
+
throw new _RuntimeError(5705 /* RuntimeErrorCode.XHR_NOT_LOADED */, (typeof ngDevMode === 'undefined' || ngDevMode) &&
|
|
17360
|
+
'Unexpected state in ServerXhr: XHR implementation is not loaded.');
|
|
17239
17361
|
}
|
|
17240
17362
|
return new impl.XMLHttpRequest();
|
|
17241
17363
|
}
|
|
17242
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
17243
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.
|
|
17364
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: ServerXhr, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
17365
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: ServerXhr });
|
|
17244
17366
|
}
|
|
17245
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
17367
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: ServerXhr, decorators: [{
|
|
17246
17368
|
type: Injectable
|
|
17247
17369
|
}] });
|
|
17370
|
+
/**
|
|
17371
|
+
* Regex to match a URL schema.
|
|
17372
|
+
*/
|
|
17373
|
+
const URL_SCHEMA_REGEXP = /^(?:[a-zA-Z][a-zA-Z0-9+\-.]*:)/;
|
|
17248
17374
|
function relativeUrlsTransformerInterceptorFn(request, next) {
|
|
17375
|
+
const trimmedUrl = request.url.trim();
|
|
17376
|
+
if (URL_SCHEMA_REGEXP.test(trimmedUrl)) {
|
|
17377
|
+
// URLs with a schema should be left unchanged.
|
|
17378
|
+
return next(request);
|
|
17379
|
+
}
|
|
17249
17380
|
const platformLocation = inject(PlatformLocation);
|
|
17250
17381
|
const { href, protocol, hostname, port } = platformLocation;
|
|
17251
17382
|
if (!protocol.startsWith('http')) {
|
|
@@ -17257,8 +17388,10 @@ function relativeUrlsTransformerInterceptorFn(request, next) {
|
|
|
17257
17388
|
}
|
|
17258
17389
|
const baseHref = platformLocation.getBaseHrefFromDOM() || href;
|
|
17259
17390
|
const baseUrl = new URL(baseHref, urlPrefix);
|
|
17260
|
-
const
|
|
17261
|
-
|
|
17391
|
+
const parsedUrl = parseUrl(request.url, baseUrl, {
|
|
17392
|
+
allowProtocolRelative: true,
|
|
17393
|
+
});
|
|
17394
|
+
return next(request.clone({ url: parsedUrl.toString() }));
|
|
17262
17395
|
}
|
|
17263
17396
|
const SERVER_HTTP_PROVIDERS = [
|
|
17264
17397
|
{ provide: XhrFactory, useClass: ServerXhr },
|
|
@@ -17269,27 +17402,6 @@ const SERVER_HTTP_PROVIDERS = [
|
|
|
17269
17402
|
},
|
|
17270
17403
|
];
|
|
17271
17404
|
|
|
17272
|
-
const LEADING_SLASHES_REGEX = /^[/\\]+/;
|
|
17273
|
-
function parseUrl(urlStr, origin) {
|
|
17274
|
-
if (!urlStr) {
|
|
17275
|
-
return origin !== undefined ? new URL('/', origin) : null;
|
|
17276
|
-
}
|
|
17277
|
-
if (URL.canParse(urlStr)) {
|
|
17278
|
-
return new URL(urlStr);
|
|
17279
|
-
}
|
|
17280
|
-
if (/^[a-zA-Z][a-zA-Z0-9+.-]*:(\/\/|\\\\)/.test(urlStr)) {
|
|
17281
|
-
throw new Error(`Invalid URL: ${urlStr}`);
|
|
17282
|
-
}
|
|
17283
|
-
if (origin === undefined) {
|
|
17284
|
-
return null;
|
|
17285
|
-
}
|
|
17286
|
-
let normalizedPath = urlStr.replace(LEADING_SLASHES_REGEX, '/');
|
|
17287
|
-
if (normalizedPath[0] !== '/') {
|
|
17288
|
-
normalizedPath = `/${normalizedPath}`;
|
|
17289
|
-
}
|
|
17290
|
-
return new URL(normalizedPath, origin);
|
|
17291
|
-
}
|
|
17292
|
-
|
|
17293
17405
|
/**
|
|
17294
17406
|
* Server-side implementation of URL state. Implements `pathname`, `search`, and `hash`
|
|
17295
17407
|
* but not the state stack.
|
|
@@ -17304,14 +17416,13 @@ class ServerPlatformLocation {
|
|
|
17304
17416
|
search = '';
|
|
17305
17417
|
hash = '';
|
|
17306
17418
|
_hashUpdate = new Subject();
|
|
17419
|
+
origin;
|
|
17307
17420
|
constructor(_doc, _config) {
|
|
17308
17421
|
this._doc = _doc;
|
|
17422
|
+
let origin = this._doc.location.origin;
|
|
17309
17423
|
const config = _config;
|
|
17310
|
-
if (
|
|
17311
|
-
|
|
17312
|
-
}
|
|
17313
|
-
if (config.url) {
|
|
17314
|
-
const { protocol, hostname, port, pathname, search, hash, href } = parseUrl(config.url, this._doc.location.origin);
|
|
17424
|
+
if (config && config.url) {
|
|
17425
|
+
const { protocol, hostname, port, pathname, search, hash, href, origin: parsedOrigin, } = parseUrl(config.url, origin);
|
|
17315
17426
|
this.protocol = protocol;
|
|
17316
17427
|
this.hostname = hostname;
|
|
17317
17428
|
this.port = port;
|
|
@@ -17319,7 +17430,9 @@ class ServerPlatformLocation {
|
|
|
17319
17430
|
this.search = search;
|
|
17320
17431
|
this.hash = hash;
|
|
17321
17432
|
this.href = href;
|
|
17433
|
+
origin = parsedOrigin;
|
|
17322
17434
|
}
|
|
17435
|
+
this.origin = origin;
|
|
17323
17436
|
}
|
|
17324
17437
|
getBaseHrefFromDOM() {
|
|
17325
17438
|
return _getDOM().getBaseHref(this._doc);
|
|
@@ -17352,7 +17465,9 @@ class ServerPlatformLocation {
|
|
|
17352
17465
|
}
|
|
17353
17466
|
replaceState(state, title, newUrl) {
|
|
17354
17467
|
const oldUrl = this.url;
|
|
17355
|
-
const { pathname, search, hash, href, protocol } = parseUrl(newUrl, this.
|
|
17468
|
+
const { pathname, search, hash, href, protocol } = parseUrl(newUrl, this.origin, {
|
|
17469
|
+
allowOriginChange: false,
|
|
17470
|
+
});
|
|
17356
17471
|
const writableThis = this;
|
|
17357
17472
|
writableThis.pathname = pathname;
|
|
17358
17473
|
writableThis.search = search;
|
|
@@ -17373,10 +17488,10 @@ class ServerPlatformLocation {
|
|
|
17373
17488
|
getState() {
|
|
17374
17489
|
return undefined;
|
|
17375
17490
|
}
|
|
17376
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
17377
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.
|
|
17491
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: ServerPlatformLocation, deps: [{ token: DOCUMENT }, { token: INITIAL_CONFIG, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
17492
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: ServerPlatformLocation });
|
|
17378
17493
|
}
|
|
17379
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
17494
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: ServerPlatformLocation, decorators: [{
|
|
17380
17495
|
type: Injectable
|
|
17381
17496
|
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
|
17382
17497
|
type: Inject,
|
|
@@ -17401,10 +17516,10 @@ class ServerEventManagerPlugin extends EventManagerPlugin {
|
|
|
17401
17516
|
addEventListener(element, eventName, handler, options) {
|
|
17402
17517
|
return _getDOM().onAndCancel(element, eventName, handler, options);
|
|
17403
17518
|
}
|
|
17404
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
17405
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.
|
|
17519
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: ServerEventManagerPlugin, deps: [{ token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
17520
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: ServerEventManagerPlugin });
|
|
17406
17521
|
}
|
|
17407
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
17522
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: ServerEventManagerPlugin, decorators: [{
|
|
17408
17523
|
type: Injectable
|
|
17409
17524
|
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
|
17410
17525
|
type: Inject,
|
|
@@ -17517,11 +17632,11 @@ const PLATFORM_SERVER_PROVIDERS = [
|
|
|
17517
17632
|
* @publicApi
|
|
17518
17633
|
*/
|
|
17519
17634
|
class ServerModule {
|
|
17520
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
17521
|
-
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.
|
|
17522
|
-
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.
|
|
17635
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: ServerModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
17636
|
+
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.25", ngImport: i0, type: ServerModule, exports: [BrowserModule] });
|
|
17637
|
+
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: ServerModule, providers: PLATFORM_SERVER_PROVIDERS, imports: [BrowserModule] });
|
|
17523
17638
|
}
|
|
17524
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
17639
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: ServerModule, decorators: [{
|
|
17525
17640
|
type: NgModule,
|
|
17526
17641
|
args: [{
|
|
17527
17642
|
exports: [BrowserModule],
|
|
@@ -17536,7 +17651,12 @@ function _document(injector) {
|
|
|
17536
17651
|
document =
|
|
17537
17652
|
typeof config.document === 'string'
|
|
17538
17653
|
? _enableDomEmulation
|
|
17539
|
-
? parseDocument(config.document, config.url !== undefined
|
|
17654
|
+
? parseDocument(config.document, config.url !== undefined
|
|
17655
|
+
? // A fallback same-origin base ('http://localhost') is provided so that relative
|
|
17656
|
+
// page URLs are parsed and resolved as same-origin paths, preventing empty
|
|
17657
|
+
// or invalid location values in the parsed virtual DOM document.
|
|
17658
|
+
parseUrl(config.url, 'http://localhost').href
|
|
17659
|
+
: undefined)
|
|
17540
17660
|
: window.document
|
|
17541
17661
|
: config.document;
|
|
17542
17662
|
}
|