Giter VIP home page Giter VIP logo

compare-versions's Introduction

compare-versions

Build Status Coverage Status npm bundle size (minified + gzip)

Compare semver version strings to find greater, equal or lesser. Runs in the browser as well as Node.js/React Native etc. Has no dependencies and is tiny.

Supports the full semver specification including versions with different number of digits like 1.0.0, 1.0, 1 and pre-releases like 1.0.0-alpha. Additionally supports the following variations:

  • Wildcards for minor and patch version like 1.0.x or 1.0.*.
  • Chromium version numbers with 4 parts, e.g. version 25.0.1364.126.
  • Any leading v is ignored, e.g. v1.0 is interpreted as 1.0.
  • Leading zero is ignored, e.g. 1.01.1 is interpreted as 1.1.1.
  • npm version ranges, e.g. 1.2.7 || >=1.2.9 <2.0.0

Install

$ npm install compare-versions

Note: Starting from v5 the main export is now named like so: import { compareVersions } from 'compare-versions'.

Note: Starting from v4 this library includes a ESM version which will automatically be selected by your bundler (webpack, parcel etc). The CJS/UMD version is lib/umd/index.js and the new ESM version is lib/esm/index.js.

Usage

Will return 1 if first version is greater, 0 if versions are equal, and -1 if the second version is greater:

import { compareVersions } from 'compare-versions';

compareVersions('11.1.1', '10.0.0'); //  1
compareVersions('10.0.0', '10.0.0'); //  0
compareVersions('10.0.0', '11.1.1'); // -1

Can also be used for sorting:

const versions = [
  '1.5.19',
  '1.2.3',
  '1.5.5'
]
const sorted = versions.sort(compareVersions);
/*
[
  '1.2.3',
  '1.5.5',
  '1.5.19'
]
*/

"Human Readable" Compare

The alternative compare function accepts an operator which will be more familiar to humans:

import { compare } from 'compare-versions';

compare('10.1.8', '10.0.4', '>');  // true
compare('10.0.1', '10.0.1', '=');  // true
compare('10.1.1', '10.2.2', '<');  // true
compare('10.1.1', '10.2.2', '<='); // true
compare('10.1.1', '10.2.2', '>='); // false

Version ranges

The satisfies function accepts a range to compare, compatible with npm package versioning:

import { satisfies } from 'compare-versions';

satisfies('10.0.1', '~10.0.0');  // true
satisfies('10.1.0', '~10.0.0');  // false
satisfies('10.1.2', '^10.0.0');  // true
satisfies('11.0.0', '^10.0.0');  // false
satisfies('10.1.8', '>10.0.4');  // true
satisfies('10.0.1', '=10.0.1');  // true
satisfies('10.1.1', '<10.2.2');  // true
satisfies('10.1.1', '<=10.2.2'); // true
satisfies('10.1.1', '>=10.2.2'); // false
satisfies('1.4.6', '1.2.7 || >=1.2.9 <2.0.0'); // true
satisfies('1.2.8', '1.2.7 || >=1.2.9 <2.0.0'); // false
satisfies('1.5.1', '1.2.3 - 2.3.4'); // true
satisfies('2.3.5', '1.2.3 - 2.3.4'); // false

Validate version numbers

Applies the same rules used comparing version numbers and returns a boolean:

import { validate } from 'compare-versions';

validate('1.0.0-rc.1'); // true
validate('1.0-rc.1');   // false
validate('foo');        // false

Validate version numbers (strict)

Validate version numbers strictly according to semver.org; 3 integers, no wildcards, no leading zero or "v" etc:

import { validateStrict } from 'compare-versions';

validate('1.0.0');      // true
validate('1.0.0-rc.1'); // true
validate('1.0');        // false
validate('1.x');        // false
validate('v1.02');      // false

Browser

If included directly in the browser, the functions above are available on the global window under the compareVersions object:

<script src=https://unpkg.com/compare-versions/lib/umd/index.js></script>
<script>
  const { compareVersions, compare, satisfies, validate } = window.compareVersions
  console.log(compareVersions('11.0.0', '10.0.0'))
  console.log(compare('11.0.0', '10.0.0', '>'))
  console.log(satisfies('1.2.0', '^1.0.0'))
  console.log(validate('11.0.0'))
  console.log(validateStrict('11.0.0'))
