/** * @file Optional Route Segments Support * @description Implements optional route segment patterns for flexible URL matching. * Enables routes that can match with or without certain path segments. * * @module @/lib/routing/advanced/optional-segments * * This module provides: * - Optional segment definitions * - Default value handling * - Conditional segment rendering * - Type-safe optional params * - Segment presence detection * * @example * ```typescript * import { OptionalSegment, createOptionalSegment } from '@/lib/routing/advanced/optional-segments'; * * // Route: /products/[[category]]/[[page]] * const segment = createOptionalSegment({ * name: 'category', * defaultValue: 'all', * validate: (v) => ['all', 'electronics', 'clothing'].includes(v), * }); * * const value = segment.resolve('/products'); // 'all' * const value2 = segment.resolve('/products/electronics'); // 'electronics' * ``` */ /** * Optional segment configuration */ export interface OptionalSegmentConfig { /** Segment parameter name */ readonly name: string; /** Default value when segment is not present */ readonly defaultValue: T; /** Validate segment value */ readonly validate?: (value: string) => boolean; /** Transform segment value */ readonly transform?: (value: string) => T; /** Allowed values (enum-style) */ readonly allowedValues?: readonly T[]; /** Position in the path (0-indexed from optional segments) */ readonly position?: number; /** Description for documentation */ readonly description?: string; /** Feature flag for this segment */ readonly featureFlag?: string; } /** * Optional segment resolution result */ export interface OptionalSegmentResolution { /** Whether segment was present in path */ readonly present: boolean; /** Resolved value (actual or default) */ readonly value: T; /** Raw string value (before transformation) */ readonly rawValue: string | null; /** Validation result */ readonly valid: boolean; /** Validation error (if any) */ readonly error: string | null; } /** * Route with optional segments */ export interface OptionalSegmentRoute { /** Base path (static portion) */ readonly basePath: string; /** Optional segments in order */ readonly segments: readonly OptionalSegmentConfig[]; /** Full pattern string */ readonly pattern: string; /** Minimum path length (static + required) */ readonly minLength: number; /** Maximum path length (static + all optional) */ readonly maxLength: number; } /** * Match result for optional segment route */ export interface OptionalRouteMatch { /** Whether path matches the route */ readonly matches: boolean; /** Resolved segment values */ readonly values: Record; /** Which segments were present */ readonly presentSegments: readonly string[]; /** Which segments used defaults */ readonly defaultedSegments: readonly string[]; /** Validation errors by segment */ readonly errors: Record; /** Match score for priority sorting */ readonly score: number; } /** * Optional segment builder configuration */ export interface OptionalRouteBuilderConfig { /** Base path */ readonly basePath: string; /** Segments to add */ readonly segments: readonly OptionalSegmentConfig[]; /** Strict mode (reject unknown segments) */ readonly strict?: boolean; } /** * Manages a single optional segment * * @example * ```typescript * const segment = new OptionalSegment({ * name: 'page', * defaultValue: '1', * transform: (v) => parseInt(v, 10), * validate: (v) => /^\d+$/.test(v), * }); * * const result = segment.resolve('5'); * // { present: true, value: 5, rawValue: '5', valid: true, error: null } * ``` */ export declare class OptionalSegment { private readonly config; constructor(config: OptionalSegmentConfig); /** * Get segment name */ getName(): string; /** * Get default value */ getDefault(): T; /** * Resolve a segment value * * @param value - Raw segment value or undefined * @returns Resolution result */ resolve(value: string | undefined | null): OptionalSegmentResolution; /** * Get the pattern string for this segment */ getPatternString(): string; /** * Get configuration */ getConfig(): Readonly>; } /** * Manages a route with optional segments * * @example * ```typescript * const route = new OptionalSegmentRouteBuilder({ * basePath: '/products', * segments: [ * { name: 'category', defaultValue: 'all' }, * { name: 'page', defaultValue: '1', transform: (v) => parseInt(v, 10) }, * ], * }); * * const match = route.match('/products/electronics/2'); * // { matches: true, values: { category: 'electronics', page: 2 }, ... } * ``` */ export declare class OptionalSegmentRouteBuilder { private readonly config; private readonly segments; private readonly orderedSegments; private readonly pattern; constructor(config: OptionalRouteBuilderConfig); /** * Match a path against this route * * @param path - URL path to match * @returns Match result */ match(path: string): OptionalRouteMatch; /** * Build a path from segment values * * @param values - Segment values * @param options - Build options * @returns Built path */ buildPath(values: Partial>, options?: { includeDefaults?: boolean; }): string; /** * Get pattern string for display */ getPatternString(): string; /** * Get segment by name * * @param name - Segment name */ getSegment(name: string): OptionalSegment | undefined; /** * Get all segments */ getAllSegments(): readonly OptionalSegment[]; /** * Get configuration */ getConfig(): Readonly; /** * Build regex pattern for matching */ private buildPattern; } /** * Manages multiple optional segment routes */ export declare class OptionalSegmentManager { private routes; private idCounter; /** * Register a route with optional segments * * @param config - Route configuration * @returns Route ID */ register(config: OptionalRouteBuilderConfig): string; /** * Unregister a route * * @param id - Route ID * @returns True if route was found and removed */ unregister(id: string): boolean; /** * Find best matching route for a path * * @param path - URL path * @returns Best match or null */ findBestMatch(path: string): { route: OptionalSegmentRouteBuilder; match: OptionalRouteMatch; id: string; } | null; /** * Get all registered routes */ getAllRoutes(): readonly { id: string; route: OptionalSegmentRouteBuilder; }[]; /** * Get a specific route */ getRoute(id: string): OptionalSegmentRouteBuilder | undefined; /** * Clear all routes */ clearAll(): void; } /** * Create an optional segment configuration * * @param config - Segment configuration * @returns OptionalSegment instance */ export declare function createOptionalSegment(config: OptionalSegmentConfig): OptionalSegment; /** * Create a route with optional segments * * @param config - Route configuration * @returns OptionalSegmentRouteBuilder instance */ export declare function createOptionalRoute(config: OptionalRouteBuilderConfig): OptionalSegmentRouteBuilder; /** * Create a pagination optional segment * * @param options - Options * @returns Configured OptionalSegment for pagination */ export declare function createPaginationSegment(options?: { name?: string; defaultPage?: number; maxPage?: number; }): OptionalSegment; /** * Create a category filter optional segment * * @param categories - Allowed categories * @param defaultCategory - Default category * @returns Configured OptionalSegment for categories */ export declare function createCategorySegment(categories: readonly string[], defaultCategory: string): OptionalSegment; /** * Create a sort order optional segment * * @param options - Sort options * @returns Configured OptionalSegment for sorting */ export declare function createSortSegment(options?: { allowedValues?: readonly string[]; defaultValue?: string; }): OptionalSegment; /** * Get the default optional segment manager */ export declare function getOptionalSegmentManager(): OptionalSegmentManager; /** * Reset the default optional segment manager */ export declare function resetOptionalSegmentManager(): void; /** * Check if a pattern contains optional segments * * @param pattern - Route pattern * @returns True if pattern has optional segments */ export declare function hasOptionalSegments(pattern: string): boolean; /** * Extract optional segment names from a pattern * * @param pattern - Route pattern * @returns Array of optional segment names */ export declare function extractOptionalSegmentNames(pattern: string): string[]; /** * Convert pattern with optional segments to regex-friendly pattern * * @param pattern - Route pattern with optional segments * @returns Pattern suitable for regex */ export declare function normalizeOptionalPattern(pattern: string): string; /** * Build all possible paths for a route with optional segments * * @param basePath - Base path * @param segments - Optional segment configs * @returns Array of all possible path combinations */ export declare function buildAllPossiblePaths(basePath: string, segments: readonly OptionalSegmentConfig[]): string[]; /** * Type guard for OptionalSegmentResolution */ export declare function isOptionalSegmentResolution(value: unknown): value is OptionalSegmentResolution; /** * Type guard for OptionalRouteMatch */ export declare function isOptionalRouteMatch(value: unknown): value is OptionalRouteMatch;