-
-
Notifications
You must be signed in to change notification settings - Fork 636
Expand file tree
/
Copy pathmatchPath.ts
More file actions
89 lines (73 loc) · 2 KB
/
matchPath.ts
File metadata and controls
89 lines (73 loc) · 2 KB
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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import { pathToRegexp, Keys } from 'path-to-regexp';
import { type Match } from './Route';
const patternCache = {};
const cacheLimit = 10000;
let cacheCount = 0;
const compilePath = (pattern, options): { re: any; keys: Keys } => {
const cacheKey = `${options.end}${options.strict}${options.sensitive}`;
const cache = patternCache[cacheKey] || (patternCache[cacheKey] = {});
if (cache[pattern]) {
return cache[pattern];
}
options.trailing = options.end && !options.strict;
pattern = pattern.replace(/\?/, '{.:optqspunct}');
if (!options.exact && !options.strict) {
pattern = pattern.replace(/\/$/, '{.:optendslash}');
}
const { regexp: re, keys } = pathToRegexp(pattern, options)
const compiledPattern = { re, keys };
if (cacheCount < cacheLimit) {
cache[pattern] = compiledPattern;
cacheCount++;
}
return compiledPattern;
};
/**
* Public API for matching a URL pathname to a path pattern.
*/
export function matchPath(pathname, options: any): Match<any> | null {
if (typeof options === 'string') {
options = { path: options };
}
const {
path = '/',
exact = false,
strict = false,
sensitive = false,
loader,
initialData = {},
} = options;
const loaderData = initialData[path];
if (path === '*' || path === '/*') {
return {
isExact: false,
loader,
loaderData,
params: [],
path,
url: '/'
};
}
const { re, keys } = compilePath(path, { end: exact, strict, sensitive });
const match = re.exec(pathname);
if (!match) {
return null;
}
const [url, ...values] = match;
const isExact = pathname === url;
if (exact && !isExact) {
return null;
}
return {
isExact,
loader,
loaderData,
params: keys.reduce((memo, key, index) => {
if (values[index] !== undefined)
memo[key.name] = values[index];
return memo;
}, {}),
path, // the path pattern used to match
url: path === '/' && url === '' ? '/' : url, // the matched portion of the URL
};
}