@@ -14,6 +14,7 @@ import { ServerAssets } from '../assets';
14
14
import { Console } from '../console' ;
15
15
import { AngularAppManifest , getAngularAppManifest } from '../manifest' ;
16
16
import { AngularBootstrap , isNgModule } from '../utils/ng' ;
17
+ import { promiseWithAbort } from '../utils/promise' ;
17
18
import { addTrailingSlash , joinUrlParts , stripLeadingSlash } from '../utils/url' ;
18
19
import {
19
20
PrerenderFallback ,
@@ -521,60 +522,79 @@ export async function getRoutesFromAngularRouterConfig(
521
522
* Asynchronously extracts routes from the Angular application configuration
522
523
* and creates a `RouteTree` to manage server-side routing.
523
524
*
524
- * @param url - The URL for server-side rendering. The URL is used to configure `ServerPlatformLocation`. This configuration is crucial
525
- * for ensuring that API requests for relative paths succeed, which is essential for accurate route extraction.
526
- * See:
527
- * - https://github.com/angular/angular/blob/d608b857c689d17a7ffa33bbb510301014d24a17/packages/platform-server/src/location.ts#L51
528
- * - https://github.com/angular/angular/blob/6882cc7d9eed26d3caeedca027452367ba25f2b9/packages/platform-server/src/http.ts#L44
529
- * @param manifest - An optional `AngularAppManifest` that contains the application's routing and configuration details.
530
- * If not provided, the default manifest is retrieved using `getAngularAppManifest()`.
531
- * @param invokeGetPrerenderParams - A boolean flag indicating whether to invoke `getPrerenderParams` for parameterized SSG routes
532
- * to handle prerendering paths. Defaults to `false`.
533
- * @param includePrerenderFallbackRoutes - A flag indicating whether to include fallback routes in the result. Defaults to `true`.
525
+ * @param options - An object containing the following options:
526
+ * - `url`: The URL for server-side rendering. The URL is used to configure `ServerPlatformLocation`. This configuration is crucial
527
+ * for ensuring that API requests for relative paths succeed, which is essential for accurate route extraction.
528
+ * See:
529
+ * - https://github.com/angular/angular/blob/d608b857c689d17a7ffa33bbb510301014d24a17/packages/platform-server/src/location.ts#L51
530
+ * - https://github.com/angular/angular/blob/6882cc7d9eed26d3caeedca027452367ba25f2b9/packages/platform-server/src/http.ts#L44
531
+ * - `manifest`: An optional `AngularAppManifest` that contains the application's routing and configuration details.
532
+ * If not provided, the default manifest is retrieved using `getAngularAppManifest()`.
533
+ * - `invokeGetPrerenderParams`: A boolean flag indicating whether to invoke `getPrerenderParams` for parameterized SSG routes
534
+ * to handle prerendering paths. Defaults to `false`.
535
+ * - `includePrerenderFallbackRoutes`: A flag indicating whether to include fallback routes in the result. Defaults to `true`.
536
+ * - `signal`: An optional `AbortSignal` that can be used to abort the operation.
534
537
*
535
538
* @returns A promise that resolves to an object containing:
536
539
* - `routeTree`: A populated `RouteTree` containing all extracted routes from the Angular application.
537
540
* - `appShellRoute`: The specified route for the app-shell, if configured.
538
541
* - `errors`: An array of strings representing any errors encountered during the route extraction process.
539
542
*/
540
- export async function extractRoutesAndCreateRouteTree (
541
- url : URL ,
542
- manifest : AngularAppManifest = getAngularAppManifest ( ) ,
543
- invokeGetPrerenderParams = false ,
544
- includePrerenderFallbackRoutes = true ,
545
- ) : Promise < { routeTree : RouteTree ; appShellRoute ?: string ; errors : string [ ] } > {
546
- const routeTree = new RouteTree ( ) ;
547
- const document = await new ServerAssets ( manifest ) . getIndexServerHtml ( ) . text ( ) ;
548
- const bootstrap = await manifest . bootstrap ( ) ;
549
- const { baseHref, appShellRoute, routes, errors } = await getRoutesFromAngularRouterConfig (
550
- bootstrap ,
551
- document ,
543
+ export function extractRoutesAndCreateRouteTree ( options : {
544
+ url : URL ;
545
+ manifest ?: AngularAppManifest ;
546
+ invokeGetPrerenderParams ?: boolean ;
547
+ includePrerenderFallbackRoutes ?: boolean ;
548
+ signal ?: AbortSignal ;
549
+ } ) : Promise < { routeTree : RouteTree ; appShellRoute ?: string ; errors : string [ ] } > {
550
+ const {
552
551
url,
553
- invokeGetPrerenderParams ,
554
- includePrerenderFallbackRoutes ,
555
- ) ;
552
+ manifest = getAngularAppManifest ( ) ,
553
+ invokeGetPrerenderParams = false ,
554
+ includePrerenderFallbackRoutes = true ,
555
+ signal,
556
+ } = options ;
556
557
557
- for ( const { route, ...metadata } of routes ) {
558
- if ( metadata . redirectTo !== undefined ) {
559
- metadata . redirectTo = joinUrlParts ( baseHref , metadata . redirectTo ) ;
560
- }
558
+ async function extract ( ) : Promise < {
559
+ appShellRoute : string | undefined ;
560
+ routeTree : RouteTree < { } > ;
561
+ errors : string [ ] ;
562
+ } > {
563
+ const routeTree = new RouteTree ( ) ;
564
+ const document = await new ServerAssets ( manifest ) . getIndexServerHtml ( ) . text ( ) ;
565
+ const bootstrap = await manifest . bootstrap ( ) ;
566
+ const { baseHref, appShellRoute, routes, errors } = await getRoutesFromAngularRouterConfig (
567
+ bootstrap ,
568
+ document ,
569
+ url ,
570
+ invokeGetPrerenderParams ,
571
+ includePrerenderFallbackRoutes ,
572
+ ) ;
573
+
574
+ for ( const { route, ...metadata } of routes ) {
575
+ if ( metadata . redirectTo !== undefined ) {
576
+ metadata . redirectTo = joinUrlParts ( baseHref , metadata . redirectTo ) ;
577
+ }
561
578
562
- // Remove undefined fields
563
- // Helps avoid unnecessary test updates
564
- for ( const [ key , value ] of Object . entries ( metadata ) ) {
565
- if ( value === undefined ) {
566
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
567
- delete ( metadata as any ) [ key ] ;
579
+ // Remove undefined fields
580
+ // Helps avoid unnecessary test updates
581
+ for ( const [ key , value ] of Object . entries ( metadata ) ) {
582
+ if ( value === undefined ) {
583
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
584
+ delete ( metadata as any ) [ key ] ;
585
+ }
568
586
}
587
+
588
+ const fullRoute = joinUrlParts ( baseHref , route ) ;
589
+ routeTree . insert ( fullRoute , metadata ) ;
569
590
}
570
591
571
- const fullRoute = joinUrlParts ( baseHref , route ) ;
572
- routeTree . insert ( fullRoute , metadata ) ;
592
+ return {
593
+ appShellRoute,
594
+ routeTree,
595
+ errors,
596
+ } ;
573
597
}
574
598
575
- return {
576
- appShellRoute,
577
- routeTree,
578
- errors,
579
- } ;
599
+ return signal ? promiseWithAbort ( extract ( ) , signal , 'Routes extraction' ) : extract ( ) ;
580
600
}
0 commit comments