-
Notifications
You must be signed in to change notification settings - Fork 4
/
index.js
73 lines (61 loc) · 1.94 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
'use strict';
const semver = require('semver');
function KoaRouterVersion() {
this.options = {
requestHeader: 'Accept-Version',
responseHeader: 'X-Api-Version',
routeParam: 'version',
fallbackLatest: false,
defaultVersion: null
};
}
function find(requested, tuples, fallbackLatest = false) {
if (requested === null || requested === '*') {
return tuples[0];
}
for (let i=0; i<tuples.length; i++) {
if (semver.satisfies(tuples[i].version, requested)) {
return tuples[i];
}
}
if (fallbackLatest) {
return tuples[0];
}
return null;
}
KoaRouterVersion.prototype.version = function(versions, options = {}) {
let tuples = [];
if (options.fallbackLatest && options.defaultVersion) {
throw new Error('Can not set options "fallbackLatest" and "defaultVersion" at same time');
}
for (let key in versions) tuples.push({version: key, cb: versions[key]});
tuples.sort(function(a, b) {
a = a.version;
b = b.version;
return semver.lt(a, b) ? 1 : -1;
});
return (ctx, next) => {
let requested = null;
const routeParam = options.routeParam || this.options.routeParam;
if (
routeParam !== '' &&
ctx.params.hasOwnProperty(routeParam) &&
typeof ctx.params[routeParam] === 'string'
) {
requested = ctx.params[routeParam].substr(1);
} else {
requested = ctx.get(options.requestHeader || this.options.requestHeader) || null;
}
if (!requested && options.defaultVersion) {
requested = options.defaultVersion;
}
let found = find(requested, tuples, options.fallbackLatest || this.options.fallbackLatest);
if (found) {
ctx.state.apiVersion = found.version;
ctx.set(options.responseHeader || this.options.responseHeader, ctx.state.apiVersion);
return found.cb(ctx, next);
}
ctx.throw(400, 'Version ' + requested + ' is not supported');
};
};
let koaRouterVersion = module.exports = exports = new KoaRouterVersion;