src/index.js
function match(routes, path) {

  // Get the query object before it gets stripped by the normalizer
  const query = getQuery(path);
  const pathname = path;

  // Normalize the path
  path = normalizePath(path);

  // Loop over each route to find the match
  for (let i = 0; i < routes.length; i++) {

    // Normalize the current route
    const currentRoute = normalizePath(routes[i].route);

    // Create the params object
    const params = {};

    // Check if it's a straight match first
    if(currentRoute === path) {
      return Object.assign({}, routes[i], {params, query, pathname, path});
    }

    // If there are no dynamic/optional/match-all parts then this route cannot match
    if(!isDynamicRoute.test(routes[i].route)) {
      continue;
    }

    // Split up the route by it's slashes so that we may match by section
    const routeSections = currentRoute.split('/');
    const pathSections = path.split('/');

    // Loop over each section looking for a full match
    for (let j = routeSections.length - 1; j >= 0; j--) {

      // If the route is to match everything, then return
      if(j === 0 && routeSections[j] === '*') {
        return Object.assign({}, routes[i], {params, query, pathname, path});
      }

      // If this section is optional
      if(optionalSectionRegex.test(routeSections[j])) {

        const currentSection = routeSections[j].replace(removeOptionalRegex, '');

        // If it's a param, add it to the params
        if(paramRegex.test(currentSection)) {
          params[currentSection.replace(paramRegex, '')] = pathSections[j];
          continue;
        }

        // If it's a star then skip to next
        if(currentSection === '*') {
          continue;
        }

        // If the optional section can possible be missing skip to next section
        if(routeSections.length === pathSections.length + 1) {
          continue;
        }

        // If the path and route sections have same number of sections and this does match, skip to next
        if(routeSections.length === pathSections.length && currentSection === pathSections[j]) {
          continue;
        }

        // Reject this route as the possible match to the path
        break;
      }

      // If it's a param, add it to the params
      if(paramRegex.test(routeSections[j])) {
        params[routeSections[j].replace(paramRegex, '')] = pathSections[j];

        if(j === 0) {
          return Object.assign({}, routes[i], {params, query, pathname, path});
        }

        continue;
      }

      // If it's a star then skip to next
      if(routeSections[j] === '*') {
        continue;
      }

      // If this doesn't match then go to next route
      if(routeSections[j] !== pathSections[j]) {
        break;
      }

      // If the last item matches strictly then return that match
      if(j === 0 && routeSections[j] === pathSections[j]) {
        return Object.assign({}, routes[i], {params, query, pathname, path});
      }
    }
  }

  // No match found
  return {path: '', params: {}, query};
}
function match(routes, path) {

  // Get the query object before it gets stripped by the normalizer
  const query = getQuery(path);
  const pathname = path;

  // Normalize the path
  path = normalizePath(path);

  // Loop over each route to find the match
  for (let i = 0; i < routes.length; i++) {

    // Normalize the current route
    const currentRoute = normalizePath(routes[i].route);

    // Create the params object
    const params = {};

    // Check if it's a straight match first
    if(currentRoute === path) {
      return Object.assign({}, routes[i], {params, query, pathname, path});
    }

    // If there are no dynamic/optional/match-all parts then this route cannot match
    if(!isDynamicRoute.test(routes[i].route)) {
      continue;
    }

    // Split up the route by it's slashes so that we may match by section
    const routeSections = currentRoute.split('/');
    const pathSections = path.split('/');

    // Loop over each section looking for a full match
    for (let j = routeSections.length - 1; j >= 0; j--) {

      // If the route is to match everything, then return
      if(j === 0 && routeSections[j] === '*') {
        return Object.assign({}, routes[i], {params, query, pathname, path});
      }

      // If this section is optional
      if(optionalSectionRegex.test(routeSections[j])) {

        const currentSection = routeSections[j].replace(removeOptionalRegex, '');

        // If it's a param, add it to the params
        if(paramRegex.test(currentSection)) {
          params[currentSection.replace(paramRegex, '')] = pathSections[j];
          continue;
        }

        // If it's a star then skip to next
        if(currentSection === '*') {
          continue;
        }

        // If the optional section can possible be missing skip to next section
        if(routeSections.length === pathSections.length + 1) {
          continue;
        }

        // If the path and route sections have same number of sections and this does match, skip to next
        if(routeSections.length === pathSections.length && currentSection === pathSections[j]) {
          continue;
        }

        // Reject this route as the possible match to the path
        break;
      }

      // If it's a param, add it to the params
      if(paramRegex.test(routeSections[j])) {
        params[routeSections[j].replace(paramRegex, '')] = pathSections[j];

        if(j === 0) {
          return Object.assign({}, routes[i], {params, query, pathname, path});
        }

        continue;
      }

      // If it's a star then skip to next
      if(routeSections[j] === '*') {
        continue;
      }

      // If this doesn't match then go to next route
      if(routeSections[j] !== pathSections[j]) {
        break;
      }

      // If the last item matches strictly then return that match
      if(j === 0 && routeSections[j] === pathSections[j]) {
        return Object.assign({}, routes[i], {params, query, pathname, path});
      }
    }
  }

  // No match found
  return {path: '', params: {}, query};
}
function match ( routes , path ) { // Get the query object before it gets stripped by the normalizer const query = getQuery ( path ) ; const pathname = path ; // Normalize the path path = normalizePath ( path ) ; // Loop over each route to find the match for ( let i = 0 ; i < routes . length ; i ++ ) { // Normalize the current route const currentRoute = normalizePath ( routes [ i ] . route ) ; // Create the params object const params = { } ; // Check if it's a straight match first if ( currentRoute === path ) { return Object . assign ( { } , routes [ i ] , { params , query , pathname , path } ) ; } // If there are no dynamic/optional/match-all parts then this route cannot match if ( ! isDynamicRoute . test ( routes [ i ] . route ) ) { continue ; } // Split up the route by it's slashes so that we may match by section const routeSections = currentRoute . split ( '/' ) ; const pathSections = path . split ( '/' ) ; // Loop over each section looking for a full match for ( let j = routeSections . length - 1 ; j >= 0 ; j -- ) { // If the route is to match everything, then return if ( j === 0 && routeSections [ j ] === '*' ) { return Object . assign ( { } , routes [ i ] , { params , query , pathname , path } ) ; } // If this section is optional if ( optionalSectionRegex . test ( routeSections [ j ] ) ) { const currentSection = routeSections [ j ] . replace ( removeOptionalRegex , '' ) ; // If it's a param, add it to the params if ( paramRegex . test ( currentSection ) ) { params [ currentSection . replace ( paramRegex , '' ) ] = pathSections [ j ] ; continue ; } // If it's a star then skip to next if ( currentSection === '*' ) { continue ; } // If the optional section can possible be missing skip to next section if ( routeSections . length === pathSections . length + 1 ) { continue ; } // If the path and route sections have same number of sections and this does match, skip to next if ( routeSections . length === pathSections . length && currentSection === pathSections [ j ] ) { continue ; } // Reject this route as the possible match to the path break ; } // If it's a param, add it to the params if ( paramRegex . test ( routeSections [ j ] ) ) { params [ routeSections [ j ] . replace ( paramRegex , '' ) ] = pathSections [ j ] ; if ( j === 0 ) { return Object . assign ( { } , routes [ i ] , { params , query , pathname , path } ) ; } continue ; } // If it's a star then skip to next if ( routeSections [ j ] === '*' ) { continue ; } // If this doesn't match then go to next route if ( routeSections [ j ] !== pathSections [ j ] ) { break ; } // If the last item matches strictly then return that match if ( j === 0 && routeSections [ j ] === pathSections [ j ] ) { return Object . assign ( { } , routes [ i ] , { params , query , pathname , path } ) ; } } } // No match found return { path : '' , params : { } , query } ; }
Function to determine what route matches the current path
Function to determine what route matches the current path