{"version":3,"file":"policy-evaluator.mjs","sources":["../../../../src/lib/auth/rbac/policy-evaluator.ts"],"sourcesContent":["/**\n * Policy Evaluator\n *\n * ABAC-style policy evaluation engine for fine-grained access control.\n * Supports complex conditions, combining algorithms, and obligations.\n *\n * @module auth/rbac/policy-evaluator\n */\n\nimport type {\n  Policy,\n  PolicySet,\n  PolicyResult,\n  PolicyEffect,\n  PolicySubject,\n  PolicyResource,\n  PolicyCondition,\n  AccessRequest,\n  EvaluationResult,\n  Obligation,\n} from './types';\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * Policy evaluation context.\n */\nexport interface EvaluationContext {\n  /** Current timestamp */\n  now: number;\n  /** Client IP address */\n  clientIp?: string;\n  /** User agent */\n  userAgent?: string;\n  /** Additional context attributes */\n  attributes?: Record<string, unknown>;\n}\n\n/**\n * Individual policy evaluation result.\n */\ninterface PolicyEvaluationResult {\n  /** Policy ID */\n  policyId: string;\n  /** Evaluation result */\n  result: PolicyResult;\n  /** Policy effect if applicable */\n  effect?: PolicyEffect;\n  /** Obligations from this policy */\n  obligations?: Obligation[];\n  /** Advice from this policy */\n  advice?: string[];\n  /** Evaluation details */\n  details?: string;\n}\n\n// =============================================================================\n// Policy Evaluator Class\n// =============================================================================\n\n/**\n * Policy Evaluator for ABAC-style access control.\n *\n * Evaluates access requests against policy sets using configurable\n * combining algorithms and condition evaluation.\n *\n * @example\n * ```typescript\n * const evaluator = new PolicyEvaluator();\n *\n * // Add policies\n * evaluator.addPolicy({\n *   id: 'admin-full-access',\n *   name: 'Admin Full Access',\n *   effect: 'allow',\n *   priority: 100,\n *   subjects: [{ type: 'role', identifier: 'admin' }],\n *   resources: [{ type: '*' }],\n *   actions: ['*'],\n *   enabled: true,\n * });\n *\n * // Evaluate request\n * const result = evaluator.evaluate({\n *   subject: { id: 'user-123', type: 'user', roles: ['admin'] },\n *   resource: { type: 'documents', id: 'doc-456' },\n *   action: 'delete',\n * });\n *\n * console.log(result.allowed); // true\n * ```\n */\nexport class PolicyEvaluator {\n  private policies: Map<string, Policy>;\n  private policySets: Map<string, PolicySet>;\n  private readonly defaultCombiningAlgorithm: PolicySet['combiningAlgorithm'];\n  private readonly debug: boolean;\n\n  constructor(options?: {\n    defaultCombiningAlgorithm?: PolicySet['combiningAlgorithm'];\n    debug?: boolean;\n  }) {\n    this.policies = new Map();\n    this.policySets = new Map();\n    this.defaultCombiningAlgorithm = options?.defaultCombiningAlgorithm ?? 'deny-overrides';\n    this.debug = options?.debug ?? false;\n  }\n\n  // ===========================================================================\n  // Policy Management\n  // ===========================================================================\n\n  /**\n   * Add a policy.\n   *\n   * @param policy - Policy to add\n   */\n  addPolicy(policy: Policy): void {\n    this.policies.set(policy.id, policy);\n  }\n\n  /**\n   * Add multiple policies.\n   *\n   * @param policies - Policies to add\n   */\n  addPolicies(policies: Policy[]): void {\n    for (const policy of policies) {\n      this.addPolicy(policy);\n    }\n  }\n\n  /**\n   * Remove a policy.\n   *\n   * @param policyId - Policy ID to remove\n   */\n  removePolicy(policyId: string): void {\n    this.policies.delete(policyId);\n  }\n\n  /**\n   * Update a policy.\n   *\n   * @param policyId - Policy ID to update\n   * @param updates - Partial updates\n   */\n  updatePolicy(policyId: string, updates: Partial<Policy>): void {\n    const existing = this.policies.get(policyId);\n    if (existing) {\n      this.policies.set(policyId, { ...existing, ...updates });\n    }\n  }\n\n  /**\n   * Get a policy by ID.\n   *\n   * @param policyId - Policy ID\n   * @returns Policy or undefined\n   */\n  getPolicy(policyId: string): Policy | undefined {\n    return this.policies.get(policyId);\n  }\n\n  /**\n   * Get all policies.\n   *\n   * @returns Array of all policies\n   */\n  getAllPolicies(): Policy[] {\n    return Array.from(this.policies.values());\n  }\n\n  /**\n   * Add a policy set.\n   *\n   * @param policySet - Policy set to add\n   */\n  addPolicySet(policySet: PolicySet): void {\n    this.policySets.set(policySet.id, policySet);\n  }\n\n  /**\n   * Remove a policy set.\n   *\n   * @param policySetId - Policy set ID\n   */\n  removePolicySet(policySetId: string): void {\n    this.policySets.delete(policySetId);\n  }\n\n  // ===========================================================================\n  // Evaluation\n  // ===========================================================================\n\n  /**\n   * Evaluate an access request.\n   *\n   * @param request - Access request\n   * @param context - Additional evaluation context\n   * @returns Evaluation result\n   */\n  evaluate(request: AccessRequest, context?: EvaluationContext): EvaluationResult {\n    const startTime = Date.now();\n    const evaluationContext = this.buildContext(context);\n\n    this.log('Evaluating request:', request);\n\n    // Get all applicable policies (from policy sets and standalone)\n    const applicablePolicies = this.getApplicablePolicies(request);\n\n    if (applicablePolicies.length === 0) {\n      return {\n        allowed: false,\n        decision: 'not-applicable',\n        reason: 'No applicable policies found',\n        evaluatedAt: Date.now(),\n        evaluationTime: Date.now() - startTime,\n      };\n    }\n\n    // Evaluate each policy\n    const policyResults = applicablePolicies.map((policy) =>\n      this.evaluatePolicy(policy, request, evaluationContext)\n    );\n\n    // Combine results\n    const combinedResult = this.combineResults(policyResults, this.defaultCombiningAlgorithm);\n\n    combinedResult.evaluationTime = Date.now() - startTime;\n\n    this.log('Evaluation result:', combinedResult);\n\n    return combinedResult;\n  }\n\n  /**\n   * Evaluate using a specific policy set.\n   *\n   * @param policySetId - Policy set ID\n   * @param request - Access request\n   * @param context - Additional context\n   * @returns Evaluation result\n   */\n  evaluatePolicySet(\n    policySetId: string,\n    request: AccessRequest,\n    context?: EvaluationContext\n  ): EvaluationResult {\n    const policySet = this.policySets.get(policySetId);\n\n    if (!policySet) {\n      return {\n        allowed: false,\n        decision: 'indeterminate',\n        reason: `Policy set '${policySetId}' not found`,\n        evaluatedAt: Date.now(),\n      };\n    }\n\n    const evaluationContext = this.buildContext(context);\n\n    // Check if request matches policy set target\n    if (policySet.target && !this.matchesTarget(policySet.target, request)) {\n      return {\n        allowed: false,\n        decision: 'not-applicable',\n        reason: 'Request does not match policy set target',\n        evaluatedAt: Date.now(),\n      };\n    }\n\n    // Evaluate policies in the set\n    const policyResults = policySet.policies\n      .filter((p) => p.enabled)\n      .map((policy) => this.evaluatePolicy(policy, request, evaluationContext));\n\n    return this.combineResults(policyResults, policySet.combiningAlgorithm);\n  }\n\n  // ===========================================================================\n  // Policy Evaluation\n  // ===========================================================================\n\n  /**\n   * Evaluate a single policy.\n   */\n  private evaluatePolicy(\n    policy: Policy,\n    request: AccessRequest,\n    context: EvaluationContext\n  ): PolicyEvaluationResult {\n    // Check if policy is enabled\n    if (!policy.enabled) {\n      return {\n        policyId: policy.id,\n        result: 'not-applicable',\n        details: 'Policy is disabled',\n      };\n    }\n\n    // Evaluate subjects\n    if ((policy.subjects?.length ?? 0) > 0 && policy.subjects !== undefined) {\n      const subjectMatch = this.evaluateSubjects(policy.subjects, request);\n      if (!subjectMatch) {\n        return {\n          policyId: policy.id,\n          result: 'not-applicable',\n          details: 'Subject does not match',\n        };\n      }\n    }\n\n    // Evaluate resources\n    if ((policy.resources?.length ?? 0) > 0) {\n      const resourceMatch = this.evaluateResources(policy.resources ?? [], request);\n      if (!resourceMatch) {\n        return {\n          policyId: policy.id,\n          result: 'not-applicable',\n          details: 'Resource does not match',\n        };\n      }\n    }\n\n    // Evaluate actions\n    if ((policy.actions?.length ?? 0) > 0) {\n      const actionMatch = this.evaluateActions(policy.actions ?? [], request);\n      if (!actionMatch) {\n        return {\n          policyId: policy.id,\n          result: 'not-applicable',\n          details: 'Action does not match',\n        };\n      }\n    }\n\n    // Evaluate conditions\n    if ((policy.conditions?.length ?? 0) > 0) {\n      const conditionsMatch = this.evaluateConditions(policy.conditions ?? [], request, context);\n      if (!conditionsMatch) {\n        return {\n          policyId: policy.id,\n          result: 'not-applicable',\n          details: 'Conditions not met',\n        };\n      }\n    }\n\n    // Policy matches - return its effect\n    return {\n      policyId: policy.id,\n      result: policy.effect === 'allow' ? 'allow' : 'deny',\n      effect: policy.effect,\n      details: `Policy ${policy.id} applies with effect: ${policy.effect}`,\n    };\n  }\n\n  /**\n   * Evaluate subject matching.\n   */\n  private evaluateSubjects(subjects: PolicySubject[], request: AccessRequest): boolean {\n    return subjects.some((subject) => {\n      switch (subject.type) {\n        case 'user':\n          return this.matchIdentifier(subject, request.subject.id);\n\n        case 'role':\n          return (\n            request.subject.roles?.some((role) => this.matchIdentifier(subject, role)) ?? false\n          );\n\n        case 'group':\n          // Would need group info in request\n          return false;\n\n        case 'attribute': {\n          const attrValue = request.subject.attributes?.[subject.identifier];\n          return subject.value === undefined || attrValue === subject.value;\n        }\n\n        default:\n          return false;\n      }\n    });\n  }\n\n  /**\n   * Evaluate resource matching.\n   */\n  private evaluateResources(resources: PolicyResource[], request: AccessRequest): boolean {\n    return resources.some((resource) => {\n      // Check resource type\n      if (resource.type !== '*' && resource.type !== request.resource.type) {\n        return false;\n      }\n\n      // Check resource identifier\n      if (\n        resource.identifier !== null &&\n        resource.identifier !== undefined &&\n        resource.identifier !== '' &&\n        resource.identifier !== '*'\n      ) {\n        if (\n          request.resource.id !== null &&\n          request.resource.id !== undefined &&\n          request.resource.id !== '' &&\n          !this.matchWildcard(resource.identifier, request.resource.id)\n        ) {\n          return false;\n        }\n      }\n\n      // Check resource attributes\n      if (resource.attributes) {\n        for (const [key, value] of Object.entries(resource.attributes)) {\n          if (request.resource.attributes?.[key] !== value) {\n            return false;\n          }\n        }\n      }\n\n      return true;\n    });\n  }\n\n  /**\n   * Evaluate action matching.\n   */\n  private evaluateActions(actions: string[], request: AccessRequest): boolean {\n    return actions.some((action) => action === '*' || action === request.action);\n  }\n\n  /**\n   * Evaluate policy conditions.\n   */\n  private evaluateConditions(\n    conditions: PolicyCondition[],\n    request: AccessRequest,\n    context: EvaluationContext\n  ): boolean {\n    return conditions.every((condition) => this.evaluateCondition(condition, request, context));\n  }\n\n  /**\n   * Evaluate a single condition.\n   */\n  private evaluateCondition(\n    condition: PolicyCondition,\n    request: AccessRequest,\n    context: EvaluationContext\n  ): boolean {\n    switch (condition.type) {\n      case 'time':\n        return this.evaluateTimeCondition(condition, context);\n\n      case 'ip':\n        return this.evaluateIPCondition(condition, request, context);\n\n      case 'location':\n        return this.evaluateLocationCondition(condition, request);\n\n      case 'attribute':\n        return this.evaluateAttributeCondition(condition, request);\n\n      case 'context':\n        return this.evaluateContextCondition(condition, request, context);\n\n      case 'custom':\n        return this.evaluateCustomCondition(condition, request, context);\n\n      default:\n        return true;\n    }\n  }\n\n  /**\n   * Evaluate time-based condition.\n   */\n  private evaluateTimeCondition(condition: PolicyCondition, context: EvaluationContext): boolean {\n    const { now } = context;\n\n    switch (condition.operator) {\n      case 'between': {\n        const [start, end] = condition.value as [number, number];\n        return now >= start && now <= end;\n      }\n\n      case 'before':\n        return now < (condition.value as number);\n\n      case 'after':\n        return now > (condition.value as number);\n\n      case 'dayOfWeek': {\n        const day = new Date(now).getDay();\n        const allowedDays = condition.value as number[];\n        return allowedDays.includes(day);\n      }\n\n      case 'timeOfDay': {\n        const date = new Date(now);\n        const timeValue = date.getHours() * 60 + date.getMinutes();\n        const [startTime, endTime] = condition.value as [number, number];\n        return timeValue >= startTime && timeValue <= endTime;\n      }\n\n      default:\n        return true;\n    }\n  }\n\n  /**\n   * Evaluate IP-based condition.\n   */\n  private evaluateIPCondition(\n    condition: PolicyCondition,\n    request: AccessRequest,\n    context: EvaluationContext\n  ): boolean {\n    const clientIp = request.context?.ipAddress ?? context.clientIp;\n\n    if (clientIp === null || clientIp === undefined || clientIp === '') {\n      return condition.operator === 'notIn';\n    }\n\n    switch (condition.operator) {\n      case 'equals':\n        return clientIp === condition.value;\n\n      case 'in':\n        return (condition.value as string[]).includes(clientIp);\n\n      case 'notIn':\n        return !(condition.value as string[]).includes(clientIp);\n\n      case 'startsWith':\n        return clientIp.startsWith(condition.value as string);\n\n      default:\n        return true;\n    }\n  }\n\n  /**\n   * Evaluate location-based condition.\n   */\n  private evaluateLocationCondition(condition: PolicyCondition, request: AccessRequest): boolean {\n    const location = request.context?.location;\n\n    if (!location) {\n      return condition.operator === 'notIn';\n    }\n\n    const key = condition.key as keyof typeof location;\n    const value = location[key];\n\n    switch (condition.operator) {\n      case 'equals':\n        return value === condition.value;\n\n      case 'in':\n        return (condition.value as string[]).includes(value as string);\n\n      case 'notIn':\n        return !(condition.value as string[]).includes(value as string);\n\n      default:\n        return true;\n    }\n  }\n\n  /**\n   * Evaluate attribute-based condition.\n   */\n  private evaluateAttributeCondition(condition: PolicyCondition, request: AccessRequest): boolean {\n    const { key } = condition;\n    if (key === null || key === undefined || key === '') return true;\n\n    // Check subject attributes first, then resource attributes\n    const value = request.subject.attributes?.[key] ?? request.resource.attributes?.[key];\n\n    return this.compareValue(condition.operator, value, condition.value);\n  }\n\n  /**\n   * Evaluate context-based condition.\n   */\n  private evaluateContextCondition(\n    condition: PolicyCondition,\n    request: AccessRequest,\n    context: EvaluationContext\n  ): boolean {\n    const { key } = condition;\n    if (key === null || key === undefined || key === '') return true;\n\n    const value = request.context?.attributes?.[key] ?? context.attributes?.[key];\n\n    return this.compareValue(condition.operator, value, condition.value);\n  }\n\n  /**\n   * Evaluate custom condition (can be extended).\n   */\n  private evaluateCustomCondition(\n    condition: PolicyCondition,\n    _request: AccessRequest,\n    _context: EvaluationContext\n  ): boolean {\n    // Custom conditions can be implemented by extending this class\n    this.log('Custom condition evaluation not implemented:', condition);\n    return true;\n  }\n\n  /**\n   * Compare values using operator.\n   */\n  private compareValue(operator: string, actual: unknown, expected: unknown): boolean {\n    switch (operator) {\n      case 'equals':\n        return actual === expected;\n\n      case 'notEquals':\n        return actual !== expected;\n\n      case 'in':\n        return (expected as unknown[]).includes(actual);\n\n      case 'notIn':\n        return !(expected as unknown[]).includes(actual);\n\n      case 'contains':\n        return String(actual).includes(String(expected));\n\n      case 'startsWith':\n        return String(actual).startsWith(String(expected));\n\n      case 'endsWith':\n        return String(actual).endsWith(String(expected));\n\n      case 'greaterThan':\n        return (actual as number) > (expected as number);\n\n      case 'lessThan':\n        return (actual as number) < (expected as number);\n\n      case 'exists':\n        return actual !== undefined && actual !== null;\n\n      case 'regex':\n        return new RegExp(expected as string).test(String(actual));\n\n      default:\n        return true;\n    }\n  }\n\n  // ===========================================================================\n  // Result Combination\n  // ===========================================================================\n\n  /**\n   * Combine policy evaluation results using combining algorithm.\n   */\n  private combineResults(\n    results: PolicyEvaluationResult[],\n    algorithm: PolicySet['combiningAlgorithm']\n  ): EvaluationResult {\n    const applicableResults = results.filter((r) => r.result !== 'not-applicable');\n    const matchingPolicies = applicableResults.map((r) => r.policyId);\n\n    if (applicableResults.length === 0) {\n      return {\n        allowed: false,\n        decision: 'not-applicable',\n        reason: 'No applicable policies',\n        matchingPolicies: [],\n        evaluatedAt: Date.now(),\n      };\n    }\n\n    switch (algorithm) {\n      case 'deny-overrides':\n        return this.denyOverrides(applicableResults, matchingPolicies);\n\n      case 'permit-overrides':\n        return this.permitOverrides(applicableResults, matchingPolicies);\n\n      case 'first-applicable':\n        return this.firstApplicable(applicableResults, matchingPolicies);\n\n      case 'ordered-deny-overrides':\n        return this.orderedDenyOverrides(applicableResults, matchingPolicies);\n\n      case 'ordered-permit-overrides':\n        return this.orderedPermitOverrides(applicableResults, matchingPolicies);\n\n      default:\n        return this.denyOverrides(applicableResults, matchingPolicies);\n    }\n  }\n\n  /**\n   * Deny-overrides combining algorithm.\n   */\n  private denyOverrides(\n    results: PolicyEvaluationResult[],\n    matchingPolicies: string[]\n  ): EvaluationResult {\n    const hasDeny = results.some((r) => r.result === 'deny');\n    const hasAllow = results.some((r) => r.result === 'allow');\n\n    if (hasDeny) {\n      return {\n        allowed: false,\n        decision: 'deny',\n        reason: 'Deny policy matched',\n        matchingPolicies,\n        evaluatedAt: Date.now(),\n      };\n    }\n\n    if (hasAllow) {\n      return {\n        allowed: true,\n        decision: 'allow',\n        reason: 'Allow policy matched, no deny',\n        matchingPolicies,\n        evaluatedAt: Date.now(),\n      };\n    }\n\n    return {\n      allowed: false,\n      decision: 'indeterminate',\n      reason: 'No conclusive policy decision',\n      matchingPolicies,\n      evaluatedAt: Date.now(),\n    };\n  }\n\n  /**\n   * Permit-overrides combining algorithm.\n   */\n  private permitOverrides(\n    results: PolicyEvaluationResult[],\n    matchingPolicies: string[]\n  ): EvaluationResult {\n    const hasAllow = results.some((r) => r.result === 'allow');\n    const hasDeny = results.some((r) => r.result === 'deny');\n\n    if (hasAllow) {\n      return {\n        allowed: true,\n        decision: 'allow',\n        reason: 'Allow policy matched',\n        matchingPolicies,\n        evaluatedAt: Date.now(),\n      };\n    }\n\n    if (hasDeny) {\n      return {\n        allowed: false,\n        decision: 'deny',\n        reason: 'Deny policy matched, no allow',\n        matchingPolicies,\n        evaluatedAt: Date.now(),\n      };\n    }\n\n    return {\n      allowed: false,\n      decision: 'indeterminate',\n      reason: 'No conclusive policy decision',\n      matchingPolicies,\n      evaluatedAt: Date.now(),\n    };\n  }\n\n  /**\n   * First-applicable combining algorithm.\n   */\n  private firstApplicable(\n    results: PolicyEvaluationResult[],\n    matchingPolicies: string[]\n  ): EvaluationResult {\n    for (const result of results) {\n      if (result.result === 'allow' || result.result === 'deny') {\n        return {\n          allowed: result.result === 'allow',\n          decision: result.result,\n          reason: `First applicable policy: ${result.policyId}`,\n          matchingPolicies: [result.policyId],\n          evaluatedAt: Date.now(),\n        };\n      }\n    }\n\n    return {\n      allowed: false,\n      decision: 'not-applicable',\n      reason: 'No applicable policy found',\n      matchingPolicies,\n      evaluatedAt: Date.now(),\n    };\n  }\n\n  /**\n   * Ordered-deny-overrides (respects policy priority).\n   */\n  private orderedDenyOverrides(\n    results: PolicyEvaluationResult[],\n    matchingPolicies: string[]\n  ): EvaluationResult {\n    // Sort by priority (handled during policy collection)\n    return this.denyOverrides(results, matchingPolicies);\n  }\n\n  /**\n   * Ordered-permit-overrides (respects policy priority).\n   */\n  private orderedPermitOverrides(\n    results: PolicyEvaluationResult[],\n    matchingPolicies: string[]\n  ): EvaluationResult {\n    return this.permitOverrides(results, matchingPolicies);\n  }\n\n  // ===========================================================================\n  // Helper Methods\n  // ===========================================================================\n\n  /**\n   * Build evaluation context.\n   */\n  private buildContext(context?: EvaluationContext): EvaluationContext {\n    return {\n      now: Date.now(),\n      ...context,\n    };\n  }\n\n  /**\n   * Get all applicable policies for a request.\n   */\n  private getApplicablePolicies(request: AccessRequest): Policy[] {\n    const policies: Policy[] = [];\n\n    // Add standalone policies\n    for (const policy of this.policies.values()) {\n      if (policy.enabled) {\n        policies.push(policy);\n      }\n    }\n\n    // Add policies from policy sets that match the request\n    for (const policySet of this.policySets.values()) {\n      if (!policySet.target || this.matchesTarget(policySet.target, request)) {\n        for (const policy of policySet.policies) {\n          if (policy.enabled) {\n            policies.push(policy);\n          }\n        }\n      }\n    }\n\n    // Sort by priority (higher first)\n    return policies.sort((a, b) => b.priority - a.priority);\n  }\n\n  /**\n   * Check if request matches policy set target.\n   */\n  private matchesTarget(targets: PolicyResource[], request: AccessRequest): boolean {\n    return this.evaluateResources(targets, request);\n  }\n\n  /**\n   * Match identifier with pattern support.\n   */\n  private matchIdentifier(subject: PolicySubject, value: string): boolean {\n    const { identifier, match = 'exact' } = subject;\n\n    switch (match) {\n      case 'any':\n        return true;\n      case 'pattern':\n        return this.matchWildcard(identifier, value);\n      case 'exact':\n      default:\n        return identifier === value;\n    }\n  }\n\n  /**\n   * Match string with wildcard pattern.\n   */\n  private matchWildcard(pattern: string, value: string): boolean {\n    const regex = new RegExp(`^${pattern.replace(/\\*/g, '.*').replace(/\\?/g, '.')}$`);\n    return regex.test(value);\n  }\n\n  /**\n   * Log debug message.\n   */\n  private log(message: string, ...args: unknown[]): void {\n    if (this.debug) {\n      console.info(`[PolicyEvaluator] ${message}`, ...args);\n    }\n  }\n}\n\n// =============================================================================\n// Factory Function\n// =============================================================================\n\n/**\n * Create a new policy evaluator.\n *\n * @param options - Evaluator options\n * @returns PolicyEvaluator instance\n */\nexport function createPolicyEvaluator(options?: {\n  policies?: Policy[];\n  policySets?: PolicySet[];\n  defaultCombiningAlgorithm?: PolicySet['combiningAlgorithm'];\n  debug?: boolean;\n}): PolicyEvaluator {\n  const evaluator = new PolicyEvaluator({\n    defaultCombiningAlgorithm: options?.defaultCombiningAlgorithm,\n    debug: options?.debug,\n  });\n\n  if (options?.policies) {\n    evaluator.addPolicies(options.policies);\n  }\n\n  if (options?.policySets) {\n    for (const policySet of options.policySets) {\n      evaluator.addPolicySet(policySet);\n    }\n  }\n\n  return evaluator;\n}\n"],"names":["PolicyEvaluator","options","policy","policies","policyId","updates","existing","policySet","policySetId","request","context","startTime","evaluationContext","applicablePolicies","policyResults","combinedResult","p","subjects","subject","role","attrValue","resources","resource","key","value","actions","action","conditions","condition","now","start","end","day","date","timeValue","endTime","clientIp","location","_request","_context","operator","actual","expected","results","algorithm","applicableResults","matchingPolicies","hasDeny","hasAllow","result","a","b","targets","identifier","match","pattern","message","args","createPolicyEvaluator","evaluator"],"mappings":"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"}