-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
92 lines (83 loc) · 2.21 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
'use strict';
const semver = require('semver');
const assert = require('assert');
/**
* @property {Map} _dict
*/
class SemverMap {
constructor() {
this._dict = new Map();
}
/**
*
* @param {string} key
* @param {*} val
* @throws {*} invalid input
*/
add(key, val) {
const [id, rawver] = this._parseKey(key);
const ver = new semver.SemVer(rawver);
ver._extra = val;
const site = this._dict.get(id);
if (site) {
const last = site.vers[site.vers.length - 1];
assert(ver.compare(last) > 0, 'expect increasing version!');
site.vers.push(ver);
site.cached.clear();
} else {
this._dict.set(id, {
vers: [ver], cached: new Map(),
});
}
}
/**
*
* @param {string} key
* @throws {*} invalid input
*/
get(key) {
const [id, rawRange, flag] = this._parseKeyAsRange(key);
const site = this._dict.get(id);
if (site) {
const trait = rawRange + '@' + flag;
const val = site.cached.get(trait);
if (typeof (val) !== 'undefined') {
return val;
}
const range = new semver.Range(rawRange);
const satisfy = flag === 'max' ?
semver.maxSatisfying : semver.minSatisfying;
const ver = satisfy(site.vers, range);
if (ver) {
site.cached.set(trait, ver._extra);
return ver._extra;
}
}
}
_parseKey(key) {
assert(typeof (key) === 'string', 'invalid key');
const items = key.split('@');
assert(items.length === 2 && items[0].length > 0 && items[1].length > 0, 'invalid key');
return items;
}
_parseKeyAsRange(key) {
assert(typeof (key) === 'string', 'invalid key');
const items = key.split('@');
assert((items.length === 2 || items.length === 3) &&
items[0].length > 0 &&
items[1].length > 0, 'invalid key');
if (items.length === 2) {
items.push('max');
} else if (items.length === 3) {
const s = items[2];
assert(s === 'max' || s === 'min', 'invalid key');
}
return items;
}
}
module.exports = SemverMap;
// const map = new SemverMap();
// map.add('myname@1.4.2-alpha', 1);
// map.add('myname@1.4.2-beta', 2);
// map.add('myname@1.4.4', 3);
// map.get('myname@^1.4.1-alpha');