@angular/platform-server 20.3.23 → 20.3.24
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 +2 -2
- package/fesm2022/platform-server.mjs.map +1 -1
- package/fesm2022/server.mjs +148 -57
- package/fesm2022/server.mjs.map +1 -1
- package/fesm2022/testing.mjs +5 -5
- package/index.d.ts +1 -1
- package/init/index.d.ts +1 -1
- package/package.json +5 -5
- package/testing/index.d.ts +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @license Angular v20.3.
|
|
2
|
+
* @license Angular v20.3.24
|
|
3
3
|
* (c) 2010-2025 Google LLC. https://angular.dev/
|
|
4
4
|
* License: MIT
|
|
5
5
|
*/
|
|
@@ -357,7 +357,7 @@ function isHostAllowed(hostname, allowedHosts) {
|
|
|
357
357
|
/**
|
|
358
358
|
* @publicApi
|
|
359
359
|
*/
|
|
360
|
-
const VERSION = /* @__PURE__ */ new Version('20.3.
|
|
360
|
+
const VERSION = /* @__PURE__ */ new Version('20.3.24');
|
|
361
361
|
|
|
362
362
|
export { BEFORE_APP_SERIALIZED, INITIAL_CONFIG, PlatformState, VERSION, platformServer, provideServerRendering, renderApplication, renderModule, SERVER_CONTEXT as ɵSERVER_CONTEXT, isHostAllowed as ɵisHostAllowed, renderInternal as ɵrenderInternal };
|
|
363
363
|
//# 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":["../../../../../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.24');\n"],"names":["startMeasuring","stopMeasuring","IS_HYDRATION_DOM_REUSE_ENABLED","annotateForHydration","SSR_CONTENT_INTEGRITY_MARKER"],"mappings":"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"}
|
package/fesm2022/server.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @license Angular v20.3.
|
|
2
|
+
* @license Angular v20.3.24
|
|
3
3
|
* (c) 2010-2025 Google LLC. https://angular.dev/
|
|
4
4
|
* License: MIT
|
|
5
5
|
*/
|
|
@@ -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; },
|
|
@@ -17207,10 +17237,10 @@ class PlatformState {
|
|
|
17207
17237
|
getDocument() {
|
|
17208
17238
|
return this._doc;
|
|
17209
17239
|
}
|
|
17210
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
17211
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.
|
|
17240
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: PlatformState, deps: [{ token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
17241
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: PlatformState });
|
|
17212
17242
|
}
|
|
17213
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
17243
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: PlatformState, decorators: [{
|
|
17214
17244
|
type: Injectable
|
|
17215
17245
|
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
|
17216
17246
|
type: Inject,
|
|
@@ -17220,6 +17250,72 @@ function enableDomEmulation(injector) {
|
|
|
17220
17250
|
return injector.get(ENABLE_DOM_EMULATION, true);
|
|
17221
17251
|
}
|
|
17222
17252
|
|
|
17253
|
+
/**
|
|
17254
|
+
* Matches http: or https:
|
|
17255
|
+
*/
|
|
17256
|
+
const HTTP_OR_HTTPS_PROTOCOL_REGEX = /^https?:/i;
|
|
17257
|
+
function parseUrl(urlStr, origin, options = {}) {
|
|
17258
|
+
const originUrl = typeof origin === 'string' ? new URL('/', origin) : origin;
|
|
17259
|
+
if (!urlStr) {
|
|
17260
|
+
return originUrl || null;
|
|
17261
|
+
}
|
|
17262
|
+
urlStr = urlStr.trim();
|
|
17263
|
+
// Fast-path: if the URL is a valid, standard absolute URL, parse and return it immediately.
|
|
17264
|
+
let resolved;
|
|
17265
|
+
try {
|
|
17266
|
+
resolved = new URL(urlStr);
|
|
17267
|
+
}
|
|
17268
|
+
catch { }
|
|
17269
|
+
if (resolved) {
|
|
17270
|
+
if (originUrl && !isSafeOriginChange(resolved, originUrl, urlStr)) {
|
|
17271
|
+
throwSuspiciousUrlError(urlStr);
|
|
17272
|
+
}
|
|
17273
|
+
return resolved;
|
|
17274
|
+
}
|
|
17275
|
+
// We identify and throw on malformed absolute URLs (like double port).
|
|
17276
|
+
// Per the WHATWG URL standard, parsing an input starting with a scheme (like 'http:') against
|
|
17277
|
+
// a standard base (like 'http://fake') ignores the base argument and parses strictly as an
|
|
17278
|
+
// absolute URL. Since it is malformed, the native URL constructor will throw a validation
|
|
17279
|
+
// error. Standard relative/protocol-relative paths parse successfully, allowing the flow to continue.
|
|
17280
|
+
if (!URL.canParse(urlStr, 'http://fake')) {
|
|
17281
|
+
throw new Error(`Invalid URL: ${urlStr}`);
|
|
17282
|
+
}
|
|
17283
|
+
if (!originUrl) {
|
|
17284
|
+
return null;
|
|
17285
|
+
}
|
|
17286
|
+
const { allowProtocolRelative = false } = options;
|
|
17287
|
+
// Check if we have a legitimate protocol-relative URL (starts with '//' and not a duplicate/backslash bypass)
|
|
17288
|
+
// and we are configured to allow and preserve standard cross-origin protocol-relative requests.
|
|
17289
|
+
if (urlStr.startsWith('//')) {
|
|
17290
|
+
if (!allowProtocolRelative) {
|
|
17291
|
+
throw new Error(`Protocol relative URLs are not allowed in this context. URL: ${urlStr}`);
|
|
17292
|
+
}
|
|
17293
|
+
return new URL(urlStr, origin);
|
|
17294
|
+
}
|
|
17295
|
+
resolved = new URL(urlStr, origin);
|
|
17296
|
+
if (!isSafeOriginChange(resolved, originUrl, urlStr)) {
|
|
17297
|
+
throwSuspiciousUrlError(urlStr);
|
|
17298
|
+
}
|
|
17299
|
+
return resolved;
|
|
17300
|
+
}
|
|
17301
|
+
/**
|
|
17302
|
+
* Throws a suspicious URL error indicating a security bypass attempt.
|
|
17303
|
+
*/
|
|
17304
|
+
function throwSuspiciousUrlError(urlStr) {
|
|
17305
|
+
throw new Error(`URL ${urlStr} changed origin unexpectedly. This is suspicious and may indicate a security bypass attempt.`);
|
|
17306
|
+
}
|
|
17307
|
+
/**
|
|
17308
|
+
* Checks if the origin has changed in a safe way.
|
|
17309
|
+
*
|
|
17310
|
+
* @param resolved The resolved URL.
|
|
17311
|
+
* @param origin The origin URL.
|
|
17312
|
+
* @param urlStr The URL string.
|
|
17313
|
+
* @returns True if the origin has changed in a safe way, false otherwise.
|
|
17314
|
+
*/
|
|
17315
|
+
function isSafeOriginChange(resolved, origin, urlStr) {
|
|
17316
|
+
return origin.origin === resolved.origin || HTTP_OR_HTTPS_PROTOCOL_REGEX.test(urlStr);
|
|
17317
|
+
}
|
|
17318
|
+
|
|
17223
17319
|
class ServerXhr {
|
|
17224
17320
|
xhrImpl;
|
|
17225
17321
|
// The `xhr2` dependency has a side-effect of accessing and modifying a
|
|
@@ -17239,13 +17335,22 @@ class ServerXhr {
|
|
|
17239
17335
|
}
|
|
17240
17336
|
return new impl.XMLHttpRequest();
|
|
17241
17337
|
}
|
|
17242
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
17243
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.
|
|
17338
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: ServerXhr, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
17339
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: ServerXhr });
|
|
17244
17340
|
}
|
|
17245
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
17341
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: ServerXhr, decorators: [{
|
|
17246
17342
|
type: Injectable
|
|
17247
17343
|
}] });
|
|
17344
|
+
/**
|
|
17345
|
+
* Regex to match a URL schema.
|
|
17346
|
+
*/
|
|
17347
|
+
const URL_SCHEMA_REGEXP = /^(?:[a-zA-Z][a-zA-Z0-9+\-.]*:)/;
|
|
17248
17348
|
function relativeUrlsTransformerInterceptorFn(request, next) {
|
|
17349
|
+
const trimmedUrl = request.url.trim();
|
|
17350
|
+
if (URL_SCHEMA_REGEXP.test(trimmedUrl)) {
|
|
17351
|
+
// URLs with a schema should be left unchanged.
|
|
17352
|
+
return next(request);
|
|
17353
|
+
}
|
|
17249
17354
|
const platformLocation = inject(PlatformLocation);
|
|
17250
17355
|
const { href, protocol, hostname, port } = platformLocation;
|
|
17251
17356
|
if (!protocol.startsWith('http')) {
|
|
@@ -17257,8 +17362,10 @@ function relativeUrlsTransformerInterceptorFn(request, next) {
|
|
|
17257
17362
|
}
|
|
17258
17363
|
const baseHref = platformLocation.getBaseHrefFromDOM() || href;
|
|
17259
17364
|
const baseUrl = new URL(baseHref, urlPrefix);
|
|
17260
|
-
const
|
|
17261
|
-
|
|
17365
|
+
const parsedUrl = parseUrl(request.url, baseUrl, {
|
|
17366
|
+
allowProtocolRelative: true,
|
|
17367
|
+
});
|
|
17368
|
+
return next(request.clone({ url: parsedUrl.toString() }));
|
|
17262
17369
|
}
|
|
17263
17370
|
const SERVER_HTTP_PROVIDERS = [
|
|
17264
17371
|
{ provide: XhrFactory, useClass: ServerXhr },
|
|
@@ -17269,27 +17376,6 @@ const SERVER_HTTP_PROVIDERS = [
|
|
|
17269
17376
|
},
|
|
17270
17377
|
];
|
|
17271
17378
|
|
|
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
17379
|
/**
|
|
17294
17380
|
* Server-side implementation of URL state. Implements `pathname`, `search`, and `hash`
|
|
17295
17381
|
* but not the state stack.
|
|
@@ -17373,10 +17459,10 @@ class ServerPlatformLocation {
|
|
|
17373
17459
|
getState() {
|
|
17374
17460
|
return undefined;
|
|
17375
17461
|
}
|
|
17376
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
17377
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.
|
|
17462
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: ServerPlatformLocation, deps: [{ token: DOCUMENT }, { token: INITIAL_CONFIG, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
17463
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: ServerPlatformLocation });
|
|
17378
17464
|
}
|
|
17379
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
17465
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: ServerPlatformLocation, decorators: [{
|
|
17380
17466
|
type: Injectable
|
|
17381
17467
|
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
|
17382
17468
|
type: Inject,
|
|
@@ -17401,10 +17487,10 @@ class ServerEventManagerPlugin extends EventManagerPlugin {
|
|
|
17401
17487
|
addEventListener(element, eventName, handler, options) {
|
|
17402
17488
|
return _getDOM().onAndCancel(element, eventName, handler, options);
|
|
17403
17489
|
}
|
|
17404
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
17405
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.
|
|
17490
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: ServerEventManagerPlugin, deps: [{ token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
17491
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: ServerEventManagerPlugin });
|
|
17406
17492
|
}
|
|
17407
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
17493
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: ServerEventManagerPlugin, decorators: [{
|
|
17408
17494
|
type: Injectable
|
|
17409
17495
|
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
|
17410
17496
|
type: Inject,
|
|
@@ -17517,11 +17603,11 @@ const PLATFORM_SERVER_PROVIDERS = [
|
|
|
17517
17603
|
* @publicApi
|
|
17518
17604
|
*/
|
|
17519
17605
|
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.
|
|
17606
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: ServerModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
17607
|
+
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.24", ngImport: i0, type: ServerModule, exports: [BrowserModule] });
|
|
17608
|
+
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: ServerModule, providers: PLATFORM_SERVER_PROVIDERS, imports: [BrowserModule] });
|
|
17523
17609
|
}
|
|
17524
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
17610
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: ServerModule, decorators: [{
|
|
17525
17611
|
type: NgModule,
|
|
17526
17612
|
args: [{
|
|
17527
17613
|
exports: [BrowserModule],
|
|
@@ -17536,7 +17622,12 @@ function _document(injector) {
|
|
|
17536
17622
|
document =
|
|
17537
17623
|
typeof config.document === 'string'
|
|
17538
17624
|
? _enableDomEmulation
|
|
17539
|
-
? parseDocument(config.document, config.url !== undefined
|
|
17625
|
+
? parseDocument(config.document, config.url !== undefined
|
|
17626
|
+
? // A fallback same-origin base ('http://localhost') is provided so that relative
|
|
17627
|
+
// page URLs are parsed and resolved as same-origin paths, preventing empty
|
|
17628
|
+
// or invalid location values in the parsed virtual DOM document.
|
|
17629
|
+
parseUrl(config.url, 'http://localhost').href
|
|
17630
|
+
: undefined)
|
|
17540
17631
|
: window.document
|
|
17541
17632
|
: config.document;
|
|
17542
17633
|
}
|