{"version":3,"file":"guard-resolver.mjs","sources":["../../../../src/lib/routing/guards/guard-resolver.ts"],"sourcesContent":["/**\n * @file Guard Resolver\n * @description Resolves and executes route guards before navigation. Manages\n * the complete guard lifecycle including registration, execution, and result handling.\n *\n * @module @/lib/routing/guards/guard-resolver\n *\n * This module provides:\n * - Guard registration and management\n * - Guard execution ordering\n * - Result handling and aggregation\n * - Navigation blocking and redirects\n * - Guard lifecycle hooks\n *\n * @example\n * ```typescript\n * import { GuardResolver, createGuardResolver } from '@/lib/routing/guards/guard-resolver';\n *\n * const resolver = createGuardResolver();\n * resolver.register(authGuard);\n * resolver.register(roleGuard);\n *\n * const result = await resolver.resolve('/admin/users', context);\n * if (result.canProceed) {\n *   // Navigate to route\n * } else {\n *   // Handle redirect or denial\n * }\n * ```\n */\n\nimport {\n  createGuardContext,\n  type GuardContext,\n  type GuardExecutionResult,\n  GuardResult,\n  type GuardResultObject,\n  type GuardTiming,\n  type RouteGuard,\n} from './route-guard';\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * Guard resolver configuration\n */\nexport interface GuardResolverConfig {\n  /** Default timeout for guard execution (ms) */\n  readonly defaultTimeout?: number;\n  /** Execute guards in parallel when possible */\n  readonly parallelExecution?: boolean;\n  /** Stop on first denial */\n  readonly stopOnDenial?: boolean;\n  /** Global guards applied to all routes */\n  readonly globalGuards?: readonly RouteGuard[];\n  /** Hook called before guard execution */\n  readonly onBeforeGuard?: (guard: RouteGuard, context: GuardContext) => void | Promise<void>;\n  /** Hook called after guard execution */\n  readonly onAfterGuard?: (\n    guard: RouteGuard,\n    result: GuardExecutionResult,\n    context: GuardContext\n  ) => void | Promise<void>;\n  /** Hook called when navigation is blocked */\n  readonly onNavigationBlocked?: (\n    result: GuardResolutionResult,\n    context: GuardContext\n  ) => void | Promise<void>;\n  /** Feature flag for resolver */\n  readonly featureFlag?: string;\n}\n\n/**\n * Guard registration options\n */\nexport interface GuardRegistrationOptions {\n  /** Routes to apply guard to */\n  readonly routes?: readonly string[];\n  /** Routes to exclude */\n  readonly exclude?: readonly string[];\n  /** Guard timing overrides */\n  readonly timing?: GuardTiming;\n  /** Priority override */\n  readonly priority?: number;\n}\n\n/**\n * Guard resolution result\n */\nexport interface GuardResolutionResult {\n  /** Whether navigation can proceed */\n  readonly canProceed: boolean;\n  /** Final result (allow, deny, or redirect) */\n  readonly result: GuardResultObject;\n  /** All executed guard results */\n  readonly guardResults: readonly GuardExecutionResult[];\n  /** Guards that passed */\n  readonly passedGuards: readonly string[];\n  /** Guards that failed */\n  readonly failedGuards: readonly string[];\n  /** Guards that were skipped */\n  readonly skippedGuards: readonly string[];\n  /** Total resolution time (ms) */\n  readonly totalTimeMs: number;\n  /** Redirect path (if applicable) */\n  readonly redirectTo?: string;\n  /** Denial reasons (if applicable) */\n  readonly denialReasons: readonly string[];\n}\n\n/**\n * Registered guard with metadata\n */\nexport interface RegisteredGuard {\n  /** Guard instance */\n  readonly guard: RouteGuard;\n  /** Registration options */\n  readonly options: GuardRegistrationOptions;\n  /** Registration ID */\n  readonly id: string;\n  /** Registration timestamp */\n  readonly registeredAt: number;\n}\n\n/**\n * Navigation intent for guard resolution\n */\nexport interface NavigationIntent {\n  /** Target path */\n  readonly to: string;\n  /** Source path (if navigating from another route) */\n  readonly from?: string;\n  /** Route parameters */\n  readonly params?: Record<string, string>;\n  /** Query parameters */\n  readonly query?: Record<string, string>;\n  /** Navigation state */\n  readonly state?: unknown;\n  /** Whether this is initial load */\n  readonly isInitialLoad?: boolean;\n  /** User context */\n  readonly user?: GuardContext['user'];\n  /** Feature flags */\n  readonly features?: Record<string, boolean>;\n}\n\n/**\n * Guard resolver state\n */\nexport interface GuardResolverState {\n  /** All registered guards */\n  readonly guards: readonly RegisteredGuard[];\n  /** Currently resolving */\n  readonly isResolving: boolean;\n  /** Last resolution result */\n  readonly lastResult: GuardResolutionResult | null;\n}\n\n// =============================================================================\n// Constants\n// =============================================================================\n\n/**\n * Default resolver configuration\n */\nexport const DEFAULT_RESOLVER_CONFIG: GuardResolverConfig = {\n  defaultTimeout: 30000,\n  parallelExecution: false,\n  stopOnDenial: true,\n};\n\n// =============================================================================\n// GuardResolver Class\n// =============================================================================\n\n/**\n * Resolves route guards before navigation\n *\n * @example\n * ```typescript\n * const resolver = new GuardResolver();\n *\n * // Register guards\n * resolver.register(authGuard);\n * resolver.register(adminGuard, { routes: ['/admin/**'] });\n *\n * // Resolve before navigation\n * const result = await resolver.resolve({\n *   to: '/admin/dashboard',\n *   user: currentUser,\n * });\n *\n * if (result.canProceed) {\n *   router.navigate(result.result.data?.path ?? intent.to);\n * } else if (result.redirectTo) {\n *   router.navigate(result.redirectTo);\n * }\n * ```\n */\nexport class GuardResolver {\n  private readonly config: GuardResolverConfig;\n  private guards: Map<string, RegisteredGuard> = new Map();\n  private globalGuards: RouteGuard[] = [];\n  private idCounter = 0;\n  private isResolving = false;\n  private lastResult: GuardResolutionResult | null = null;\n\n  constructor(config: GuardResolverConfig = {}) {\n    this.config = { ...DEFAULT_RESOLVER_CONFIG, ...config };\n\n    // Register global guards\n    if (config.globalGuards) {\n      for (const guard of config.globalGuards) {\n        this.globalGuards.push(guard);\n      }\n    }\n  }\n\n  /**\n   * Register a guard\n   *\n   * @param guard - Guard to register\n   * @param options - Registration options\n   * @returns Registration ID\n   */\n  register(guard: RouteGuard, options: GuardRegistrationOptions = {}): string {\n    const id = `guard_${++this.idCounter}_${guard.name}`;\n\n    const registered: RegisteredGuard = {\n      guard,\n      options,\n      id,\n      registeredAt: Date.now(),\n    };\n\n    this.guards.set(id, registered);\n    return id;\n  }\n\n  /**\n   * Unregister a guard\n   *\n   * @param id - Registration ID\n   * @returns True if guard was found and removed\n   */\n  unregister(id: string): boolean {\n    return this.guards.delete(id);\n  }\n\n  /**\n   * Unregister a guard by name\n   *\n   * @param name - Guard name\n   * @returns Number of guards removed\n   */\n  unregisterByName(name: string): number {\n    let count = 0;\n    for (const [id, registered] of this.guards) {\n      if (registered.guard.name === name) {\n        this.guards.delete(id);\n        count++;\n      }\n    }\n    return count;\n  }\n\n  /**\n   * Resolve guards for a navigation intent\n   *\n   * @param intent - Navigation intent\n   * @returns Resolution result\n   */\n  async resolve(intent: NavigationIntent): Promise<GuardResolutionResult> {\n    this.isResolving = true;\n\n    try {\n      // Build context\n      const context = createGuardContext({\n        path: intent.to,\n        params: intent.params ?? {},\n        query: intent.query ?? {},\n        currentRoute: intent.from,\n        nextRoute: intent.to,\n        user: intent.user,\n        features: intent.features,\n        state: intent.state,\n        isInitialLoad: intent.isInitialLoad ?? false,\n      });\n\n      // Get applicable guards\n      const applicableGuards = this.getApplicableGuards(intent.to);\n\n      // Sort by priority\n      const sortedGuards = [...applicableGuards].sort(\n        (a, b) => (a.guard.priority ?? 100) - (b.guard.priority ?? 100)\n      );\n\n      // Execute guards\n      const result = await this.executeGuards(sortedGuards, 'canActivate', context);\n\n      this.lastResult = result;\n\n      // Call blocked hook if navigation is blocked\n      if (!result.canProceed && this.config.onNavigationBlocked) {\n        await this.config.onNavigationBlocked(result, context);\n      }\n\n      return result;\n    } finally {\n      this.isResolving = false;\n    }\n  }\n\n  /**\n   * Resolve guards for deactivation (leaving a route)\n   *\n   * @param intent - Navigation intent (from = current route)\n   * @returns Resolution result\n   */\n  async resolveDeactivation(intent: NavigationIntent): Promise<GuardResolutionResult> {\n    if (intent.from === null || intent.from === undefined || intent.from === '') {\n      return {\n        canProceed: true,\n        result: GuardResult.allow(),\n        guardResults: [],\n        passedGuards: [],\n        failedGuards: [],\n        skippedGuards: [],\n        totalTimeMs: 0,\n        denialReasons: [],\n      };\n    }\n\n    this.isResolving = true;\n\n    try {\n      const context = createGuardContext({\n        path: intent.from,\n        params: intent.params ?? {},\n        query: intent.query ?? {},\n        currentRoute: intent.from,\n        nextRoute: intent.to,\n        user: intent.user,\n        features: intent.features,\n        state: intent.state,\n        isInitialLoad: false,\n      });\n\n      // Get guards for the route being left\n      const applicableGuards = this.getApplicableGuards(intent.from);\n\n      // Execute canDeactivate\n\n      return await this.executeGuards(applicableGuards, 'canDeactivate', context);\n    } finally {\n      this.isResolving = false;\n    }\n  }\n\n  /**\n   * Get resolver state\n   */\n  getState(): GuardResolverState {\n    return {\n      guards: Array.from(this.guards.values()),\n      isResolving: this.isResolving,\n      lastResult: this.lastResult,\n    };\n  }\n\n  /**\n   * Get all registered guards\n   */\n  getGuards(): readonly RegisteredGuard[] {\n    return Array.from(this.guards.values());\n  }\n\n  /**\n   * Get a specific guard by ID\n   */\n  getGuard(id: string): RegisteredGuard | undefined {\n    return this.guards.get(id);\n  }\n\n  /**\n   * Clear all guards\n   */\n  clearAll(): void {\n    this.guards.clear();\n    this.globalGuards = [];\n    this.lastResult = null;\n  }\n\n  /**\n   * Check if currently resolving\n   */\n  getIsResolving(): boolean {\n    return this.isResolving;\n  }\n\n  /**\n   * Get last resolution result\n   */\n  getLastResult(): GuardResolutionResult | null {\n    return this.lastResult;\n  }\n\n  /**\n   * Get guards applicable to a path\n   */\n  private getApplicableGuards(path: string): RegisteredGuard[] {\n    const applicable: RegisteredGuard[] = [];\n\n    // Add global guards first\n    for (const guard of this.globalGuards) {\n      if (guard.appliesTo(path)) {\n        applicable.push({\n          guard,\n          options: {},\n          id: `global_${guard.name}`,\n          registeredAt: 0,\n        });\n      }\n    }\n\n    // Add registered guards\n    for (const registered of this.guards.values()) {\n      if (this.guardAppliesToPath(registered, path)) {\n        applicable.push(registered);\n      }\n    }\n\n    return applicable;\n  }\n\n  /**\n   * Check if a registered guard applies to a path\n   */\n  private guardAppliesToPath(registered: RegisteredGuard, path: string): boolean {\n    const { guard, options } = registered;\n\n    // Check exclusions first\n    if (options.exclude) {\n      for (const pattern of options.exclude) {\n        if (this.matchPattern(pattern, path)) {\n          return false;\n        }\n      }\n    }\n\n    // Check inclusions\n    if (options.routes && options.routes.length > 0) {\n      for (const pattern of options.routes) {\n        if (this.matchPattern(pattern, path)) {\n          return true;\n        }\n      }\n      return false;\n    }\n\n    // Fall back to guard's own appliesTo\n    return guard.appliesTo(path);\n  }\n\n  /**\n   * Match a glob pattern\n   */\n  private matchPattern(pattern: string, path: string): boolean {\n    const regexStr = pattern\n      .replace(/[.+^${}()|[\\]\\\\]/g, '\\\\$&')\n      .replace(/\\*\\*/g, '{{GLOBSTAR}}')\n      .replace(/\\*/g, '[^/]*')\n      .replace(/\\{\\{GLOBSTAR\\}\\}/g, '.*');\n\n    const regex = new RegExp(`^${regexStr}$`);\n    return regex.test(path);\n  }\n\n  /**\n   * Execute guards with timing\n   */\n  private async executeGuards(\n    guards: readonly RegisteredGuard[],\n    timing: GuardTiming,\n    context: GuardContext\n  ): Promise<GuardResolutionResult> {\n    const startTime = Date.now();\n    const guardResults: GuardExecutionResult[] = [];\n    const passedGuards: string[] = [];\n    const failedGuards: string[] = [];\n    const skippedGuards: string[] = [];\n    const denialReasons: string[] = [];\n    let finalResult: GuardResultObject = GuardResult.allow();\n\n    if (this.config.parallelExecution === true) {\n      // Parallel execution\n      const promises = guards.map(async (registered) => {\n        return this.executeSingleGuard(registered.guard, timing, context);\n      });\n\n      const results = await Promise.all(promises);\n\n      for (let i = 0; i < results.length; i++) {\n        const result = results[i];\n        if (result === undefined) continue;\n        const guardInfo = guards[i];\n        if (guardInfo === undefined) continue;\n        const { guard } = guardInfo;\n\n        guardResults.push(result);\n\n        if (result.result.type === 'allow') {\n          passedGuards.push(guard.name);\n        } else {\n          failedGuards.push(guard.name);\n          if (\n            result.result.reason !== undefined &&\n            result.result.reason !== null &&\n            result.result.reason !== ''\n          ) {\n            denialReasons.push(result.result.reason);\n          }\n          if (finalResult.type === 'allow') {\n            finalResult = result.result;\n          }\n        }\n      }\n    } else {\n      // Sequential execution\n      for (const registered of guards) {\n        const result = await this.executeSingleGuard(registered.guard, timing, context);\n        guardResults.push(result);\n\n        if (result.result.type === 'allow') {\n          passedGuards.push(registered.guard.name);\n        } else {\n          failedGuards.push(registered.guard.name);\n          if (\n            result.result.reason !== undefined &&\n            result.result.reason !== null &&\n            result.result.reason !== ''\n          ) {\n            denialReasons.push(result.result.reason);\n          }\n\n          // Update final result\n          if (finalResult.type === 'allow') {\n            finalResult = result.result;\n          }\n\n          // Stop on denial if configured\n          if (this.config.stopOnDenial === true) {\n            // Mark remaining guards as skipped\n            const remaining = guards.slice(guards.indexOf(registered) + 1);\n            for (const r of remaining) {\n              skippedGuards.push(r.guard.name);\n            }\n            break;\n          }\n        }\n      }\n    }\n\n    const canProceed = failedGuards.length === 0;\n    const redirectTo = finalResult.type === 'redirect' ? finalResult.redirectTo : undefined;\n\n    return {\n      canProceed,\n      result: canProceed ? GuardResult.allow() : finalResult,\n      guardResults: Object.freeze(guardResults),\n      passedGuards: Object.freeze(passedGuards),\n      failedGuards: Object.freeze(failedGuards),\n      skippedGuards: Object.freeze(skippedGuards),\n      totalTimeMs: Date.now() - startTime,\n      redirectTo,\n      denialReasons: Object.freeze(denialReasons),\n    };\n  }\n\n  /**\n   * Execute a single guard\n   */\n  private async executeSingleGuard(\n    guard: RouteGuard,\n    timing: GuardTiming,\n    context: GuardContext\n  ): Promise<GuardExecutionResult> {\n    const startTime = Date.now();\n\n    // Before hook\n    if (this.config.onBeforeGuard) {\n      await this.config.onBeforeGuard(guard, context);\n    }\n\n    try {\n      const timeout = this.config.defaultTimeout ?? 30000;\n\n      const result = await Promise.race([\n        guard.execute(timing, context),\n        new Promise<GuardResultObject>((_, reject) =>\n          setTimeout(() => reject(new Error('Guard timeout')), timeout)\n        ),\n      ]);\n\n      const execResult: GuardExecutionResult = {\n        guardName: guard.name,\n        result,\n        durationMs: Date.now() - startTime,\n        timedOut: false,\n      };\n\n      // After hook\n      if (this.config.onAfterGuard) {\n        await this.config.onAfterGuard(guard, execResult, context);\n      }\n\n      return execResult;\n    } catch (error) {\n      const isTimeout = (error as Error).message === 'Guard timeout';\n\n      const execResult: GuardExecutionResult = {\n        guardName: guard.name,\n        result: GuardResult.deny(isTimeout ? 'Guard timed out' : (error as Error).message),\n        durationMs: Date.now() - startTime,\n        timedOut: isTimeout,\n        error: error as Error,\n      };\n\n      if (this.config.onAfterGuard) {\n        await this.config.onAfterGuard(guard, execResult, context);\n      }\n\n      return execResult;\n    }\n  }\n}\n\n// =============================================================================\n// Factory Functions\n// =============================================================================\n\n/**\n * Create a guard resolver\n *\n * @param config - Resolver configuration\n * @returns GuardResolver instance\n */\nexport function createGuardResolver(config: GuardResolverConfig = {}): GuardResolver {\n  return new GuardResolver(config);\n}\n\n// =============================================================================\n// Singleton Instance\n// =============================================================================\n\nlet defaultResolver: GuardResolver | null = null;\n\n/**\n * Get the default guard resolver\n */\nexport function getGuardResolver(): GuardResolver {\n  defaultResolver ??= new GuardResolver();\n  return defaultResolver;\n}\n\n/**\n * Initialize the default guard resolver\n *\n * @param config - Resolver configuration\n */\nexport function initGuardResolver(config: GuardResolverConfig = {}): void {\n  defaultResolver = new GuardResolver(config);\n}\n\n/**\n * Reset the default guard resolver\n */\nexport function resetGuardResolver(): void {\n  defaultResolver?.clearAll();\n  defaultResolver = null;\n}\n\n// =============================================================================\n// Type Guards\n// =============================================================================\n\n/**\n * Type guard for GuardResolutionResult\n */\nexport function isGuardResolutionResult(value: unknown): value is GuardResolutionResult {\n  return (\n    typeof value === 'object' &&\n    value !== null &&\n    'canProceed' in value &&\n    'result' in value &&\n    'guardResults' in value &&\n    'passedGuards' in value\n  );\n}\n\n/**\n * Type guard for NavigationIntent\n */\nexport function isNavigationIntent(value: unknown): value is NavigationIntent {\n  return typeof value === 'object' && value !== null && 'to' in value && true;\n}\n"],"names":["DEFAULT_RESOLVER_CONFIG","GuardResolver","config","guard","options","id","registered","name","count","intent","context","createGuardContext","sortedGuards","a","b","result","GuardResult","applicableGuards","path","applicable","pattern","regexStr","guards","timing","startTime","guardResults","passedGuards","failedGuards","skippedGuards","denialReasons","finalResult","promises","results","i","guardInfo","remaining","r","canProceed","redirectTo","timeout","_","reject","execResult","error","isTimeout","createGuardResolver","defaultResolver","getGuardResolver","initGuardResolver","resetGuardResolver","isGuardResolutionResult","value","isNavigationIntent"],"mappings":"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"}