{"version":3,"file":"bootkit-angular-router.mjs","sources":["../../../projects/bootkit/router/claim.guard.ts","../../../projects/bootkit/router/types.ts","../../../projects/bootkit/router/public-api.ts","../../../projects/bootkit/router/bootkit-angular-router.ts"],"sourcesContent":["import { EnvironmentInjector, inject, Injectable, runInInjectionContext } from '@angular/core';\r\nimport { ActivatedRouteSnapshot, CanActivateFn, MaybeAsync, RedirectCommand, RouterStateSnapshot, UrlTree } from '@angular/router';\r\nimport { User, UserStore } from '@bootkit/angular/security';\r\nimport { Route } from './types';\r\nimport { concatMap, from, map, Observable, reduce, takeWhile } from 'rxjs';\r\nimport { toObservable } from '@bootkit/angular/rxjs';\r\n\r\n/**\r\n * Creates a guard function that checks user claims and executes pre-check policies for route activation.\r\n * \r\n * @param {boolean} [checkChildRoutes=true] - Whether to check child routes recursively.\r\n * @returns {CanActivateFn} - A guard function that determines if the route can be activated.\r\n * \r\n * The guard function performs the following steps:\r\n * 1. Iterates through the route and its child routes (if `checkChildRoutes` is true).\r\n * 2. For each route, it checks if there is a guard defined in the route configuration.\r\n * 3. If a guard is defined, it (optionally) performs a pre-check step based on the guard's `preCheckPolicy`.\r\n * 4. If the pre-check step is successful, it checks if the user has the required claim.\r\n * 5. If the user does not have the required claim, it executes the guard's redirect function if defined.\r\n * 6. Returns `true` if all checks pass, otherwise returns the result of the first failed check.\r\n */\r\nexport function claimGuard(checkChildRoutes = true): CanActivateFn {\r\n  return (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => {\r\n    let gs = inject(ClaimGuardState);\r\n    let userStore = inject<UserStore<User>>(UserStore);\r\n    let eInjector = inject(EnvironmentInjector);\r\n    let observables: Observable<any>[] = [];\r\n\r\n    let currentState = route;\r\n    do {\r\n      const routeConfig = currentState.routeConfig as Route;\r\n      const guard = routeConfig.guard;\r\n\r\n      if (guard) {\r\n        // Claim precheck step\r\n        if (typeof guard.preCheck == 'function') {\r\n          const precheckPolicy = guard.preCheckPolicy || 'once';\r\n          var shouldCallPrecheck =\r\n            precheckPolicy == 'always' ||\r\n            (precheckPolicy == 'once' && !gs.calledFuncs.has(guard.preCheck));\r\n\r\n          if (shouldCallPrecheck) {\r\n            var precheckResult = runInInjectionContext(eInjector, guard.preCheck.bind(routeConfig, route, state));\r\n            if (precheckResult instanceof Observable) {\r\n              observables.push(precheckResult.pipe(map(x => true)));\r\n            }\r\n\r\n            if (!gs.calledFuncs.has(guard.preCheck))\r\n              gs.calledFuncs.add(guard.preCheck);\r\n          }\r\n        }\r\n\r\n        // Claim check step\r\n        if (guard.claim) {\r\n          var claimCheckObs = new Observable(s => {\r\n            var user = userStore.user();\r\n            if (user && user.hasClaim(guard.claim)) {\r\n              s.next(true);\r\n            } else {\r\n              if (guard.redirect) {\r\n                var redirectResult = runInInjectionContext<UrlTree | RedirectCommand>(eInjector, guard.redirect.bind(routeConfig, route, state))\r\n                s.next(redirectResult);\r\n              } else {\r\n                s.next(false);\r\n              }\r\n            }\r\n            s.complete();\r\n          });\r\n\r\n          observables.push(claimCheckObs);\r\n        }\r\n      }\r\n\r\n      currentState = currentState?.children[0];\r\n    } while (currentState && checkChildRoutes);\r\n\r\n    if (observables.length > 0) {\r\n      return from(observables).pipe(\r\n        concatMap(obs => obs),              // Ensure each observable is executed sequentially\r\n        takeWhile(value => value === true, true),  // Stop and emit when a non-true value is found\r\n        reduce((acc, value) => acc && value, true), // Accumulate all values, return true if all are true\r\n      );\r\n    }\r\n\r\n    return true;\r\n  }\r\n}\r\n\r\n@Injectable({ providedIn: 'root' })\r\nclass ClaimGuardState {\r\n  calledFuncs = new Set<Function>();\r\n}","import { ActivatedRouteSnapshot, Data, GuardResult, MaybeAsync, RedirectCommand, Route as NgRoute, RouterStateSnapshot, UrlTree } from '@angular/router';\r\nimport { ClaimCriteria } from '@bootkit/angular/security';\r\nimport { Observable } from 'rxjs';\r\n\r\n// export interface MetaTagDescriptor {\r\n//     key?: string;\r\n//     attrs: { [key: string]: string };\r\n// }\r\n\r\n// export type MetaTagAttributes = { [key: string]: string }\r\n// export type MetaTag = MetaTagAttributes;\r\n\r\nexport type ClaimPreCheckPolicy = 'always' | 'once';\r\n\r\nexport interface RouteGuard {\r\n    /** Guard precheck step */\r\n    preCheck?: (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => void | undefined | Observable<any>;\r\n    preCheckPolicy?: ClaimPreCheckPolicy;\r\n\r\n    claim?: ClaimCriteria;\r\n    redirect?: (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => MaybeAsync<RedirectCommand | UrlTree>;\r\n}\r\n\r\n/** Route data */\r\nexport interface RouteData extends Data {\r\n    // title?: string;\r\n    // titleKey?: string;\r\n    // metaTags?: MetaTag[]\r\n}\r\n\r\nexport interface Route extends NgRoute {\r\n    children?: Routes;\r\n    // permission?: RoutePermission;\r\n    // data?: RouteData;\r\n    guard?: RouteGuard;\r\n}\r\n\r\nexport type Routes = Route[];\r\n\r\n\r\n/** Router activated route */\r\n// export class RouterActivatedRouteSnapshot {\r\n//     constructor(\r\n//         public readonly activatedRoute: ActivatedRouteSnapshot,\r\n//         public readonly routeData: RouteData | undefined,\r\n//         public readonly localizedTitle?: string,\r\n//         public readonly localizedMetaDescription?: string,\r\n//         public readonly localizedMetaKeywords?: string,\r\n//     ) { }\r\n// }\r\n\r\n\r\n/** Router navigation event */\r\n// export class RouterNavigationEndEvent {\r\n//     private _last: RouterActivatedRouteSnapshot;\r\n//     get last() { return this._last };\r\n\r\n//     constructor(readonly activatedRoutes: RouterActivatedRouteSnapshot[]) {\r\n//         this._last = activatedRoutes[activatedRoutes.length - 1];\r\n//     }\r\n// }\r\n\r\n/** Router Utils Configuration */\r\n// export interface RouterUtilsConfiguration {\r\n//     /** Document configurations */\r\n//     document?: {\r\n//         /** Determines whether page title should be set automatically or not */\r\n//         setTitle?: boolean | ((e: RouterNavigationEndEvent) => string);\r\n\r\n//         /** Determines whether page meta keywords should be set automatically or not */\r\n//         setDescription?: boolean | ((e: RouterNavigationEndEvent) => string);\r\n\r\n//         /** Determines whether page meta keywords should be set automatically or not */\r\n//         setKeywords?: boolean | ((e: RouterNavigationEndEvent) => string);\r\n//     };\r\n// }\r\n\r\n/** Router Utils Configuration Token */\r\n// export const RouterUtilsConfigurationToken = new InjectionToken<RouterUtilsConfiguration>('RouterConfigurationToken');\r\n\r\n// export type RouteCheck = {\r\n//     deps: any[],\r\n//     f: (...dependecies) => boolean | UrlTree | Observable<boolean | UrlTree> | Promise<boolean | UrlTree>\r\n// };\r\n\r\n// export interface RoutePermission {\r\n//     claims?: string[];\r\n//     anyClaim?: string[];\r\n//     deny?: string | UrlTree;\r\n//     precheck?: RouteCheck;\r\n//     postcheck?: RouteCheck;\r\n// }\r\n\r\n\r\n","export  *  from './claim.guard';\r\n export * from './types';\r\n// export * from './router-service';\r\n// export * from './router-utils.module';","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}