</script>

compare-versions's People

Contributors

batmat avatar brianhung avatar cudr avatar dineshks1 avatar eppsilon avatar greenkeeper[bot] avatar greenkeeperio-bot avatar lucasicarus avatar m-mohr avatar niktekusho avatar notherdev avatar omer avatar omichelsen avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

compare-versions's Issues

Difference between API exported via CommonJS and ESM

In version 4.0.0 the ES6 module version of script was added (there is a new file index.mjs). However, it exports different API then exported by index.js. A good practice is to export the same APIs both for ESM and CJS. Otherwise, it can cause problems.

Example:

  • Webpack prefers the code from .mjs
  • Jest prefers the code from .js
  • compareVersions.validate is a function in .js, and is undefined in .mjs
  • Code works correctly in Jest, but fails in the browser

The exported APIs should be the same.

`"latest"` support

Hello! Love this module!

Any considerations around "latest" support?

In Example:

{
  "lodash": "lastest"
}

Thank you!

[feature request (`satisfies`)]: support ranges with `||`

Hi, thanks for this library!

I was wondering if it'd be possible to add support for ranges that contain multiple ranges using || -- ie, something like:

^12.22.0 || ^14.17.0 || >=16.0.0

I'm currently using a workaround where I split the string and test if any of them pass satisfies:

const rangeArray = dep.version.split('||').map((range) => range.trim());
const doesSatisfy = rangeArray.some((range) => satisfies(version, range));

but I think it would be nice if it was supported out of the box. I'd be happy to open a PR if you are into this idea! Thanks again!

Much smaller alternative version

Just wanted to share this:

Was looking for an alternative dependency free solution
came up with this:

let version = [...process.version.match(/v(\d+)\.(\d+)\.(\d+)/)] // [ 'v16.4.2', '16', '4', '2' ]
version[0] = 0
version = new Uint32Array(new Uint8Array(version).buffer)[0]

if (version < 34541056) {
  // node version is lower than 14.15.2
}

Regex not matching Chrome version

Current regex not matching Chrome version (65.0.3325.181) as result method validate throw Error "Invalid argument not valid semver"

Validate allows wildcards

Hello,

first of all, thanks for this library.

I'm not sure if it is a bug or intended behavior, but validate also returns true if the given version contains a wildcard (x, *). I'm aware that this lib is already lenient and not strictly adhering to semver, which is fine. However the docs for validate don't mention that wildcards are allowed in versions.

import { validate } from 'compare-versions';

describe('versions-compare:validate', () => {
  it.each([
    '1.0',
    '1.0.0',
    '1.0.1',
    '1.1.0',
    '1.0.0-rc1',
    '1.0.0-rc.1',
    '1.0.0-rc.1.2',
    '1.0.0-rc.1.2+1',
    '1.0.0-rc.1.2+1.2',
  ])('valid version: %s', (validVersion) => {
    expect(validate(validVersion)).toEqual(true);
  });

  it.each(['x.0.1', '1.x', '1.*', '1.0.x', '1.0.*'])('invalid version: %s', (invalidVersion) => {
    expect(validate(invalidVersion)).toEqual(false);
  });
});

I would expect each case of 'invalid version' to fail.

If the current behavior is intended, would it be possible to introduce a new validate function for strict semver or is this out of the scope of this library?

Comparison with prior art

Wondering what the rationale was for creating this library, when @substack's semver-compare already existed. A comparison helping users pick between the two would be nice. Thanks!

Uncaught ReferenceError

Uncaught ReferenceError: require is not defined

Attempting to set 'var compareVersions = require('compare-versions');' in my main js file.

What steps do I need to take to get 'require' defined?

Error on certain hyphenated range '-'

Here is the error log message:
image

    at validateAndParse (index.js:131:15)
    at compareVersions (index.js:11:16)
    at compare (index.js:64:17)
    at satisfies (index.js:97:16)
    at index.js:90:27
    at Array.every (<anonymous>)
    at satisfies (index.js:90:14)
    at getVulnerabilityPaint (graph.js:251:7)
    at nodePaint (graph.js:271:19)
    at Object.nodeCanvasObject (graph.js:284:36)
