-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
50 lines (39 loc) · 1.09 KB
/
index.js
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
import UrlPattern from 'url-pattern';
import queryString from 'query-string';
// handles cases where the url has an optional token e.g. /foo/:bar?/:baz
// url-pattern requires: /foo(/:bar)/:baz
const rOptionalToken = /(\/:[^?/]+\?)/g;
const normalizeUrl = function(url) {
return url.replace(rOptionalToken, match => (
`(${match.substr(0, match.length - 1)})`
));
};
export default function Location(url) {
const pattern = new UrlPattern(normalizeUrl(url));
let qs = '';
const location = function(config = {}) {
const base = pattern.stringify(config);
return `${base}${qs ? '?' : ''}${qs}`;
};
const api = Object.assign(location, {
get() {
return url;
},
match(path) {
return pattern.match(path);
},
query(config) {
qs = queryString.stringify(config);
return api;
},
});
return api;
};
export const locations = function(config) {
if (!config) throw new Error('locations: missing config');
if (Array.isArray(config)) return config.map(Location);
return Object.entries(config).reduce((memo, [key, value]) => {
memo[key] = Location(value);
return memo;
}, {});
};