-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy pathindex.js
118 lines (113 loc) · 3.64 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
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
function routesVersioning() {
return function(args, notFoundMiddleware) {
if (!args || typeof(args) !== 'object' ||
require('util').isArray(args)) {
console.log('Input has to be either an object');
return -1;
}
return function(req, res, next) {
var that = this;
var version = getVersion(req);
var keys = Object.keys(args);
var key;
var tempKey;
var versionArr;
var tempVersion;
if (!version) {
if (notFoundMiddleware) {
notFoundMiddleware.call(that, req, res, next);
} else {
key = findLatestVersion(keys);
args[key].call(that, req, res, next);
}
return;
}
for (var i = 0; i < keys.length; i++) {
key = keys[i];
versionArr = version.split('.');
if (key[0] === '~') {
tempKey = key.substr(1);
tempKey = tempKey.split('.').slice(0, 2).join('.');
versionArr[1] = versionArr[1] || 0;
tempVersion = versionArr.slice(0, 2).join('.');
} else if (key[0] === '^') {
tempKey = key.substr(1);
tempKey = tempKey.split('.').slice(0, 1).join('.');
tempVersion = versionArr.slice(0, 1).join('.');
} else {
tempKey = key;
versionArr[1] = versionArr[1] || 0;
versionArr[2] = versionArr[2] || 0;
tempVersion = versionArr.join('.');
}
if (tempKey === tempVersion) {
args[key].call(that, req, res, next);
return;
}
}
if (notFoundMiddleware) {
notFoundMiddleware.call(that, req, res, next);
} else {
//get the latest version when no version match found
key = findLatestVersion(keys);
args[key].call(that, req, res, next);
}
}
}
}
/**
* Given an array of versions, returns the latest version.
* Follows semver versioning rules.
* Supports version types: 1, 1.0, 0.1, 1.0.0
* Note: 1 is treated as 1.0.0
**/
function findLatestVersion(versions) {
versions.sort(function(v1, v2) {
var v1Arr = v1.split('.');
var v2Arr = v2.split('.');
v1Arr[0] = v1Arr[0].replace('^', '');
v1Arr[0] = v1Arr[0].replace('~', '');
v2Arr[0] = v2Arr[0].replace('^', '');
v2Arr[0] = v2Arr[0].replace('~', '');
for (var i = 0; i < 2; i ++) {
if(!v1Arr[i]) {
v1Arr[i] = 0;
}
if(!v2Arr[i]) {
v2Arr[i] = 0;
}
}
if (isNaN(v2Arr[0]) || v1Arr[0] > v2Arr[0]) {
return 1;
} else if (isNaN(v1Arr[0]) || v1Arr[0] < v2Arr[0]) {
return -1;
} else if (isNaN(v2Arr[1]) || v1Arr[1] > v2Arr[1]){
return 1;
} else if (isNaN(v1Arr[1]) || v1Arr[1] < v2Arr[1]) {
return -1;
} else if (isNaN(v2Arr[2]) || v1Arr[2] > v2Arr[2]) {
return 1;
} else if (isNaN(v1Arr[2]) || v1Arr[2] < v2Arr[2]) {
return -1;
} else {
return 0;
}
});
return versions[versions.length -1];
}
/**
* Gets the version of the application either from accept-version headers
* or req.version property
**/
function getVersion(req) {
var version;
if (!req.version) {
if (req.headers && req.headers['accept-version']) {
version = req.headers['accept-version'];
}
} else {
version = String(req.version);
}
return version;
}
module.exports = routesVersioning;