import { Route , Routes , } from '@angular/router' ; import { DaffExternalRouterInsertionStrategy } from '../../model/insertion-strategy.type' ; import { DaffExternalRouteType } from '../../model/route-type' ; import { DaffRouteWithDataPath } from '../../model/route-with-data-path' ; /**
 * Tests whether or not a route matches a specific Daffodil Route type.
 *
 * See  DaffRouteWithDataPath const routeMatchesRouteType = ( route , type ) : boolean => route ?. data ?. daffExternalRouteType === type ; /**
 * Adds a path to the `daffPaths` of the given route.
 *
 * See  DaffRouteWithDataPath const addRouteToDaffPaths = ( route , path ) => route . data . daffPaths = { ... route . data . daffPaths , [ path ] : path , } ; const operateOnRoute = ( externalRoute ) : ( route : Route ) => Route => ( route ) => addRouteToDaffPaths ( route , externalRoute . path ) ; /**
 * Traverse the router config tree, halting after the first match.
 * This traversal is implemented in a pre-order manner. As such, for large
 * configuration trees, it will be most efficient to place externally routed
 * components at the top of router configuration.
 */ const traverseRouteTree = ( routes = [ ] , matcher , operate ) : Routes => { if ( routes . length === 0 ) { return routes ; } const stack = [ ] ; const treeRoot = { children : routes } ; stack . push ( treeRoot ) ; while ( stack . length ) { const route = stack . pop ( ) ; if ( matcher ( route ) ) { operate ( route ) ; break ; } if ( route . children ) { stack . push ( ... route . children . reverse ( ) ) ; } } return routes ; } ; /**
 * A route insertion strategy that can be used to append external routes onto
 * existing Angular routes. This can be useful when you need to route to
 * an existing lazy-loaded module from multiple externally defined urls.
 *
 * This should be used in combination with the  daffDataPathUrlMatcher to match lazy-loaded modules with
 * associated external urls.
 *
 * For example, you can provide the insertion strategy in the  DaffExternalRouterModule as below.
 *
 * ```ts
 * DaffExternalRouterModule.forRoot({}, [
 *  {
 *    type: 'CATEGORY',
 *    insertionStrategy: daffInsertDataPathStrategy,
 *    route: {}
 *  }
 * ],
 * ```
 *
 * Then, you can match it with an associated route defined in your Routing
 * configuration with the  daffDataPathUrlMatcher .
 *
 * ```ts
 *  export const routes: Routes = [
 *    {
 *      matcher: daffDataPathUrlMatcher,
 *      data: {
 *        daffExternalRouteType: "CATEGORY",
 *      },
 *      loadChildren: () => import('./category/category.module').then((m) => m.MyCategoryModule),
 *    }
 * ]
 * ```
 *
 * See  DaffRouteWithDataPath export const daffInsertDataPathStrategy = ( externalRoute , routes ) => traverseRouteTree ( routes , ( route ) => routeMatchesRouteType ( route , externalRoute . data ?. daffExternalRouteType ) , operateOnRoute ( externalRoute ) ) ;