All files / src matcher.ts

100% Statements 23/23
100% Branches 11/11
100% Functions 2/2
100% Lines 23/23

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62  2x 2x                   2x 156x 172x 4x     168x 36x 4x     132x 28x       136x 136x 46x 12x     90x 24x       100x     56x                         2x 166x 162x   152x    
import { Route } from './types'
import { parseRoutes } from './parser'
import { validateProtocol } from './validation'
 
/**
 * Matches a list of routes against a given URL to determine if a match is found.
 *
 * @param {URL} url - The URL to be matched against the provided routes.
 * @param {Route[]} routes - Array of route objects that define the matching criteria such as protocol, hostname, and path.
 *
 * @return {Route | undefined} Returns matched route, or undefined if no match is found.
 */
export function findMatchingRoute<Metadata>(url: URL, routes: Route<Metadata>[]): Route<Metadata> | undefined {
  for (const route of routes) {
    if (route.protocol && route.protocol !== url.protocol) {
      continue
    }
 
    if (route.wildcardHostnamePrefix) {
      if (!url.hostname.endsWith(route.hostname)) {
        continue
      }
    } else {
      if (url.hostname !== route.hostname) {
        continue
      }
    }
 
    const pathWithQuery = url.pathname + url.search
    if (route.wildcardPathSuffix) {
      if (!pathWithQuery.startsWith(route.path)) {
        continue
      }
    } else {
      if (pathWithQuery !== route.path) {
        continue
      }
    }
 
    return route
  }
 
  return undefined
}
 
/**
 * Matches a given URL against a list of string patterns to determine if it adheres to any specified pattern.
 *
 * @param {URL} url - The URL object that needs to be tested against the patterns.
 * @param {string[]} patterns - An array of string patterns that define the routes to match against.
 *
 * @throws {InvalidProtocolError} If provided URL protocol is not `http:` or `https:`.
 * @throws {InvalidPatternError} If one of the provided patterns contains a query string or infix wildcard.
 * @return {boolean} Returns true if the URL matches any of the given patterns; otherwise, returns false.
 */
export function matchesPatterns(url: URL, patterns: string[]): boolean {
  validateProtocol(url.protocol)
  const parsedRoutes = parseRoutes(patterns)
 
  return Boolean(findMatchingRoute(url, parsedRoutes))
}