UNPKG

frontitygit

Version:

A Frontity source package for the REST API of self-hosted and WordPress.com sites

126 lines (113 loc) 3.21 kB
import { Pattern } from "../../types"; import pathToRegexp, { Key } from "path-to-regexp"; /** * Extract the parameters of the `path-to-regexp` pattern from the link. * * @param link - The link that was matched. * @param regexp - The regexp from `path-to-regexp` that will be used. * @param keys - The array with keys generated by `path-to-regexp`. * * @returns An object with the parameter names and its corresponding values * from the link. */ const extractParameters = ( link: string, regexp: RegExp, keys: Key[] ): Record<string, string> => link // First remove the query and hash part. // These parameters are extracted from the pathname. .replace(/\?.*/, "") .match(regexp) .slice(1) .reduce((result, value, index) => { result[keys[index].name] = value; return result; }, {}); /** * The return object for the {@link getMatch} function. */ interface GetMatchReturn< Func extends (...args: any) => any, Patt extends Pattern<Func> > { /** * The params extracted from the `path-to-regexp` pattern or the named capture * groups of the regular expresion. */ params: Record<string, string>; /** * The handler/redirection function that was matched. */ func: Patt["func"]; /** * The name of the handler/redirection function that was matched. */ name: string; /** * The pattern of the handler/redirection function that was matched. */ pattern: string; } /** * The `source` object that contains a link and a route. */ interface Source { /** * The full link with `queryString`. */ link?: string; /** * The link without the query and pagination part. */ route?: string; } /** * The regular expression flag. */ const REGULAR_EXPRESSION = "RegExp:"; /** * Match a link with a list of handler/redirection objects. * * @param source - The source to be matched. * @param list - The list of handler/redirection objects. * * @returns An object containing the matched handler/redirection. Defined in * {@link GetMatchReturn}. */ export const getMatch = < Func extends (...args: any) => any, Patt extends Pattern<Func> >( source: Source, list: Patt[] ): GetMatchReturn<Func, Patt> | null => { const result = list .sort(({ priority: p1 }, { priority: p2 }) => p1 - p2) .map(({ name, priority, pattern, func }) => { let url: string; const keys = []; // Otherwise, we need to pick the value based on the pattern if (pattern.startsWith(REGULAR_EXPRESSION)) { url = source.link; } else { url = source.route; } const regexp = pattern.startsWith(REGULAR_EXPRESSION) ? new RegExp(pattern.replace(REGULAR_EXPRESSION, "")) : pathToRegexp(pattern, keys); return { name, priority, pattern, regexp, keys, url, func }; }) .find(({ regexp, url }) => regexp.test(url)); return result ? { func: result.func, params: result.pattern.startsWith(REGULAR_EXPRESSION) ? result.regexp.exec(result.url).groups : extractParameters(result.url, result.regexp, result.keys), name: result.name, pattern: result.pattern, } : null; };