{"version":3,"file":"types.mjs","sources":["../../../src/lib/routing/types.ts"],"sourcesContent":["/**\n * @file Route Auto-Discovery Type System\n * @description Type-safe route definitions with compile-time validation and template literal param extraction\n * @module @/lib/routing/types\n *\n * This module provides a comprehensive type system for React Router routes including:\n * - Template literal types for extracting route parameters at compile time\n * - Type-safe route builders that enforce correct parameter types\n * - Route validation types for detecting conflicts and issues\n * - Middleware and prefetch configuration types\n *\n * @example\n * ```typescript\n * import type { RouteParams, RouteBuilder } from '@/lib/routing/types';\n *\n * // Extract params from a route path at compile time\n * type UserParams = RouteParams<'/users/:id/posts/:postId'>;\n * // Result: { id: string; postId: string }\n *\n * // Create a type-safe route builder\n * const userRoute: RouteBuilder<'/users/:id'> = (params) => `/users/${params.id}`;\n * ```\n */\n\nimport type { RouteObject, LoaderFunction, ActionFunction } from 'react-router-dom';\nimport type { ComponentType, LazyExoticComponent, ReactNode } from 'react';\nimport type { ParsedRouteSegment } from './route-segment-types';\nimport type {\n  ExtractRequiredParams,\n  ExtractOptionalParams,\n  RouteParams,\n  HasParams,\n  ParamsFor as _ParamsFor,\n} from './route-parameter-types';\n\n// Re-export types for external use\nexport type { ParsedRouteSegment, RouteSegmentType } from './route-segment-types';\nexport type {\n  ExtractRequiredParams,\n  ExtractOptionalParams,\n  RouteParams,\n  HasParams,\n  ParamsFor,\n} from './route-parameter-types';\n\n// =============================================================================\n// Route Builder Types\n// =============================================================================\n\n/**\n * Type-safe route builder function signature\n * - For routes without params: `() => TPath`\n * - For routes with params: `(params: RouteParams<TPath>, query?: QueryParams) => string`\n */\nexport type RouteBuilder<TPath extends string> = keyof RouteParams<TPath> extends never\n  ? (query?: Record<string, string | undefined>) => TPath\n  : (params: RouteParams<TPath>, query?: Record<string, string | undefined>) => string;\n\n/**\n * Type-safe route registry with builders for all routes\n */\nexport type TypedRouteRegistry<TRoutes extends Record<string, string>> = {\n  readonly [K in keyof TRoutes]: RouteBuilder<TRoutes[K]>;\n};\n\n// =============================================================================\n// Route Metadata Types\n// =============================================================================\n\n/**\n * Route metadata for SEO, analytics, and display\n */\nexport interface RouteMetadata {\n  /** Page title */\n  readonly title?: string;\n  /** Page description for SEO */\n  readonly description?: string;\n  /** SEO keywords */\n  readonly keywords?: readonly string[];\n  /** Canonical URL override */\n  readonly canonical?: string;\n  /** Robots directive */\n  readonly robots?: 'index' | 'noindex' | 'follow' | 'nofollow';\n  /** Analytics configuration */\n  readonly analytics?: {\n    readonly pageType: string;\n    readonly section?: string;\n    readonly category?: string;\n  };\n}\n\n/**\n * Route access control configuration\n */\nexport interface RouteAccessConfig {\n  /** Whether route is publicly accessible */\n  readonly isPublic: boolean;\n  /** Required roles for access */\n  readonly requiredRoles?: readonly string[];\n  /** Required permissions for access */\n  readonly requiredPermissions?: readonly string[];\n  /** Feature flag that must be enabled */\n  readonly featureFlag?: string;\n  /** Additional required feature flags */\n  readonly requiredFlags?: readonly string[];\n}\n\n// =============================================================================\n// Route Definition Types\n// =============================================================================\n\n/**\n * Complete route definition with full type safety\n */\nexport interface RouteDefinition<\n  TPath extends string = string,\n  TParams extends Record<string, string> = Record<string, string>,\n  _TSearchParams extends Record<string, string | undefined> = Record<string, string | undefined>,\n  _TLoaderData = unknown,\n> {\n  /** Unique route identifier */\n  readonly id: string;\n\n  /** URL path pattern (e.g., '/users/:id') */\n  readonly path: TPath;\n\n  /** Human-readable name for debugging/navigation */\n  readonly displayName: string;\n\n  /** Source file path (for error messages) */\n  readonly sourceFile: string;\n\n  /** Extracted parameter names from path */\n  readonly paramNames: ReadonlyArray<keyof TParams>;\n\n  /** Layout to wrap this route (if any) */\n  readonly layout?: string;\n\n  /** Feature module this route belongs to */\n  readonly feature?: string;\n\n  /** Route metadata */\n  readonly meta: RouteMetadata;\n\n  /** Access control configuration */\n  readonly access: RouteAccessConfig;\n\n  /** Whether route has a loader function */\n  readonly hasLoader: boolean;\n\n  /** Whether route has an action function */\n  readonly hasAction: boolean;\n}\n\n// =============================================================================\n// Route Module Types\n// =============================================================================\n\n/**\n * Route module exports (what each route file can export)\n */\nexport interface RouteModule {\n  /** Default export: the route component */\n  default: ComponentType<unknown>;\n\n  /** Optional: route loader function for data fetching */\n  loader?: LoaderFunction;\n\n  /** Optional: route action function for mutations */\n  action?: ActionFunction;\n\n  /** Optional: route metadata */\n  meta?: RouteMetadata;\n\n  /** Optional: access control */\n  access?: RouteAccessConfig;\n\n  /** Optional: error boundary component */\n  ErrorBoundary?: ComponentType<{ error: Error }>;\n\n  /** Optional: pending/loading UI */\n  PendingComponent?: ComponentType;\n\n  /** Optional: route handle for useMatches */\n  handle?: Record<string, unknown>;\n}\n\n/**\n * Lazy route module with preload capability\n */\nexport interface LazyRouteModule extends LazyExoticComponent<ComponentType<unknown>> {\n  preload?: () => Promise<RouteModule>;\n}\n\n// =============================================================================\n// Route Discovery Types\n// =============================================================================\n\n/**\n * Discovery result from file system scan\n */\nexport interface DiscoveredRoute {\n  /** Absolute file path */\n  readonly filePath: string;\n  /** Path relative to scan root */\n  readonly relativePath: string;\n  /** Generated URL path */\n  readonly urlPath: string;\n  /** Parsed path segments */\n  readonly segments: readonly ParsedRouteSegment[];\n  /** Whether this is a layout file */\n  readonly isLayout: boolean;\n  /** Whether this is an index file */\n  readonly isIndex: boolean;\n  /** Parent layout file path (if any) */\n  readonly parentLayout?: string;\n  /** Nesting depth */\n  readonly depth: number;\n}\n\n/**\n * Route conflict information\n */\nexport interface RouteConflict {\n  /** Type of conflict */\n  readonly type: 'exact' | 'ambiguous' | 'shadow';\n  /** Conflicting path pattern */\n  readonly path: string;\n  /** Files involved in conflict */\n  readonly files: readonly string[];\n  /** Human-readable message */\n  readonly message: string;\n  /** Severity level */\n  readonly severity: 'error' | 'warning';\n}\n\n// =============================================================================\n// Discovery Configuration\n// =============================================================================\n\n/**\n * Route discovery configuration\n */\nexport interface DiscoveryConfig {\n  /** Root directories to scan for routes */\n  readonly scanPaths: readonly string[];\n\n  /** File extensions to consider as routes */\n  readonly extensions: readonly string[];\n\n  /** Glob patterns to ignore */\n  readonly ignorePatterns: readonly string[];\n\n  /** Layout file naming convention (default: '_layout') */\n  readonly layoutFileName: string;\n\n  /** Enable parallel scanning for large codebases */\n  readonly parallel: boolean;\n\n  /** Cache discovery results */\n  readonly cacheResults: boolean;\n}\n\n/**\n * Default discovery configuration\n */\nexport const DEFAULT_DISCOVERY_CONFIG: DiscoveryConfig = {\n  scanPaths: ['src/routes', 'src/features'],\n  extensions: ['.tsx', '.ts'],\n  ignorePatterns: [\n    '**/*.test.{ts,tsx}',\n    '**/*.spec.{ts,tsx}',\n    '**/__tests__/**',\n    '**/*.stories.{ts,tsx}',\n    '**/components/**',\n    '**/hooks/**',\n    '**/utils/**',\n    '**/wiring/**',\n    '**/types/**',\n    '**/*.d.ts',\n  ],\n  layoutFileName: '_layout',\n  parallel: true,\n  cacheResults: true,\n};\n\n// =============================================================================\n// Router Factory Types\n// =============================================================================\n\n/**\n * Router creation options\n */\nexport interface CreateRouterOptions {\n  /** Enable feature route integration */\n  includeFeatures?: boolean;\n\n  /** Custom error element */\n  errorElement?: ReactNode;\n\n  /** Custom loading fallback */\n  loadingFallback?: ReactNode;\n\n  /** Base path for all routes */\n  basename?: string;\n\n  /** Enable route prefetching on hover */\n  prefetchOnHover?: boolean;\n\n  /** Enable route prefetching on focus */\n  prefetchOnFocus?: boolean;\n\n  /** Delay before prefetch triggers (ms) */\n  prefetchDelay?: number;\n}\n\n/**\n * Extended RouteObject with additional properties\n */\nexport type ExtendedRouteObject = RouteObject & {\n  /** Route metadata */\n  meta?: RouteMetadata;\n  /** Access control */\n  access?: RouteAccessConfig;\n  /** Preload function for prefetching */\n  preload?: () => Promise<unknown>;\n};\n\n// =============================================================================\n// Type Utilities\n// =============================================================================\n\n/**\n * Prettify a type for better IntelliSense display\n */\nexport type Prettify<T> = {\n  [K in keyof T]: T[K];\n} & {};\n\n/**\n * Make specific keys optional\n */\nexport type PartialBy<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;\n\n/**\n * Extract route path from route ID\n */\nexport type RoutePathFromId<\n  TRegistry extends Record<string, string>,\n  TId extends keyof TRegistry,\n> = TRegistry[TId];\n\n// =============================================================================\n// Advanced Type Utilities for Route Discovery\n// =============================================================================\n\n/**\n * Extract all segments from a route path\n *\n * @example\n * ExtractSegments<'/users/:id/posts/:postId'> = ['users', ':id', 'posts', ':postId']\n */\nexport type ExtractSegments<TPath extends string> = TPath extends `/${infer Rest}`\n  ? ExtractSegments<Rest>\n  : TPath extends `${infer Segment}/${infer Rest}`\n    ? [Segment, ...ExtractSegments<Rest>]\n    : TPath extends ''\n      ? []\n      : [TPath];\n\n/**\n * Count the depth of a route path\n *\n * @example\n * RouteDepth<'/users/:id/posts'> = 3\n */\nexport type RouteDepth<TPath extends string> = ExtractSegments<TPath>['length'];\n\n/**\n * Check if a route path is a child of another\n *\n * @example\n * IsChildRoute<'/users/:id', '/users'> = true\n * IsChildRoute<'/users', '/users/:id'> = false\n */\nexport type IsChildRoute<\n  TChild extends string,\n  TParent extends string,\n> = TChild extends `${TParent}/${infer _Rest}` ? true : false;\n\n/**\n * Get the parent path of a route\n *\n * @example\n * GetParentPath<'/users/:id/posts'> = '/users/:id'\n */\nexport type GetParentPath<TPath extends string> = TPath extends `${infer Parent}/${infer _Last}`\n  ? Parent extends ''\n    ? '/'\n    : Parent\n  : '/';\n\n/**\n * Check if a path segment is dynamic\n */\nexport type IsDynamicSegment<TSegment extends string> = TSegment extends `:${infer _Param}`\n  ? true\n  : false;\n\n/**\n * Check if a path segment is optional\n */\nexport type IsOptionalSegment<TSegment extends string> = TSegment extends `:${infer _Param}?`\n  ? true\n  : false;\n\n/**\n * Check if a path segment is catch-all\n */\nexport type IsCatchAllSegment<TSegment extends string> = TSegment extends '*' ? true : false;\n\n/**\n * Get all static segments from a path\n */\nexport type StaticSegments<TPath extends string> = {\n  [K in keyof ExtractSegments<TPath>]: K extends number\n    ? ExtractSegments<TPath>[K] extends string\n      ? IsDynamicSegment<ExtractSegments<TPath>[K]> extends true\n        ? never\n        : ExtractSegments<TPath>[K]\n      : never\n    : never;\n}[number];\n\n/**\n * Get all dynamic segments from a path\n */\nexport type DynamicSegments<TPath extends string> = {\n  [K in keyof ExtractSegments<TPath>]: K extends number\n    ? ExtractSegments<TPath>[K] extends string\n      ? IsDynamicSegment<ExtractSegments<TPath>[K]> extends true\n        ? ExtractSegments<TPath>[K]\n        : never\n      : never\n    : never;\n}[number];\n\n// =============================================================================\n// Route Validation Types\n// =============================================================================\n\n/**\n * Validation result for a route\n */\nexport interface RouteValidationResult {\n  readonly isValid: boolean;\n  readonly errors: readonly RouteValidationError[];\n  readonly warnings: readonly RouteValidationWarning[];\n  readonly suggestions: readonly RouteFixSuggestion[];\n}\n\n/**\n * Route validation error\n */\nexport interface RouteValidationError {\n  readonly code: RouteErrorCode;\n  readonly message: string;\n  readonly filePath: string;\n  readonly line?: number;\n  readonly column?: number;\n}\n\n/**\n * Route validation warning\n */\nexport interface RouteValidationWarning {\n  readonly code: RouteWarningCode;\n  readonly message: string;\n  readonly filePath: string;\n  readonly suggestion?: string;\n}\n\n/**\n * Suggestion for fixing a route issue\n */\nexport interface RouteFixSuggestion {\n  readonly description: string;\n  readonly oldValue: string;\n  readonly newValue: string;\n  readonly autoFixable: boolean;\n}\n\n/**\n * Error codes for route validation\n */\nexport type RouteErrorCode =\n  | 'DUPLICATE_PATH'\n  | 'INVALID_SEGMENT_NAME'\n  | 'MISSING_DEFAULT_EXPORT'\n  | 'CONFLICTING_PARAMS'\n  | 'INVALID_LAYOUT_STRUCTURE'\n  | 'CIRCULAR_LAYOUT_REFERENCE'\n  | 'CATCH_ALL_NOT_LAST'\n  | 'AMBIGUOUS_DYNAMIC_ROUTES';\n\n/**\n * Warning codes for route validation\n */\nexport type RouteWarningCode =\n  | 'STATIC_SHADOWED_BY_DYNAMIC'\n  | 'DEEP_NESTING'\n  | 'UNUSED_LAYOUT'\n  | 'MISSING_ERROR_BOUNDARY'\n  | 'MISSING_LOADER'\n  | 'REDUNDANT_INDEX_ROUTE'\n  | 'INCONSISTENT_NAMING';\n\n// =============================================================================\n// Route Middleware Types\n// =============================================================================\n\n/**\n * Route middleware function signature\n */\nexport type RouteMiddleware<TContext = unknown, TResult = void> = (\n  context: RouteMiddlewareContext<TContext>\n) => TResult | Promise<TResult>;\n\n/**\n * Context passed to route middleware\n */\nexport interface RouteMiddlewareContext<TContext = unknown> {\n  /** Current route path */\n  readonly path: string;\n  /** Route parameters */\n  readonly params: Record<string, string>;\n  /** Query parameters */\n  readonly query: Record<string, string>;\n  /** Custom context data */\n  readonly data: TContext;\n  /** Navigate to a different route */\n  readonly redirect: (path: string) => never;\n  /** Continue to next middleware */\n  readonly next: () => void;\n}\n\n/**\n * Middleware chain configuration\n */\nexport interface MiddlewareChain<TContext = unknown> {\n  readonly middlewares: readonly RouteMiddleware<TContext>[];\n  readonly fallback?: (error: Error) => void;\n}\n\n// =============================================================================\n// Route Prefetch Configuration Types\n// =============================================================================\n\n/**\n * Prefetch strategy for a route\n */\nexport type PrefetchStrategy = 'hover' | 'viewport' | 'idle' | 'mount' | 'none';\n\n/**\n * Prefetch priority level\n */\nexport type PrefetchPriority = 'high' | 'medium' | 'low';\n\n/**\n * Route prefetch configuration\n */\nexport interface RoutePrefetchConfig {\n  /** Strategy for triggering prefetch */\n  readonly strategy: PrefetchStrategy;\n  /** Priority level */\n  readonly priority: PrefetchPriority;\n  /** Delay before prefetching (ms) */\n  readonly delay?: number;\n  /** Whether to prefetch data in addition to code */\n  readonly includeData?: boolean;\n  /** Custom query keys to prefetch */\n  readonly queryKeys?: readonly unknown[][];\n  /** Network conditions to respect */\n  readonly networkConditions?: {\n    /** Minimum connection quality */\n    readonly minQuality?: '4g' | '3g' | '2g';\n    /** Respect data saver mode */\n    readonly respectDataSaver?: boolean;\n  };\n}\n\n/**\n * Default prefetch configuration\n */\nexport const DEFAULT_PREFETCH_CONFIG: RoutePrefetchConfig = {\n  strategy: 'hover',\n  priority: 'medium',\n  delay: 100,\n  includeData: false,\n  networkConditions: {\n    minQuality: '3g',\n    respectDataSaver: true,\n  },\n};\n\n// =============================================================================\n// Route Navigation Types\n// =============================================================================\n\n/**\n * Type-safe navigation options\n */\nexport interface TypedNavigationOptions {\n  /** Replace current history entry */\n  readonly replace?: boolean;\n  /** State to pass to route */\n  readonly state?: unknown;\n  /** Prevent scroll restoration */\n  readonly preventScrollReset?: boolean;\n  /** Relative navigation base */\n  readonly relative?: 'route' | 'path';\n  /** Scroll to element after navigation */\n  readonly scrollToId?: string;\n}\n\n/**\n * Navigation result\n */\nexport interface NavigationResult {\n  readonly success: boolean;\n  readonly path: string;\n  readonly error?: Error;\n}\n\n// =============================================================================\n// Route Analytics Types\n// =============================================================================\n\n/**\n * Route analytics event\n */\nexport interface RouteAnalyticsEvent {\n  readonly eventType: 'navigation' | 'prefetch' | 'error';\n  readonly path: string;\n  readonly timestamp: number;\n  readonly metadata?: Record<string, unknown>;\n}\n\n/**\n * Route performance metrics\n */\nexport interface RoutePerformanceMetrics {\n  /** Time to first byte */\n  readonly ttfb: number;\n  /** Time to interactive */\n  readonly tti: number;\n  /** Largest contentful paint */\n  readonly lcp: number;\n  /** Cumulative layout shift */\n  readonly cls: number;\n  /** First input delay */\n  readonly fid: number;\n}\n\n// =============================================================================\n// Route Discovery Result Types\n// =============================================================================\n\n/**\n * Complete discovery result with all metadata\n */\nexport interface RouteDiscoveryResult {\n  /** All discovered routes */\n  readonly routes: readonly DiscoveredRoute[];\n  /** Layout hierarchy */\n  readonly layoutTree: RouteLayoutTree;\n  /** Conflict detection results */\n  readonly conflicts: {\n    readonly hasErrors: boolean;\n    readonly hasWarnings: boolean;\n    readonly items: readonly RouteConflict[];\n  };\n  /** Discovery statistics */\n  readonly stats: RouteDiscoveryStats;\n  /** Generated type definitions */\n  readonly generatedTypes?: string;\n}\n\n/**\n * Layout tree structure\n */\nexport interface RouteLayoutTree {\n  readonly root: RouteLayoutNode | null;\n  readonly orphanedLayouts: readonly string[];\n}\n\n/**\n * Node in the layout tree\n */\nexport interface RouteLayoutNode {\n  readonly layoutPath: string;\n  readonly children: readonly RouteLayoutNode[];\n  readonly routes: readonly DiscoveredRoute[];\n}\n\n/**\n * Discovery statistics\n */\nexport interface RouteDiscoveryStats {\n  /** Total routes discovered */\n  readonly totalRoutes: number;\n  /** Number of layouts */\n  readonly layoutCount: number;\n  /** Number of dynamic routes */\n  readonly dynamicRouteCount: number;\n  /** Maximum route depth */\n  readonly maxDepth: number;\n  /** Scan duration in ms */\n  readonly scanDurationMs: number;\n  /** Files scanned */\n  readonly filesScanned: number;\n  /** Files ignored */\n  readonly filesIgnored: number;\n}\n\n// =============================================================================\n// ADVANCED CONDITIONAL TYPE HELPERS\n// =============================================================================\n\n/**\n * Extract all parameter names as a union type\n *\n * @template TPath - A route path string\n *\n * @example\n * ```typescript\n * type Params = ParamNames<'/users/:id/posts/:postId'>;\n * // Result: 'id' | 'postId'\n * ```\n */\nexport type ParamNames<TPath extends string> = keyof RouteParams<TPath>;\n\n/**\n * Check if a route requires any parameters\n *\n * @template TPath - A route path string\n *\n * @example\n * ```typescript\n * type NeedsParams = RequiresParams<'/users/:id'>; // true\n * type NoParams = RequiresParams<'/about'>; // false\n * ```\n */\nexport type RequiresParams<TPath extends string> = keyof ExtractRequiredParams<TPath> extends never\n  ? false\n  : true;\n\n/**\n * Check if a route has only optional parameters\n *\n * @template TPath - A route path string\n *\n * @example\n * ```typescript\n * type OnlyOptional = HasOnlyOptionalParams<'/search/:query?'>; // true\n * type HasRequired = HasOnlyOptionalParams<'/users/:id'>; // false\n * ```\n */\nexport type HasOnlyOptionalParams<TPath extends string> =\n  RequiresParams<TPath> extends false\n    ? keyof ExtractOptionalParams<TPath> extends never\n      ? false\n      : true\n    : false;\n\n/**\n * Get the number of parameters in a route\n *\n * @template TPath - A route path string\n * @returns A numeric literal type\n */\nexport type ParamCount<TPath extends string> = keyof RouteParams<TPath> extends never\n  ? 0\n  : TupleFromUnion<keyof RouteParams<TPath>>['length'];\n\n/**\n * Convert a union type to a tuple (for counting)\n * @internal\n */\ntype TupleFromUnion<T, L = LastOfUnion<T>> = [T] extends [never]\n  ? []\n  : [...TupleFromUnion<Exclude<T, L>>, L];\n\n/**\n * Get the last element of a union type\n * @internal\n */\ntype LastOfUnion<T> =\n  UnionToIntersection<T extends unknown ? (t: T) => T : never> extends (t: infer L) => unknown\n    ? L\n    : never;\n\n/**\n * Convert a union to an intersection\n * @internal\n */\ntype UnionToIntersection<U> = (U extends unknown ? (k: U) => void : never) extends (\n  k: infer I\n) => void\n  ? I\n  : never;\n\n/**\n * Create a typed link props object for a route\n *\n * @template TPath - The route path\n *\n * @example\n * ```typescript\n * type UserLinkProps = TypedLinkProps<'/users/:id'>;\n * // { to: '/users/:id'; params: { id: string }; query?: Record<string, string> }\n * ```\n */\nexport type TypedLinkProps<TPath extends string> =\n  RequiresParams<TPath> extends true\n    ? {\n        readonly to: TPath;\n        readonly params: RouteParams<TPath>;\n        readonly query?: Record<string, string | undefined>;\n      }\n    : HasOnlyOptionalParams<TPath> extends true\n      ? {\n          readonly to: TPath;\n          readonly params?: RouteParams<TPath>;\n          readonly query?: Record<string, string | undefined>;\n        }\n      : {\n          readonly to: TPath;\n          readonly query?: Record<string, string | undefined>;\n        };\n\n/**\n * Create a type-safe navigation function type\n *\n * @template TPath - The route path\n *\n * @example\n * ```typescript\n * type NavigateToUser = TypedNavigate<'/users/:id'>;\n * const navigate: NavigateToUser = (params) => { ... };\n * navigate({ id: '123' }); // Type-safe!\n * ```\n */\nexport type TypedNavigate<TPath extends string> =\n  RequiresParams<TPath> extends true\n    ? (params: RouteParams<TPath>, options?: TypedNavigationOptions) => void\n    : HasOnlyOptionalParams<TPath> extends true\n      ? (params?: RouteParams<TPath>, options?: TypedNavigationOptions) => void\n      : (options?: TypedNavigationOptions) => void;\n\n/**\n * Validate that a path string matches the expected route pattern\n *\n * @template TPath - The route pattern\n * @template TActual - The actual path string to validate\n *\n * @example\n * ```typescript\n * type Valid = ValidatePath<'/users/:id', '/users/123'>; // true\n * type Invalid = ValidatePath<'/users/:id', '/posts/123'>; // false\n * ```\n */\nexport type ValidatePath<TPath extends string, TActual extends string> = TActual extends TPath\n  ? true\n  : false;\n\n/**\n * Build a URL path type from a pattern and params\n *\n * @template TPath - The route pattern\n * @template TParams - The parameters to substitute\n *\n * @example\n * ```typescript\n * type URL = BuildPath<'/users/:id', { id: '123' }>;\n * // Result: '/users/123'\n * ```\n */\nexport type BuildPath<\n  TPath extends string,\n  TParams extends Record<string, string>,\n> = TPath extends `${infer Start}:${infer Param}/${infer Rest}`\n  ? `${Start}${TParams[Param & keyof TParams]}/${BuildPath<`/${Rest}`, TParams>}`\n  : TPath extends `${infer Start}:${infer Param}`\n    ? `${Start}${TParams[Param & keyof TParams]}`\n    : TPath;\n\n/**\n * Extract query param types from a search params schema\n *\n * @template TSchema - A Zod schema or object type\n */\nexport type QueryParamsFromSchema<TSchema> = TSchema extends { parse: (data: unknown) => infer R }\n  ? R extends Record<string, unknown>\n    ? R\n    : never\n  : TSchema extends Record<string, unknown>\n    ? TSchema\n    : never;\n\n/**\n * Create a complete route definition with all metadata\n *\n * @template TPath - The route path pattern\n * @template TMeta - Optional metadata type\n *\n * @example\n * ```typescript\n * const userRoute: CompleteRouteDefinition<'/users/:id', { title: string }> = {\n *   path: '/users/:id',\n *   params: ['id'],\n *   meta: { title: 'User Profile' },\n *   component: UserPage,\n * };\n * ```\n */\nexport type CompleteRouteDefinition<\n  TPath extends string,\n  TMeta extends Record<string, unknown> = Record<string, unknown>,\n> = {\n  readonly path: TPath;\n  readonly params: ReadonlyArray<ParamNames<TPath>>;\n  readonly meta?: TMeta;\n  readonly component: ComponentType<unknown>;\n  readonly loader?: LoaderFunction;\n  readonly action?: ActionFunction;\n  readonly errorElement?: ReactNode;\n};\n\n/**\n * Infer route types from a route configuration object\n *\n * @template TConfig - A route configuration object\n */\nexport type InferRouteTypes<TConfig extends Record<string, { path: string }>> = {\n  [K in keyof TConfig]: {\n    path: TConfig[K]['path'];\n    params: RouteParams<TConfig[K]['path']>;\n    builder: RouteBuilder<TConfig[K]['path']>;\n  };\n};\n\n/**\n * Create a type-safe route map from paths\n *\n * @template TPaths - A record of route names to path patterns\n *\n * @example\n * ```typescript\n * const routes = {\n *   home: '/',\n *   user: '/users/:id',\n *   post: '/posts/:postId',\n * } as const;\n *\n * type RouteMap = TypedRouteMap<typeof routes>;\n * // RouteMap.user.params = { id: string }\n * ```\n */\nexport type TypedRouteMap<TPaths extends Record<string, string>> = {\n  readonly [K in keyof TPaths]: {\n    readonly path: TPaths[K];\n    readonly params: RouteParams<TPaths[K]>;\n    readonly hasParams: HasParams<TPaths[K]>;\n    readonly requiresParams: RequiresParams<TPaths[K]>;\n  };\n};\n\n/**\n * Merge multiple route configurations\n *\n * @template TRoutes - An array of route configuration types\n */\nexport type MergeRoutes<TRoutes extends readonly Record<string, string>[]> =\n  TRoutes extends readonly [infer First, ...infer Rest]\n    ? First extends Record<string, string>\n      ? Rest extends readonly Record<string, string>[]\n        ? First & MergeRoutes<Rest>\n        : First\n      : never\n    : Record<string, never>;\n\n// =============================================================================\n// ROUTE PATH BUILDER UTILITIES\n// =============================================================================\n\n/**\n * Create a route path builder function with full type safety\n *\n * @deprecated Use `createRouteBuilder` from `./route-builder` instead.\n * This function has been removed to consolidate path building logic\n * and eliminate circular dependencies.\n *\n * @example\n * ```typescript\n * // Instead of:\n * import { createPathBuilder } from './types';\n * const userPath = createPathBuilder('/users/:id');\n *\n * // Use:\n * import { createRouteBuilder } from './route-builder';\n * const userPath = createRouteBuilder('/users/:id');\n * ```\n */\n// REMOVED: Re-export caused circular dependency (route-builder → scanner → types → route-builder)\n// Import directly from './route-builder' instead\n\n/**\n * Validate that provided params match the expected route params\n *\n * @param path - The route path pattern\n * @param params - The params to validate\n * @returns True if params are valid\n *\n * @example\n * ```typescript\n * validateRouteParams('/users/:id', { id: '123' }); // true\n * validateRouteParams('/users/:id', { userId: '123' }); // false\n * ```\n */\nexport function validateRouteParams<TPath extends string>(\n  path: TPath,\n  params: Record<string, unknown>\n): params is RouteParams<TPath> {\n  const expectedParams = (path.match(/:([a-zA-Z0-9_]+)\\??/g) ?? []).map((p) => p.slice(1));\n  const providedParams = Object.keys(params);\n\n  // Check all required params are provided\n  const requiredParams = expectedParams.filter((p) => !p.endsWith('?'));\n  for (const required of requiredParams) {\n    if (!providedParams.includes(required)) {\n      return false;\n    }\n  }\n\n  return true;\n}\n\n/**\n * Extract parameter names from a route path\n *\n * @deprecated Use `extractParamNames` from `./scanner` instead.\n * Re-export removed to eliminate circular dependencies.\n *\n * @example\n * ```typescript\n * // Instead of:\n * import { extractParamNames } from './types';\n *\n * // Use:\n * import { extractParamNames } from './scanner';\n * ```\n */\n// REMOVED: Re-export caused circular dependency (scanner → types → scanner)\n// Import directly from './scanner' instead\n\n/**\n * Check if a path matches a route pattern\n *\n * @param pattern - The route pattern\n * @param path - The actual path to check\n * @returns True if the path matches the pattern\n *\n * @example\n * ```typescript\n * matchesPattern('/users/:id', '/users/123'); // true\n * matchesPattern('/users/:id', '/posts/123'); // false\n * ```\n */\nexport function matchesPattern(pattern: string, path: string): boolean {\n  const regexPattern = pattern\n    .replace(/:[^/?]+\\?/g, '([^/]*)?') // Optional params\n    .replace(/:[^/]+/g, '([^/]+)') // Required params\n    .replace(/\\//g, '\\\\/');\n\n  const regex = new RegExp(`^${regexPattern}$`);\n  return regex.test(path);\n}\n\n/**\n * Parse route params from a path given a pattern\n *\n * @param pattern - The route pattern\n * @param path - The actual path to parse\n * @returns The parsed parameters or null if no match\n *\n * @example\n * ```typescript\n * parseRouteParams('/users/:id', '/users/123');\n * // { id: '123' }\n * ```\n */\nexport function parseRouteParams<TPath extends string>(\n  pattern: TPath,\n  path: string\n): RouteParams<TPath> | null {\n  const paramNames = (pattern.match(/:([a-zA-Z0-9_]+)\\??/g) ?? []).map((p) => p.slice(1));\n  const regexPattern = pattern\n    .replace(/:[^/?]+\\?/g, '([^/]*)?')\n    .replace(/:[^/]+/g, '([^/]+)')\n    .replace(/\\//g, '\\\\/');\n\n  const regex = new RegExp(`^${regexPattern}$`);\n  const match = path.match(regex);\n\n  if (!match) {\n    return null;\n  }\n\n  const params: Record<string, string> = {};\n  for (let i = 0; i < paramNames.length; i++) {\n    const value = match[i + 1];\n    const name = paramNames[i];\n    if (value !== undefined && value !== '' && name !== undefined && name !== '') {\n      params[name] = decodeURIComponent(value);\n    }\n  }\n\n  return params as RouteParams<TPath>;\n}\n\n// =============================================================================\n// ADVANCED DISCOVERY TYPES\n// =============================================================================\n\n/**\n * Extended discovery configuration for advanced scanning\n */\nexport interface AdvancedDiscoveryConfig extends DiscoveryConfig {\n  /** Enable watch mode for hot reloading */\n  readonly watchMode?: boolean;\n  /** Debounce delay for file changes (ms) */\n  readonly debounceMs?: number;\n  /** Enable code generation */\n  readonly generateCode?: boolean;\n  /** Output directory for generated code */\n  readonly outputDir?: string;\n  /** Custom file type classifier */\n  readonly classifyFile?: (filename: string) => string;\n}\n\n// =============================================================================\n// PARALLEL ROUTES TYPES\n// =============================================================================\n\n/**\n * Parallel route slot definition\n */\nexport interface ParallelRouteSlotDefinition {\n  /** Slot name (e.g., '@modal', '@sidebar') */\n  readonly name: string;\n  /** Component to render in slot */\n  readonly component: ComponentType<unknown>;\n  /** Loading fallback */\n  readonly loading?: ComponentType;\n  /** Error fallback */\n  readonly error?: ComponentType<{ error: Error }>;\n  /** Default when slot is inactive */\n  readonly default?: ComponentType;\n}\n\n/**\n * Parallel routes configuration\n */\nexport interface ParallelRoutesDefinition {\n  /** Named slots */\n  readonly slots: Record<string, ParallelRouteSlotDefinition>;\n  /** Layout wrapping all slots */\n  readonly layout?: ComponentType<{ children: ReactNode }>;\n}\n\n// =============================================================================\n// INTERCEPTING ROUTES TYPES\n// =============================================================================\n\n/**\n * Interception level for route interception\n */\nexport type InterceptionLevelType = '.' | '..' | '...' | '....';\n\n/**\n * Intercepting route definition\n */\nexport interface InterceptingRouteDefinition {\n  /** Route pattern to intercept */\n  readonly pattern: string;\n  /** Interception level */\n  readonly level: InterceptionLevelType;\n  /** Component for intercepted view */\n  readonly interceptComponent: ComponentType<unknown>;\n  /** Component for full page view */\n  readonly fullComponent: ComponentType<unknown>;\n  /** Allowed origin paths */\n  readonly allowedOrigins?: readonly string[];\n}\n\n// =============================================================================\n// ROUTE GUARD TYPES\n// =============================================================================\n\n/**\n * Guard execution timing\n */\nexport type GuardTimingType = 'canActivate' | 'canDeactivate' | 'canMatch' | 'canLoad';\n\n/**\n * Guard result type\n */\nexport type GuardResultType = 'allow' | 'deny' | 'redirect' | 'pending';\n\n/**\n * Route guard result\n */\nexport interface RouteGuardResult {\n  /** Result type */\n  readonly type: GuardResultType;\n  /** Redirect path (if redirect) */\n  readonly redirectTo?: string;\n  /** Denial reason (if deny) */\n  readonly reason?: string;\n  /** Additional data */\n  readonly data?: Record<string, unknown>;\n}\n\n/**\n * Guard context passed to guard functions\n */\nexport interface RouteGuardContext {\n  /** Target path */\n  readonly path: string;\n  /** Route parameters */\n  readonly params: Record<string, string>;\n  /** Query parameters */\n  readonly query: Record<string, string>;\n  /** Current user */\n  readonly user?: RouteGuardUser;\n  /** Feature flags */\n  readonly features?: Record<string, boolean>;\n  /** Custom data */\n  readonly data: Record<string, unknown>;\n}\n\n/**\n * User context for guards\n */\nexport interface RouteGuardUser {\n  /** User ID */\n  readonly id: string;\n  /** Is authenticated */\n  readonly isAuthenticated: boolean;\n  /** User roles */\n  readonly roles: readonly string[];\n  /** User permissions */\n  readonly permissions: readonly string[];\n}\n\n/**\n * Route guard function type\n */\nexport type RouteGuardFunction = (\n  context: RouteGuardContext\n) => RouteGuardResult | Promise<RouteGuardResult>;\n\n/**\n * Route guard configuration\n */\nexport interface RouteGuardConfig {\n  /** Guard name */\n  readonly name: string;\n  /** Guard priority (lower = first) */\n  readonly priority?: number;\n  /** Routes to apply to */\n  readonly routes?: readonly string[];\n  /** Routes to exclude */\n  readonly exclude?: readonly string[];\n  /** Guard implementation */\n  readonly canActivate?: RouteGuardFunction;\n  /** Deactivation guard */\n  readonly canDeactivate?: RouteGuardFunction;\n}\n\n// =============================================================================\n// ROUTE MIDDLEWARE TYPES\n// =============================================================================\n\n/**\n * Route middleware function type\n */\nexport type RouteMiddlewareFunction = (\n  context: RouteMiddlewareContext,\n  next: () => void | Promise<void>\n) => void | Promise<void>;\n\n/**\n * Route middleware configuration\n */\nexport interface RouteMiddlewareConfig {\n  /** Middleware name */\n  readonly name: string;\n  /** Middleware function */\n  readonly handler: RouteMiddlewareFunction;\n  /** Priority (lower = first) */\n  readonly priority?: number;\n  /** Routes to apply to */\n  readonly routes?: readonly string[];\n  /** Routes to exclude */\n  readonly exclude?: readonly string[];\n}\n\n// =============================================================================\n// ROUTE GROUP TYPES\n// =============================================================================\n\n/**\n * Route group configuration\n */\nexport interface RouteGroupDefinition {\n  /** Group name */\n  readonly name: string;\n  /** Display name */\n  readonly displayName?: string;\n  /** Group layout component */\n  readonly layout?: ComponentType<{ children: ReactNode }>;\n  /** Guards for all routes in group */\n  readonly guards?: readonly RouteGuardConfig[];\n  /** Middleware for all routes in group */\n  readonly middleware?: readonly RouteMiddlewareConfig[];\n  /** Group metadata */\n  readonly meta?: RouteGroupMetadata;\n  /** Parent group */\n  readonly parent?: string;\n}\n\n/**\n * Route group metadata\n */\nexport interface RouteGroupMetadata {\n  /** Requires authentication */\n  readonly requiresAuth?: boolean;\n  /** Required roles */\n  readonly roles?: readonly string[];\n  /** Required permissions */\n  readonly permissions?: readonly string[];\n  /** Feature flag dependency */\n  readonly featureFlag?: string;\n}\n\n// =============================================================================\n// CATCH-ALL ROUTE TYPES\n// =============================================================================\n\n/**\n * Catch-all route configuration\n */\nexport interface CatchAllRouteDefinition {\n  /** Base path */\n  readonly basePath: string;\n  /** Parameter name for segments */\n  readonly paramName: string;\n  /** Whether optional (can match base path alone) */\n  readonly optional: boolean;\n  /** Component to render */\n  readonly component: ComponentType<CatchAllRouteComponentProps>;\n  /** Maximum segments allowed */\n  readonly maxSegments?: number;\n  /** Segment validator */\n  readonly validateSegment?: (segment: string) => boolean;\n}\n\n/**\n * Props passed to catch-all route component\n */\nexport interface CatchAllRouteComponentProps {\n  /** Captured segments */\n  readonly segments: readonly string[];\n  /** Joined path */\n  readonly joinedPath: string;\n  /** Segment count */\n  readonly depth: number;\n  /** Is base path (no segments) */\n  readonly isBase: boolean;\n}\n\n// =============================================================================\n// OPTIONAL SEGMENT TYPES\n// =============================================================================\n\n/**\n * Optional segment configuration\n */\nexport interface OptionalSegmentDefinition<T = string> {\n  /** Segment name */\n  readonly name: string;\n  /** Default value */\n  readonly defaultValue: T;\n  /** Validator */\n  readonly validate?: (value: string) => boolean;\n  /** Transformer */\n  readonly transform?: (value: string) => T;\n  /** Allowed values */\n  readonly allowedValues?: readonly T[];\n}\n\n/**\n * Route with optional segments\n */\nexport interface OptionalSegmentRouteDefinition {\n  /** Base path */\n  readonly basePath: string;\n  /** Optional segments */\n  readonly segments: readonly OptionalSegmentDefinition[];\n  /** Component */\n  readonly component: ComponentType<unknown>;\n}\n\n// =============================================================================\n// DISCOVERY EVENT TYPES\n// =============================================================================\n\n/**\n * Discovery event type\n */\nexport type RouteDiscoveryEventType =\n  | 'scan-start'\n  | 'scan-complete'\n  | 'route-found'\n  | 'route-changed'\n  | 'route-removed'\n  | 'error';\n\n/**\n * Discovery event\n */\nexport interface RouteDiscoveryEvent {\n  /** Event type */\n  readonly type: RouteDiscoveryEventType;\n  /** Event timestamp */\n  readonly timestamp: number;\n  /** Event data */\n  readonly data?: unknown;\n}\n\n/**\n * Discovery event listener\n */\nexport type RouteDiscoveryEventListener = (event: RouteDiscoveryEvent) => void;\n"],"names":["DEFAULT_PREFETCH_CONFIG"],"mappings":"AAklBO,MAAMA,IAA+C;AAAA,EAC1D,UAAU;AAAA,EACV,UAAU;AAAA,EACV,OAAO;AAAA,EACP,aAAa;AAAA,EACb,mBAAmB;AAAA,IACjB,YAAY;AAAA,IACZ,kBAAkB;AAAA,EAAA;AAEtB;"}