validateAndParse @ index.js:131
compareVersions @ index.js:11
compare @ index.js:64
satisfies @ index.js:97
(anonymous) @ index.js:90
satisfies @ index.js:90
getVulnerabilityPaint @ graph.js:251
nodePaint @ graph.js:271
(anonymous) @ graph.js:284
(anonymous) @ force-graph.min.js:5
(anonymous) @ force-graph.min.js:5
tickFrame @ force-graph.min.js:5
Object.keys.forEach.i.<computed> @ force-graph.min.js:2
t @ force-graph.min.js:5
requestAnimationFrame (async)
t @ force-graph.min.js:5
init @ force-graph.min.js:5
o @ force-graph.min.js:2
i @ force-graph.min.js:2
drawVulnerabilityTree @ graph.js:280
(anonymous) @ graph.js:24
postMessage (async)
(anonymous) @ index.html?id=c3e4c0d0-f2d7-461a-aaf6-9ae5549d360d&origin=69c50012-63f2-42a6-88bd-170dcb44a4ed&swVersion=4&extensionId=ArtT14.npm-dependancy-graph&platform=electron&vscode-resource-base-authority=vscode-resource.vscode-cdn.net&parentOrigin=vscode-file%3A%2F%2Fvscode-app:1039
onLoad @ index.html?id=c3e4c0d0-f2d7-461a-aaf6-9ae5549d360d&origin=69c50012-63f2-42a6-88bd-170dcb44a4ed&swVersion=4&extensionId=ArtT14.npm-dependancy-graph&platform=electron&vscode-resource-base-authority=vscode-resource.vscode-cdn.net&parentOrigin=vscode-file%3A%2F%2Fvscode-app:1038
(anonymous) @ index.html?id=c3e4c0d0-f2d7-461a-aaf6-9ae5549d360d&origin=69c50012-63f2-42a6-88bd-170dcb44a4ed&swVersion=4&extensionId=ArtT14.npm-dependancy-graph&platform=electron&vscode-resource-base-authority=vscode-resource.vscode-cdn.net&parentOrigin=vscode-file%3A%2F%2Fvscode-app:1065
load (async)
hookupOnLoadHandlers @ index.html?id=c3e4c0d0-f2d7-461a-aaf6-9ae5549d360d&origin=69c50012-63f2-42a6-88bd-170dcb44a4ed&swVersion=4&extensionId=ArtT14.npm-dependancy-graph&platform=electron&vscode-resource-base-authority=vscode-resource.vscode-cdn.net&parentOrigin=vscode-file%3A%2F%2Fvscode-app:1059
(anonymous) @ index.html?id=c3e4c0d0-f2d7-461a-aaf6-9ae5549d360d&origin=69c50012-63f2-42a6-88bd-170dcb44a4ed&swVersion=4&extensionId=ArtT14.npm-dependancy-graph&platform=electron&vscode-resource-base-authority=vscode-resource.vscode-cdn.net&parentOrigin=vscode-file%3A%2F%2Fvscode-app:975
setTimeout (async)
onFrameLoaded @ index.html?id=c3e4c0d0-f2d7-461a-aaf6-9ae5549d360d&origin=69c50012-63f2-42a6-88bd-170dcb44a4ed&swVersion=4&extensionId=ArtT14.npm-dependancy-graph&platform=electron&vscode-resource-base-authority=vscode-resource.vscode-cdn.net&parentOrigin=vscode-file%3A%2F%2Fvscode-app:971
(anonymous) @ index.html?id=c3e4c0d0-f2d7-461a-aaf6-9ae5549d360d&origin=69c50012-63f2-42a6-88bd-170dcb44a4ed&swVersion=4&extensionId=ArtT14.npm-dependancy-graph&platform=electron&vscode-resource-base-authority=vscode-resource.vscode-cdn.net&parentOrigin=vscode-file%3A%2F%2Fvscode-app:1002

