{"version":3,"file":"types.mjs","sources":["../../../src/lib/feature/types.ts"],"sourcesContent":["/**\n * @file Feature Types\n * @description Types for feature configuration (roles, flags, metadata)\n */\n\nimport type React from 'react';\nimport type { Role } from '../auth/types';\n\n/**\n * Feature metadata\n */\nexport interface FeatureMetadata {\n  /** Unique feature identifier */\n  id: string;\n\n  /** Display name */\n  name: string;\n\n  /** Description of the feature */\n  description?: string;\n\n  /** Feature icon name */\n  icon?: string;\n\n  /** Feature category for grouping */\n  category?: string;\n\n  /** Sort order in navigation */\n  order?: number;\n\n  /** Feature version */\n  version?: string;\n}\n\n/**\n * Feature access configuration\n */\nexport interface FeatureAccess {\n  /** Required roles to access the feature */\n  requiredRoles?: Role[];\n\n  /** Any of these roles grants access */\n  allowedRoles?: Role[];\n\n  /** Specific permissions required */\n  permissions?: string[];\n\n  /** Feature flag that must be enabled */\n  featureFlag?: string;\n\n  /** Additional feature flags that must be enabled */\n  requiredFlags?: string[];\n\n  /** Whether authentication is required */\n  requireAuth?: boolean;\n}\n\n/**\n * Feature tab definition\n */\nexport interface FeatureTab {\n  /** Tab identifier */\n  id: string;\n\n  /** Tab display label */\n  label: string;\n\n  /** Tab icon */\n  icon?: string;\n\n  /** Route path for the tab */\n  path?: string;\n\n  /** Whether tab is disabled */\n  disabled?: boolean;\n\n  /** Tab-specific access restrictions */\n  access?: FeatureAccess;\n\n  /** Badge count or indicator */\n  badge?: number | string;\n}\n\n/**\n * Feature page configuration\n */\nexport interface FeatureConfig {\n  /** Feature metadata */\n  metadata: FeatureMetadata;\n\n  /** Access configuration */\n  access: FeatureAccess;\n\n  /** Tab definitions */\n  tabs?: FeatureTab[];\n\n  /** Default tab ID */\n  defaultTab?: string;\n\n  /** Loading component override */\n  loadingFallback?: React.ReactNode;\n\n  /** Error component override */\n  errorFallback?: React.ReactNode;\n\n  /** Whether to show breadcrumbs */\n  showBreadcrumbs?: boolean;\n\n  /** Whether to show page title */\n  showTitle?: boolean;\n\n  /** Additional page metadata */\n  pageMetadata?: {\n    title?: string;\n    description?: string;\n  };\n}\n\n/**\n * Feature view model base interface\n */\nexport interface FeatureViewModel<TData = unknown> {\n  /** Loading state */\n  isLoading: boolean;\n\n  /** Error state */\n  error: Error | null;\n\n  /** Feature data */\n  data: TData | null;\n\n  /** Current tab (if applicable) */\n  activeTab?: string;\n\n  /** Tab change handler */\n  setActiveTab?: (tab: string) => void;\n\n  /** Refresh data */\n  refresh: () => void;\n}\n\n/**\n * Feature page props\n */\nexport interface FeaturePageProps<TViewModel extends FeatureViewModel = FeatureViewModel> {\n  /** Feature configuration */\n  config: FeatureConfig;\n\n  /** View model instance */\n  viewModel: TViewModel;\n}\n\n/**\n * Feature component props\n */\nexport interface FeatureViewProps<TViewModel extends FeatureViewModel = FeatureViewModel> {\n  /** View model */\n  viewModel: TViewModel;\n\n  /** Whether in loading state */\n  isLoading?: boolean;\n}\n\n/**\n * Feature creation options\n */\nexport interface CreateFeatureOptions<\n  TData = unknown,\n  TViewModel extends FeatureViewModel<TData> = FeatureViewModel<TData>,\n> {\n  /** Feature configuration */\n  config: FeatureConfig;\n\n  /** View model hook */\n  useViewModel: () => TViewModel;\n\n  /** View component */\n  View: React.ComponentType<FeatureViewProps<TViewModel>>;\n\n  /** Custom loading component */\n  Loading?: React.ComponentType;\n\n  /** Custom error component */\n  Error?: React.ComponentType<{ error: Error; retry: () => void }>;\n}\n\n/**\n * Feature registry entry\n */\nexport interface FeatureRegistryEntry {\n  config: FeatureConfig;\n  component: React.LazyExoticComponent<React.ComponentType>;\n}\n\n/**\n * Feature registry\n */\nexport type FeatureRegistry = Map<string, FeatureRegistryEntry>;\n\n/**\n * Check if user has access to feature\n */\nexport function hasFeatureAccess(\n  access: FeatureAccess,\n  userRoles: Role[],\n  enabledFlags: string[]\n): boolean {\n  // Check authentication requirement\n  if (access.requireAuth === true && !userRoles.length) {\n    return false;\n  }\n\n  // Check feature flag\n  if (\n    access.featureFlag != null &&\n    access.featureFlag !== '' &&\n    !enabledFlags.includes(access.featureFlag)\n  ) {\n    return false;\n  }\n\n  // Check required flags\n  if (access.requiredFlags != null && access.requiredFlags.length > 0) {\n    const hasAllFlags = access.requiredFlags.every((flag) => enabledFlags.includes(flag));\n    if (!hasAllFlags) return false;\n  }\n\n  // Check required roles (all must match)\n  if (access.requiredRoles != null && access.requiredRoles.length > 0) {\n    const hasAllRoles = access.requiredRoles.every((role) => userRoles.includes(role));\n    if (!hasAllRoles) return false;\n  }\n\n  // Check allowed roles (any must match)\n  if (access.allowedRoles != null && access.allowedRoles.length > 0) {\n    const hasAnyRole = access.allowedRoles.some((role) => userRoles.includes(role));\n    if (!hasAnyRole) return false;\n  }\n\n  return true;\n}\n"],"names":["hasFeatureAccess","access","userRoles","enabledFlags","flag","role"],"mappings":"AA0MO,SAASA,EACdC,GACAC,GACAC,GACS;AA4BT,SA1BI,EAAAF,EAAO,gBAAgB,MAAQ,CAACC,EAAU,UAM5CD,EAAO,eAAe,QACtBA,EAAO,gBAAgB,MACvB,CAACE,EAAa,SAASF,EAAO,WAAW,KAMvCA,EAAO,iBAAiB,QAAQA,EAAO,cAAc,SAAS,KAE5D,CADgBA,EAAO,cAAc,MAAM,CAACG,MAASD,EAAa,SAASC,CAAI,CAAC,KAKlFH,EAAO,iBAAiB,QAAQA,EAAO,cAAc,SAAS,KAE5D,CADgBA,EAAO,cAAc,MAAM,CAACI,MAASH,EAAU,SAASG,CAAI,CAAC,KAK/EJ,EAAO,gBAAgB,QAAQA,EAAO,aAAa,SAAS,KAE1D,CADeA,EAAO,aAAa,KAAK,CAACI,MAASH,EAAU,SAASG,CAAI,CAAC;AAKlF;"}