{"version":3,"file":"path-utils.mjs","sources":["../../../../src/lib/routing/core/path-utils.ts"],"sourcesContent":["/**\n * @file Core Path Utilities\n * @description Framework-agnostic path building, parameter extraction, and pattern matching utilities.\n * This module provides reusable functions for working with URL paths and route patterns\n * that can be used in any JavaScript/TypeScript project.\n *\n * @module @/lib/routing/core/path-utils\n *\n * @example\n * ```typescript\n * import {\n *   buildPath,\n *   extractParamNames,\n *   matchPathPattern,\n *   parsePathParams,\n * } from '@/lib/routing/core/path-utils';\n *\n * // Build a path with parameters\n * buildPath('/users/:id', { id: '123' }); // '/users/123'\n *\n * // Extract parameter names from a pattern\n * extractParamNames('/users/:id/posts/:postId'); // ['id', 'postId']\n *\n * // Check if a path matches a pattern\n * matchPathPattern('/users/:id', '/users/123'); // true\n *\n * // Parse parameters from a matched path\n * parsePathParams('/users/:id', '/users/123'); // { id: '123' }\n * ```\n */\n\n// =============================================================================\n// Path Building\n// =============================================================================\n\n/**\n * Build a URL path from a pattern and parameters\n *\n * Supports:\n * - Required parameters: `:id`\n * - Optional parameters: `:id?`\n * - Query string parameters\n *\n * @param pattern - Route pattern with parameter placeholders\n * @param params - Object containing parameter values\n * @param query - Optional query string parameters\n * @returns The built URL path\n *\n * @example\n * ```typescript\n * buildPath('/users/:id', { id: '123' }); // '/users/123'\n * buildPath('/users/:id?', {}); // '/users'\n * buildPath('/users/:id', { id: '123' }, { tab: 'settings' }); // '/users/123?tab=settings'\n * ```\n */\nexport function buildPath(\n  pattern: string,\n  params?: Record<string, string | number | undefined>,\n  query?: Record<string, string | number | undefined>\n): string {\n  let path = pattern;\n\n  // Replace parameters\n  if (params) {\n    for (const [key, value] of Object.entries(params)) {\n      if (value !== undefined && value !== null) {\n        // Replace both required and optional params\n        path = path.replace(`:${key}?`, encodeURIComponent(String(value)));\n        path = path.replace(`:${key}`, encodeURIComponent(String(value)));\n      }\n    }\n  }\n\n  // Remove unfilled optional params\n  path = path.replace(/\\/:[^/]+\\?/g, '');\n\n  // Clean up any double slashes\n  path = path.replace(/\\/+/g, '/');\n\n  // Add query string\n  if (query && Object.keys(query).length > 0) {\n    const searchParams = new URLSearchParams();\n    for (const [key, value] of Object.entries(query)) {\n      if (value !== undefined && value !== null && value !== '') {\n        searchParams.set(key, String(value));\n      }\n    }\n    const queryString = searchParams.toString();\n    if (queryString) {\n      path = `${path}?${queryString}`;\n    }\n  }\n\n  return path;\n}\n\n/**\n * Build a query string from parameters\n *\n * @param query - Query parameters object\n * @returns Query string (without leading ?)\n *\n * @example\n * ```typescript\n * buildQueryString({ page: 1, sort: 'name' }); // 'page=1&sort=name'\n * buildQueryString({ filter: undefined, sort: 'name' }); // 'sort=name'\n * ```\n */\nexport function buildQueryString(\n  query: Record<string, string | number | boolean | undefined>\n): string {\n  const searchParams = new URLSearchParams();\n  for (const [key, value] of Object.entries(query)) {\n    if (value !== undefined && value !== null && value !== '') {\n      searchParams.set(key, String(value));\n    }\n  }\n  return searchParams.toString();\n}\n\n/**\n * Parse query string into parameters object\n *\n * @param queryString - Query string to parse (with or without leading ?)\n * @returns Parsed query parameters\n *\n * @example\n * ```typescript\n * parseQueryString('?page=1&sort=name'); // { page: '1', sort: 'name' }\n * parseQueryString('page=1&sort=name'); // { page: '1', sort: 'name' }\n * ```\n */\nexport function parseQueryString(queryString: string): Record<string, string> {\n  const cleanQuery = queryString.startsWith('?') ? queryString.slice(1) : queryString;\n  const params = new URLSearchParams(cleanQuery);\n  const result: Record<string, string> = {};\n  params.forEach((value, key) => {\n    result[key] = value;\n  });\n  return result;\n}\n\n// =============================================================================\n// Parameter Extraction\n// =============================================================================\n\n/**\n * Extract parameter names from a route pattern\n *\n * @param pattern - Route pattern with parameter placeholders\n * @returns Array of parameter names (without : prefix)\n *\n * @example\n * ```typescript\n * extractParamNames('/users/:id'); // ['id']\n * extractParamNames('/users/:id/posts/:postId'); // ['id', 'postId']\n * extractParamNames('/search/:query?'); // ['query']\n * ```\n */\nexport function extractParamNames(pattern: string): string[] {\n  const matches = pattern.match(/:[^/?]+/g) ?? [];\n  return matches.map((m) => m.slice(1).replace('?', ''));\n}\n\n/**\n * Extract required parameter names from a route pattern\n *\n * @param pattern - Route pattern with parameter placeholders\n * @returns Array of required parameter names\n *\n * @example\n * ```typescript\n * extractRequiredParams('/users/:id/:tab?'); // ['id']\n * ```\n */\nexport function extractRequiredParams(pattern: string): string[] {\n  const allParams = extractParamNames(pattern);\n  return allParams.filter((param) => !pattern.includes(`:${param}?`));\n}\n\n/**\n * Extract optional parameter names from a route pattern\n *\n * @param pattern - Route pattern with parameter placeholders\n * @returns Array of optional parameter names\n *\n * @example\n * ```typescript\n * extractOptionalParams('/users/:id/:tab?'); // ['tab']\n * ```\n */\nexport function extractOptionalParams(pattern: string): string[] {\n  const matches = pattern.match(/:[^/]+\\?/g) ?? [];\n  return matches.map((m) => m.slice(1, -1));\n}\n\n/**\n * Check if a route pattern has any parameters\n *\n * @param pattern - Route pattern to check\n * @returns True if the pattern contains parameters\n *\n * @example\n * ```typescript\n * hasParams('/users/:id'); // true\n * hasParams('/about'); // false\n * ```\n */\nexport function hasParams(pattern: string): boolean {\n  return /:/.test(pattern);\n}\n\n/**\n * Check if a route pattern has any dynamic segments\n * (alias for hasParams for clarity)\n *\n * @param pattern - Route pattern to check\n * @returns True if the pattern contains dynamic segments\n */\nexport function hasDynamicSegments(pattern: string): boolean {\n  return hasParams(pattern);\n}\n\n/**\n * Check if a route pattern has a catch-all segment\n *\n * @param pattern - Route pattern to check\n * @returns True if the pattern contains a catch-all segment\n *\n * @example\n * ```typescript\n * hasCatchAll('/docs/*'); // true\n * hasCatchAll('/users/:id'); // false\n * ```\n */\nexport function hasCatchAll(pattern: string): boolean {\n  return /\\*/.test(pattern);\n}\n\n// =============================================================================\n// Pattern Matching\n// =============================================================================\n\n/**\n * Check if a path matches a route pattern\n *\n * @param pattern - Route pattern with parameter placeholders\n * @param path - Actual path to match\n * @returns True if the path matches the pattern\n *\n * @example\n * ```typescript\n * matchPathPattern('/users/:id', '/users/123'); // true\n * matchPathPattern('/users/:id', '/posts/123'); // false\n * matchPathPattern('/docs/*', '/docs/getting-started/installation'); // true\n * ```\n */\nexport function matchPathPattern(pattern: string, path: string): boolean {\n  const patternParts = pattern.split('/').filter(Boolean);\n  const pathParts = path.split('/').filter(Boolean);\n\n  // Handle catch-all\n  if (pattern.includes('*')) {\n    const catchAllIndex = patternParts.findIndex((p) => p === '*');\n    if (catchAllIndex !== -1) {\n      // Everything before catch-all must match\n      for (let i = 0; i < catchAllIndex; i++) {\n        const patternPart = patternParts[i];\n        const pathPart = pathParts[i];\n        if (\n          patternPart !== undefined &&\n          patternPart !== '' &&\n          !matchSegment(patternPart, pathPart)\n        ) {\n          return false;\n        }\n      }\n      return true;\n    }\n  }\n\n  // Different lengths (accounting for optional params)\n  const optionalCount = patternParts.filter((p) => p.endsWith('?')).length;\n  if (\n    pathParts.length < patternParts.length - optionalCount ||\n    pathParts.length > patternParts.length\n  ) {\n    return false;\n  }\n\n  // Check each segment\n  for (let i = 0; i < patternParts.length; i++) {\n    const patternPart = patternParts[i];\n    const pathPart = pathParts[i];\n\n    if (patternPart == null) {\n      continue;\n    }\n\n    // Optional param at end with no corresponding path part\n    if (patternPart.endsWith('?') && pathPart === undefined) {\n      continue;\n    }\n\n    if (!matchSegment(patternPart, pathPart)) {\n      return false;\n    }\n  }\n\n  return true;\n}\n\n/**\n * Check if a single path segment matches a pattern segment\n *\n * @param pattern - Pattern segment (may include : for params)\n * @param segment - Actual path segment\n * @returns True if the segment matches\n */\nfunction matchSegment(pattern: string, segment: string | undefined): boolean {\n  if (segment === undefined) return false;\n\n  // Dynamic segment matches anything\n  if (pattern.startsWith(':')) {\n    return true;\n  }\n\n  // Static segment must match exactly\n  return pattern === segment;\n}\n\n/**\n * Parse path parameters from a path using a pattern\n *\n * @param pattern - Route pattern with parameter placeholders\n * @param path - Actual path to parse\n * @returns Object containing parsed parameters, or null if no match\n *\n * @example\n * ```typescript\n * parsePathParams('/users/:id', '/users/123'); // { id: '123' }\n * parsePathParams('/users/:id/posts/:postId', '/users/123/posts/456'); // { id: '123', postId: '456' }\n * parsePathParams('/users/:id', '/posts/123'); // null\n * ```\n */\nexport function parsePathParams(pattern: string, path: string): Record<string, string> | null {\n  if (!matchPathPattern(pattern, path)) {\n    return null;\n  }\n\n  const patternParts = pattern.split('/').filter(Boolean);\n  const pathParts = path.split('/').filter(Boolean);\n  const params: Record<string, string> = {};\n\n  for (let i = 0; i < patternParts.length; i++) {\n    const patternPart = patternParts[i];\n    const pathPart = pathParts[i];\n\n    const startsWithColon = patternPart?.startsWith(':') === true;\n    if (startsWithColon && patternPart !== undefined) {\n      const paramName = patternPart.slice(1).replace('?', '');\n      if (pathPart !== undefined) {\n        params[paramName] = decodeURIComponent(pathPart);\n      }\n    }\n  }\n\n  // Handle catch-all\n  const catchAllIndex = patternParts.findIndex((p) => p === '*');\n  if (catchAllIndex !== -1) {\n    params['*'] = pathParts.slice(catchAllIndex).join('/');\n  }\n\n  return params;\n}\n\n// =============================================================================\n// Path Utilities\n// =============================================================================\n\n/**\n * Get the static prefix of a path (before first dynamic segment)\n *\n * @param pattern - Route pattern\n * @returns Static prefix of the path\n *\n * @example\n * ```typescript\n * getStaticPrefix('/users/:id/posts'); // '/users'\n * getStaticPrefix('/about'); // '/about'\n * ```\n */\nexport function getStaticPrefix(pattern: string): string {\n  const firstDynamic = pattern.indexOf(':');\n  if (firstDynamic === -1) return pattern;\n  return pattern.slice(0, firstDynamic).replace(/\\/$/, '');\n}\n\n/**\n * Normalize a path by removing trailing slashes and ensuring leading slash\n *\n * @param path - Path to normalize\n * @returns Normalized path\n *\n * @example\n * ```typescript\n * normalizePath('users/123/'); // '/users/123'\n * normalizePath('/users/123/'); // '/users/123'\n * ```\n */\nexport function normalizePath(path: string): string {\n  let normalized = path;\n\n  // Ensure leading slash\n  if (!normalized.startsWith('/')) {\n    normalized = `/${normalized}`;\n  }\n\n  // Remove trailing slash (except for root)\n  if (normalized.length > 1 && normalized.endsWith('/')) {\n    normalized = normalized.slice(0, -1);\n  }\n\n  // Remove double slashes\n  normalized = normalized.replace(/\\/+/g, '/');\n\n  return normalized;\n}\n\n/**\n * Join path segments into a single path\n *\n * @param segments - Path segments to join\n * @returns Joined path\n *\n * @example\n * ```typescript\n * joinPath('/users', '123', 'posts'); // '/users/123/posts'\n * joinPath('users/', '/123/', '/posts'); // '/users/123/posts'\n * ```\n */\nexport function joinPath(...segments: string[]): string {\n  const joined = segments\n    .map((s) => s.replace(/^\\/+|\\/+$/g, ''))\n    .filter(Boolean)\n    .join('/');\n  return `/${joined}`;\n}\n\n/**\n * Split a path into segments\n *\n * @param path - Path to split\n * @returns Array of path segments\n *\n * @example\n * ```typescript\n * splitPath('/users/123/posts'); // ['users', '123', 'posts']\n * ```\n */\nexport function splitPath(path: string): string[] {\n  return path.split('/').filter(Boolean);\n}\n\n/**\n * Get the depth (number of segments) of a path\n *\n * @param path - Path to measure\n * @returns Number of path segments\n *\n * @example\n * ```typescript\n * getPathDepth('/users/123/posts'); // 3\n * getPathDepth('/'); // 0\n * ```\n */\nexport function getPathDepth(path: string): number {\n  return splitPath(path).length;\n}\n\n/**\n * Check if a path is a child of another path\n *\n * @param childPath - Potential child path\n * @param parentPath - Potential parent path\n * @returns True if childPath is a child of parentPath\n *\n * @example\n * ```typescript\n * isChildPath('/users/123', '/users'); // true\n * isChildPath('/posts/123', '/users'); // false\n * ```\n */\nexport function isChildPath(childPath: string, parentPath: string): boolean {\n  const normalizedChild = normalizePath(childPath);\n  const normalizedParent = normalizePath(parentPath);\n\n  if (normalizedParent === '/') {\n    return normalizedChild !== '/';\n  }\n\n  return normalizedChild.startsWith(`${normalizedParent}/`);\n}\n\n/**\n * Get the parent path of a given path\n *\n * @param path - Path to get parent of\n * @returns Parent path\n *\n * @example\n * ```typescript\n * getParentPath('/users/123/posts'); // '/users/123'\n * getParentPath('/users'); // '/'\n * ```\n */\nexport function getParentPath(path: string): string {\n  const segments = splitPath(path);\n  if (segments.length <= 1) return '/';\n  return `/${segments.slice(0, -1).join('/')}`;\n}\n\n/**\n * Get the last segment of a path\n *\n * @param path - Path to get last segment of\n * @returns Last path segment\n *\n * @example\n * ```typescript\n * getLastSegment('/users/123/posts'); // 'posts'\n * getLastSegment('/users'); // 'users'\n * ```\n */\nexport function getLastSegment(path: string): string {\n  const segments = splitPath(path);\n  const lastSegment = segments[segments.length - 1];\n  return lastSegment !== undefined && lastSegment !== '' ? lastSegment : '';\n}\n\n// =============================================================================\n// Route Specificity\n// =============================================================================\n\n/**\n * Calculate the specificity score of a route pattern\n *\n * Higher specificity = more specific route = should be matched first\n *\n * @param pattern - Route pattern to calculate specificity for\n * @returns Specificity score\n *\n * @example\n * ```typescript\n * getPatternSpecificity('/users/new'); // Higher\n * getPatternSpecificity('/users/:id'); // Lower\n * getPatternSpecificity('/users/*'); // Lowest\n * ```\n */\nexport function getPatternSpecificity(pattern: string): number {\n  const segments = splitPath(pattern);\n  let specificity = 0;\n\n  for (const segment of segments) {\n    if (segment === '*') {\n      specificity += 10;\n    } else if (segment.endsWith('?')) {\n      specificity += 30;\n    } else if (segment.startsWith(':')) {\n      specificity += 50;\n    } else {\n      specificity += 100;\n    }\n  }\n\n  return specificity;\n}\n\n/**\n * Compare two route patterns by specificity\n *\n * @param a - First pattern\n * @param b - Second pattern\n * @returns Negative if a is more specific, positive if b is more specific\n *\n * @example\n * ```typescript\n * ['/users/:id', '/users/new'].sort(comparePatternSpecificity);\n * // ['/users/new', '/users/:id']\n * ```\n */\nexport function comparePatternSpecificity(a: string, b: string): number {\n  return getPatternSpecificity(b) - getPatternSpecificity(a);\n}\n"],"names":["buildPath","pattern","params","query","path","key","value","searchParams","queryString","buildQueryString","parseQueryString","cleanQuery","result","extractParamNames","m","extractRequiredParams","param","extractOptionalParams","hasParams","hasDynamicSegments","hasCatchAll","matchPathPattern","patternParts","pathParts","catchAllIndex","p","i","patternPart","pathPart","matchSegment","optionalCount","segment","parsePathParams","paramName","getStaticPrefix","firstDynamic","normalizePath","normalized","joinPath","segments","s","splitPath","getPathDepth","isChildPath","childPath","parentPath","normalizedChild","normalizedParent","getParentPath","getLastSegment","lastSegment","getPatternSpecificity","specificity","comparePatternSpecificity","a","b"],"mappings":"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"}