-
Notifications
You must be signed in to change notification settings - Fork 8
/
compileRoute.js
101 lines (83 loc) · 2.58 KB
/
compileRoute.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
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
90
91
92
93
94
95
96
97
98
99
100
101
'use strict'
var URLON = require('urlon')
var pathToRegexp = require('path-to-regexp')
function getKeyName(key) {
return key.name.toString()
}
// loose escaping for segment part
// see: https://github.com/pillarjs/path-to-regexp/pull/75
function encodeSegment(str) {
return encodeURI(str).replace(/[/?#'"]/g, function (c) {
return '%' + c.charCodeAt(0).toString(16).toUpperCase()
})
}
function compileRoute(route, options) {
var re
var compiled
var keys = []
var querySeparator = options.querySeparator || '?'
re = pathToRegexp(route, keys)
keys = keys.map(getKeyName)
compiled = pathToRegexp.compile(route)
return {
parse: function (url) {
var path = url
var result = {}
if (~path.indexOf('#') && !~querySeparator.indexOf('#')) {
path = path.split('#')[0]
}
if (~path.indexOf(querySeparator)) {
if (options.query) {
var queryString = '$' + path.slice(path.indexOf(querySeparator) + querySeparator.length)
result = URLON.parse(queryString)
}
path = path.split(querySeparator)[0]
}
var match = re.exec(path)
if (!match) return null
for (var i = 1; i < match.length; ++i) {
var key = keys[i - 1]
var value = match[i] && decodeURIComponent(match[i])
result[key] = value && value[0] === ':' ? URLON.parse(value) : value
}
return result
},
stringify: function (values) {
var pathParams = {}
var queryParams = {}
Object.keys(values).forEach(function (key) {
if (~keys.indexOf(key)) {
switch (typeof values[key]) {
case 'boolean':
case 'number':
pathParams[key] = URLON.stringify(values[key])
break
case 'object':
if (values[key]) {
throw new Error(
'URL Mapper - objects are not allowed to be stringified as part of path'
)
} else {
// null
pathParams[key] = URLON.stringify(values[key])
}
break
default:
pathParams[key] = values[key]
}
} else {
queryParams[key] = values[key]
}
})
var path = compiled(pathParams, { encode: encodeSegment })
var queryString = ''
if (options.query) {
if (Object.keys(queryParams).length) {
queryString = URLON.stringify(queryParams).slice(1)
}
}
return path + (queryString ? querySeparator + queryString : '')
}
}
}
module.exports = compileRoute