UNPKG

1.64 kBJavaScriptView Raw
1import pathToRegexp from "path-to-regexp";
2
3const cache = {};
4const cacheLimit = 10000;
5let cacheCount = 0;
6
7function compilePath(path, options) {
8 const cacheKey = `${options.end}${options.strict}${options.sensitive}`;
9 const pathCache = cache[cacheKey] || (cache[cacheKey] = {});
10
11 if (pathCache[path]) return pathCache[path];
12
13 const keys = [];
14 const regexp = pathToRegexp(path, keys, options);
15 const result = { regexp, keys };
16
17 if (cacheCount < cacheLimit) {
18 pathCache[path] = result;
19 cacheCount++;
20 }
21
22 return result;
23}
24
25/**
26 * Public API for matching a URL pathname to a path.
27 */
28function matchPath(pathname, options = {}) {
29 if (typeof options === "string" || Array.isArray(options)) {
30 options = { path: options };
31 }
32
33 const { path, exact = false, strict = false, sensitive = false } = options;
34
35 const paths = [].concat(path);
36
37 return paths.reduce((matched, path) => {
38 if (!path && path !== "") return null;
39 if (matched) return matched;
40
41 const { regexp, keys } = compilePath(path, {
42 end: exact,
43 strict,
44 sensitive
45 });
46 const match = regexp.exec(pathname);
47
48 if (!match) return null;
49
50 const [url, ...values] = match;
51 const isExact = pathname === url;
52
53 if (exact && !isExact) return null;
54
55 return {
56 path, // the path used to match
57 url: path === "/" && url === "" ? "/" : url, // the matched portion of the URL
58 isExact, // whether or not we matched exactly
59 params: keys.reduce((memo, key, index) => {
60 memo[key.name] = values[index];
61 return memo;
62 }, {})
63 };
64 }, null);
65}
66
67export default matchPath;