Last active

Embed URL

HTTPS clone URL

SSH clone URL

You can clone with HTTPS or SSH.

Download Gist

Parse Semver

View README.md

Please use semver-utils instead!

npm install semver-utils

See the README for semver-utils at https://github.com/coolaj86/semver-utils

npm install semver-utils

Obsolete Functions

parse-semver.js parses a single semver such as 2.1.0-6+b. This has been tested quite a bit.

parse-semver-range.js parses ranges such as >= 1.3.1 <= 1.4.6. This needs more testing.

View README.md
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
/*
* WARNING: OBSOLETE
*
* Please use the code at https://github.com/coolaj86/semver-utils, not this gist
* npm install semver-utils
*/
(function () {
"use strict";
console.warn('OBSOLETE: `npm install semver-utils` and see README at https://github.com/coolaj86/semver-utils');
 
var re = /\s*((\|\||\-)|(([<>~]?=?)\s*(v)?([0-9]+)(\.(x|[0-9]+))?(\.(x|[0-9]+))?(([\-+])([a-zA-Z0-9\.]+))?))\s*/g
;
 
function parseRangeFull(str) {
console.warn('OBSOLETE: `npm install semver-utils` and see README at https://github.com/coolaj86/semver-utils');
var m
, arr = []
, obj
;
 
function prune(key) {
if ('undefined' === typeof obj[key]) {
delete obj[key];
}
}
 
while (true) {
m = re.exec(str);
if (!m) {
break;
}
obj = {
semver: m[3]
, operator: m[4] || m[2]
, major: m[6]
, minor: m[8]
, patch: m[10]
};
if ('+' === m[12]) {
obj.build = m[13];
}
if ('-' === m[12]) {
obj.release = m[13];
}
Object.keys(obj).forEach(prune);
arr.push(obj);
//console.log(m);
}
 
return arr;
}
 
function test() {
var str = '~1.0.0 || >= 1.1.7 < 2.0.0+build.1848 || v1.1.3 || 2.0.1-alpha.1227 || 1.0.0 - 1.0.x'
;
console.log(parseRangeFull(str));
console.log(parseRangeFull('v1.0.0'));
console.log(parseRangeFull('< v2.0.0'));
console.log(parseRangeFull('~v2.0.0'));
}
 
test();
}());
View README.md
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 119 120 121 122 123 124 125 126 127 128
/*
* WARNING: OBSOLETE
*
* Please use the code at https://github.com/coolaj86/semver-utils, not this gist
* npm install semver-utils
*/
(function () {
"use strict";
 
console.warn('OBSOLETE: `npm install semver-utils` and see README at https://github.com/coolaj86/semver-utils');
 
var good
, bad
, reSemver = /^((\d+)\.(\d+)\.(\d+))(?:-([\dA-Za-z\-]+(?:\.[\dA-Za-z\-]+)*))?(?:\+([\dA-Za-z\-]+(?:\.[\dA-Za-z\-]+)*))?$/
;
 
good = [
"1.0.8"
, "1.23.7"
, "2.0.0-alpha.123.abc"
, "2.0.0-alpha.123.abc+build.acebfde1284"
, "1.0.0-alpha"
, "1.0.0-alpha.1"
, "1.0.0-0.3.7"
, "1.0.0-x.7.z.92"
, "1.0.0-alpha"
, "1.0.0-alpha.1"
, "1.0.0-beta.2"
, "1.0.0-beta.11"
, "1.0.0-rc.1"
, "1.0.0-rc.1+build.1"
, "1.0.0-rc.1+build.1-b"
, "1.0.0"
, "1.0.0+0.3.7"
, "1.3.7+build"
, "1.3.7+build.2.b8f12d7"
, "1.3.7+build.11.e0f985a"
, "1.3.7+build.11.e0f9-85a"
, "1.0.0+build-acbe"
, "2.0.0+build.acebfde1284-alpha.123.abc"
];
 
bad = [
"v1.0.0"
, "a.b.c"
, "1"
, "1.0.0b"
, "1.0"
, "1.0.0+b[\\]^_`uild" // [,\,],^,_,` are between A-z, but not A-Za-z
, "1.0.0+build-acbe." // trailing period
, "1.0.0+build.!@#$%"
];
 
function parseSemver(version) {
console.warn('OBSOLETE: `npm install semver-utils` and see README at https://github.com/coolaj86/semver-utils');
// semver, major, minor, patch
// https://github.com/mojombo/semver/issues/32
// https://github.com/isaacs/node-semver/issues/10
// optional v
var m = reSemver.exec(version) || []
, ver = {
semver: m[0]
, version: m[1]
, major: m[2]
, minor: m[3]
, patch: m[4]
, release: m[5]
, build: m[6]
}
;
 
if (0 === m.length) {
ver = null;
}
 
return ver;
}
 
good.every(function (version) {
var result = parseSemver(version)
;
 
if (!result) {
throw new Error("didn't parse something that should be parseable: " + version);
}
 
return true;
});
 
bad.every(function (version) {
var result = parseSemver(version)
;
 
if (result) {
throw new Error("parsed something that should not be parseable: " + version);
}
 
return true;
});
 
console.log(parseSemver("a.b.c")); // null
console.log(parseSemver("1.0.3"));
/*
{
semver: 1.0.3
, major: 1
, minor: 0
, patch: 3
}
*/
 
console.log(parseSemver("1.0.3-rc.1+build.aef312"));
/*
{
semver: v1.0.3-rc.1+build.aef312
, major: 1
, minor: 0
, patch: 3
, build: build.aef312
, release: rc.1
}
*/
 
console.log(parseSemver("1.0.0-rc.1-1"));
console.log(parseSemver("1.0.0-rc.1+build.1-b"));
console.log(parseSemver("1.0.0-rc.1-1+build.1-b"));
console.log(parseSemver("2.0.0+build.acebfde1284-alpha.123.abc"));
}());

The use of "A-z" in the regex allows for the six interstitial characters between 'Z' and 'a' to be included in identifiers. (i.e. left-square-bracket, backslash, right-square-bracket, caret, underscore, and backtick). These are not legal identifier characters. Adding these two negative test cases between lines 43 and 44 demonstrates the problem:

, "1.0.0+build_with_underscore" // underscore is illegal
, "1.0.0+build[5]" // square brackets are illegal

Replacing the four instances of "A-z" with "A-Za-z" fixes this issue.

Owner

thanks for the heads up

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.