| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| import {BehaviorSubject} from 'rxjs'; |
| import _ from 'lodash'; |
| |
| /** |
| * Utility service for version parsing and comparing |
| */ |
| const VERSION_MATCHER = /(\d+)\.(\d+)\.(\d+)([-.]([^0123456789][^-]+)(-SNAPSHOT)?)?(-(\d+))?(-([\da-f]+))?/i; |
| |
| const numberComparator = (a, b) => a > b ? 1 : a < b ? -1 : 0; |
| |
| export default class IgniteVersion { |
| constructor() { |
| this.webConsole = '2.8.0'; |
| |
| this.supportedVersions = [ |
| { |
| label: 'Ignite 2.8', |
| ignite: '2.8.0' |
| }, |
| { |
| label: 'Ignite 2.7', |
| ignite: '2.7.0' |
| }, |
| { |
| label: 'Ignite 2.6', |
| ignite: '2.6.0' |
| }, |
| { |
| label: 'Ignite 2.5', |
| ignite: '2.5.0' |
| }, |
| { |
| label: 'Ignite 2.4', |
| ignite: '2.4.0' |
| }, |
| { |
| label: 'Ignite 2.3', |
| ignite: '2.3.0' |
| }, |
| { |
| label: 'Ignite 2.1', |
| ignite: '2.2.0' |
| }, |
| { |
| label: 'Ignite 2.0', |
| ignite: '2.0.0' |
| }, |
| { |
| label: 'Ignite 1.x', |
| ignite: '1.9.0' |
| } |
| ]; |
| |
| /** Current product version. */ |
| let current = _.head(this.supportedVersions); |
| |
| try { |
| const ignite = localStorage.configurationVersion; |
| |
| const restored = _.find(this.supportedVersions, {ignite}); |
| |
| if (restored) |
| current = restored; |
| } |
| catch (ignored) { |
| // No-op. |
| } |
| |
| this.currentSbj = new BehaviorSubject(current); |
| |
| this.currentSbj.subscribe({ |
| next: (ver) => { |
| try { |
| localStorage.setItem('configurationVersion', ver.ignite); |
| } |
| catch (ignored) { |
| // No-op. |
| } |
| } |
| }); |
| } |
| |
| /** |
| * @return {String} Current Ignite version. |
| */ |
| get current() { |
| return this.currentSbj.getValue().ignite; |
| } |
| |
| /** |
| * Check if version in range. |
| * |
| * @param {String} target Target version. |
| * @param {String | Array.<String>} ranges Version ranges to compare with. |
| * @returns {Boolean} `True` if version is equal or greater than specified range. |
| */ |
| since(target, ...ranges) { |
| const targetVer = this.parse(target); |
| |
| return !!_.find(ranges, (range) => { |
| if (_.isArray(range)) { |
| const [after, before] = range; |
| |
| return this.compare(targetVer, this.parse(after)) >= 0 && |
| (_.isNil(before) || this.compare(targetVer, this.parse(before)) < 0); |
| } |
| |
| return this.compare(targetVer, this.parse(range)) >= 0; |
| }); |
| } |
| |
| /** |
| * Check whether version before than specified version. |
| * |
| * @param {String} target Target version. |
| * @param {String} ranges Version ranges to compare with. |
| * @return {Boolean} `True` if version before than specified version. |
| */ |
| before(target, ...ranges) { |
| return !this.since(target, ...ranges); |
| } |
| |
| /** |
| * Check if current version in specified range. |
| * |
| * @param {String|Array.<String>} ranges Version ranges to compare with. |
| * @returns {Boolean} `True` if configuration version is equal or greater than specified range. |
| */ |
| available(...ranges) { |
| return this.since(this.current, ...ranges); |
| } |
| |
| /** |
| * Tries to parse product version from it's string representation. |
| * |
| * @param {String} ver - String representation of version. |
| * @returns {{major: Number, minor: Number, maintenance: Number, stage: String, revTs: Number, revHash: String}} - Object that contains product version fields. |
| */ |
| parse(ver) { |
| // Development or built from source ZIP. |
| ver = ver.replace(/(-DEV|-n\/a)$/i, ''); |
| |
| const [, major, minor, maintenance, stage, ...chunks] = ver.match(VERSION_MATCHER); |
| |
| return { |
| major: parseInt(major, 10), |
| minor: parseInt(minor, 10), |
| maintenance: parseInt(maintenance, 10), |
| stage: (stage || '').substring(1), |
| revTs: chunks[2] ? parseInt(chunks[3], 10) : 0, |
| revHash: chunks[4] ? chunks[5] : null |
| }; |
| } |
| |
| /** |
| * Compare to version. |
| * |
| * @param {Object} a first compared version. |
| * @param {Object} b second compared version. |
| * @returns {Number} 1 if a > b, 0 if versions equals, -1 if a < b |
| */ |
| compare(a, b) { |
| let res = numberComparator(a.major, b.major); |
| |
| if (res !== 0) |
| return res; |
| |
| res = numberComparator(a.minor, b.minor); |
| |
| if (res !== 0) |
| return res; |
| |
| res = numberComparator(a.maintenance, b.maintenance); |
| |
| if (res !== 0) |
| return res; |
| |
| return numberComparator(a.stage, b.stage); |
| } |
| |
| } |