I logged inputs to see what input caused error, Looks like the error happened on the following call:
satisfies("2.0.0", "2.0.0 - 2.0.3")

I am using compare-versions to parse data yielded by npm audit --json.

Is this is an error on my end or is it an edge case that the library misses?

I thought maybe an error on my end so I wrote the following simple doc+script and I get the same error:

<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
	<script src=https://unpkg.com/compare-versions/lib/umd/index.js></script>
	<script>
	  const { compareVersions, compare, satisfies, validate } = window.compareVersions
	  console.log(satisfies('2.0.0', '2.0.0 - 2.0.3'))
	</script>
</head>

<body>
	<p id="test"></p>
</body>

</html>

image

P.S. If you would like I can debug, search, and submit a PR for a fix

esm index.js does not work in the browser

Hi

When I import index.js as esm module in the browser then the re-exported modules are not found because the extension (.js) is missing.

This should be fixed if you add the extension in the source (index.ts), e.g. export { compare } from './compare.js';

Source maps are broken on v5

This is obvious when using source-map-loader:

Failed to parse source map from '<projectPath>/node_modules/compare-versions/src/index.ts' file: Error: ENOENT: no such file or directory, open '<projectPath>/node_modules/compare-versions/src/index.ts'.

Source src/index.ts is referenced in esm/index.js.map:

image

I would love to help but I'm tight on time at the moment. Hopefully, this will at least help you catch this sooner.

Thanks!

Make interface human readable

Currently this kind of code is not human readable without the comment. We must make the interface self-explanatory.

compareVersions('10.1.8', '10.0.4'); //  1
compareVersions('10.0.1', '10.0.1'); //  0
compareVersions('10.1.1', '10.2.2'); // -1

Consider something like:

compareVersions.compare('10.1.8', '10.0.4', '>'); // return true
compareVersions.compare('10.0.1', '10.0.1', '='); // return true
compareVersions.compare('10.1.1', '10.2.2', '<'); // return true
compareVersions.compare('10.1.1', '10.2.2', '<='); // return true
compareVersions.compare('10.1.1', '10.2.2', '>='); // return false

compareVersions('~12.1.2', '11.1.2') => 0 ?

Hi,

this test fails:

it('should return 1 for versions ~12.1.2 and 11.1.2', () => { const result: VersionsComparison = compareVersions('~12.1.2', '11.1.2'); expect(result).toBe(1); });

with error:

Expected 0 to be 1.

Is this behaving expected?

`satisfies()` using `1.*`-style wildcard evaluates to `false` for all non `0` patch versions

Hi, thanks for your work on this package! ๐Ÿ™‚

While troubleshooting, I came across some unexpected results. It looks like using a non-zero patch version will always evaluate to false if there's a wildcard for the minor version but not the patch version.

Some examples here to illustrate:

> const { satisfies } = require('compare-versions');
undefined
> satisfies('1.0.0', '1.*');
true
> satisfies('1.0.1', '1.*');
false
> satisfies('1.1.0', '1.*');
true
> satisfies('1.1.1', '1.*');
false

Additional info:

false compare

payloads:

1.12.11-v20211011
1.12.11-v20211011-beta

Error when running:

compareVersions('10.1.1.v29012', '10.2.2.v29121'); // -1
Uncaught Error: Invalid argument not valid semver ('10.1.1.v29012' received)
    at validate (/Users/xsser/node_modules/compare-versions/index.js:36:13)
    at Array.forEach (<anonymous>)
    at compareVersions (/Users/xsser/node_modules/compare-versions/index.js:41:14)

Unexpected comparison result

hi.
we try use: compareVersions('5.0.0', '5.0.0-1'). but it return 1. why? Logically it is new build of v.5. it must be -1.
Best Regard, Eugene

Support metadata comparison

It would be nice to have an option to support metadata comparison, as a pure string.

For version like 1.2.3+444.3

Thanks.

satisfies return false if minor version is lower

I'm checking if 2.0.0 satisfies >=1.10 and I'm getting false:

        console.log(compare("2.0.0", "1.1.0", '>=')); // true
        console.log(satisfies("2.0.0", ">=1.1.0")); // false

