Search code examples
javascriptnode.jsversioning

Parsing a version number string to an associating value


I'm attempting to parse a version string (examples below) in order to return a value depending on a key that matches the following rules listed below.

Each version ID can include a wildcard, however the input cannot. Ofcourse this object is dynamic and will most likely include more version matches.

In this example, the version string will be "1.2.3".

  • Version IDs higher than 3.2.1 will return "null"
  • Version IDs between 3.2.1 and 2.8.10 will return "testing_server"
  • Version ID of 2.8.10 will return "second_value"
  • Version IDs between 2.8.10 and 1.0.* will return "last value"
  • Version IDs matching 1.0.* or less (including 0.*) will return "last value"

Example object:

{
   "3.2.1": "testing_server",
   "2.8.10": "second_value",
   "1.0.*": "last value"
}

I have tried several functions each including regex, or manual comparisons but haven't achieved much luck. I know its a bit of a tough one, but hopefully someone can help. :)


Solution

  • I ended up using "compare-versions" along with some logic to get it going.

    const compareVersions = require('compare-versions');
    
    function getVersion(version) {
        const versions = {
            "3.2.1": "testing_server",
            "2.8.10": "second_value",
            "1.0.*": "last value"
        }
        const sortedKeys = Object.keys(versions).sort(compareVersions);
    
        // not required
        //if (compareVersions(version, sortedKeys[sortedKeys.length - 1]) > 0) return null;
    
        let i = 0;
        while (i < sortedKeys.length && compareVersions(version, sortedKeys[i]) > 0) i++;
        return versions[sortedKeys[i]] || null;
    }
    
    const examples = [
        "3.2.2",
        "3.2.1",
        "2.8.11",
        "2.8.10",
        "1.1.0",
        "1.0",
        "0.0"
    ];
    
    const answers = {};
    for (const example of examples) {
        answers[example] = getVersion(example);
    }
    console.log(answers);