-
Notifications
You must be signed in to change notification settings - Fork 151
Expand file tree
/
Copy pathutil.js
More file actions
80 lines (71 loc) · 1.92 KB
/
util.js
File metadata and controls
80 lines (71 loc) · 1.92 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
const EMPTY = {};
export function exec(url, route, opts=EMPTY) {
let reg = /^([^?]*)(?:\?([^#]*))?(#.*)?$/,
[, pathname, search] = (url.match(reg) || []),
matches = {},
ret;
url = segmentize(pathname);
route = segmentize(route || '');
let max = Math.max(url.length, route.length);
for (let i=0; i<max; i++) {
if (route[i] && route[i].charAt(0)===':') {
let [, param, flags] = /^:(.*?)([+*?]*)$/.exec(route[i]),
plus = ~flags.indexOf('+'),
star = ~flags.indexOf('*'),
val = url[i] || '';
if (!val && !star && (flags.indexOf('?')<0 || plus)) {
ret = false;
break;
}
else if (plus || star) {
matches[param] = decodeURIComponent(url.slice(i).join('/'));
break;
}
matches[param] = decodeURIComponent(val);
}
else if (route[i]!==url[i]) {
ret = false;
break;
}
}
if (opts.default!==true && ret===false) return false;
if (search) {
const queryParams = {};
search.split('&').forEach(parameter => {
let [name, ...value] = parameter.split('=');
queryParams[decodeURIComponent(name)] = decodeURIComponent(value.join('='));
});
matches = {
...queryParams,
...matches
};
}
return matches;
}
export function pathRankSort(a, b) {
let aAttr = a.attributes || EMPTY,
bAttr = b.attributes || EMPTY;
if (aAttr.default) return 1;
if (bAttr.default) return -1;
let aRank = rank(aAttr.path),
bRank = rank(bAttr.path);
return (aRank < bRank) ? 1 :
(aRank == bRank) ? 0 :
-1;
}
export function segmentize(url) {
return strip(url).split('/');
}
export const rankSegment = (segment) => {
let [, isParam, , flag] = /^(:?)(.*?)([*+?]?)$/.exec(segment);
return isParam ? ('0*+?'.indexOf(flag) || 4) : 5;
};
export const rank = (path) => (
segmentize(path).map(rankSegment).join('')
);
export function rankChild({ attributes=EMPTY }) {
return attributes.default ? '0' : rank(attributes.path);
}
export function strip(url) {
return url.replace(/(^\/+|\/+$)/g, '');
}