In my exemple you go directly though compare whenre calling statsifies function since operator is >=:

I tried

      console.log(`s1 ${s1[i]} and s2 ${s2[i]}`)
      console.log(`n1 ${n1} and n2 ${n2}`)

In function compareVersions(v1, v2)

here is the output:


 LOG  s1 1 and s2 >=0
 LOG  n1 1 and n2 NaN
 LOG  s1 0 and s2 1
 LOG  n1 0 and n2 1

therefore I think remove the operator after the match in the satisfies should and does fix the issue.

Misplaced commas in the example usage in README

Example usage in readme for usage in sorting is as below:

var versions = [
    '1.5.19'
    '1.2.3',
    '1.5.5',
];
console.log(versions.sort(compareVersions));

The commas are misplaced and actually running this example would throw a syntax error.

Should probably look like this:

var versions = [
    '1.5.19',
    '1.2.3',
    '1.5.5'
];
console.log(versions.sort(compareVersions));

Wrong result by comparing versions with leading zero for patch.

Hello!

First of all thanks for such a great library!

I've revealed the problem with comparing versions with leading zero for the patch. Example:

compare('2.0.0123123', '2.0.13', '<=')

Expected: true
Actual: false

As I understood the patches are compared with the following logic.

compare('2.0.0123123', '2.0.13', '<=') 

// first operand patch: "123123"
// second operand patch: "13"

Number("0123123") <= Number("13")  // false

Is it considered as expected behavior? Is there any possibility to compare strings instead?

Thanks

Subversions is only limited to 4

I have a version that is 9.2.0.4.0 and it fails as the the semver can only take upto 4 subversions.

//copied the below from compare-versions/index.js
var semver = /^v?(?:\d+)(.(?:[x*]|\d+)(.(?:[x*]|\d+)(.(?:[x*]|\d+))?(?:-[\da-z-]+(?:.[\da-z-]+))?(?:+[\da-z-]+(?:.[\da-z-]+))?)?)?$/i;

Can this be dynamic allowing any number of sub versions?

Versionnumbers with leading zeros

Versions like "1.09.0" raises an Error
Error: Invalid argument not valid semver

This is the correct behavior looking at the spec, but it would be nice if there was an option to still parse something like this.

Expose validate function?

Thanks for this useful library. Is there any chance to get the validate function exposed, too? I'd like to use it and at the moment I need to copy the code as it is not exported. Something like compareVersions.validate() maybe?

I would be willing to do a PR if it has a chance to get merged and released soon.

angular.js version error

angular.js 1.0.0rc12 version Invalid argument not valid semver Error.

var semver = /^v?(?:0|[1-9]\d_)(.(?:[x_]|0|[1-9]\d_)(.(?:[x_]|0|[1-9]\d_)(?:-[\da-z-]+(?:.[\da-z-]+))?(?:+[\da-z-]+(?:.[\da-z-]+))?)?)?$/i;
//var semver = /^v?(?:0|[1-9]\d
)(.(?:[x_]|0|[1-9]\d_)(.(?:[x_]|0|[1-9]\d_)(?:-[\da-z-]+(?:.[\da-z-]+))?(?:+[\da-z-]+(?:.[\da-z-]+))?)?)?$/i;
var patch = /-_([0-9A-Za-z-.]+)/;
//var patch = /-([0-9A-Za-z-.]+)/;

'-' should be optional .

Caret ranges don't handle 0.x versions properly

Caret ranges (^) are defined as the following in the npm semver documentation`.

Allows changes that do not modify the left-most non-zero digit in the [major, minor, patch] tuple. In other words, this allows patch and minor updates for versions 1.0.0 and above, patch updates for versions 0.X >=0.1.0, and no updates for versions 0.0.X.

compare-versions does not follow this behavior and treat all 0.x.x versions as compatible. Here is a simple example to reproduce the issue:

import { satisfies } from 'compare-versions';

console.log(satisfies("1.2.3", "^1.1.2")); // true - ok
console.log(satisfies("0.3.4", "^0.2.3")); // true - should be false 
console.log(satisfies("0.0.4", "^0.0.3")); // true - should be false

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.