types/version.js

'use strict';

import {Monster} from '../namespace.js';
import {Base} from  './base.js';

/**
 * the version object contains a sematic version number
 *
 * you can create the object via the monster namespace `new Monster.Types.Version()`.
 *
 * ```
 * <script type="module">
 * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.6.0/dist/modules/types/version.js';
 * console.log(new Monster.Types.Version('1.2.3')) // ↦ 1.2.3
 * console.log(new Monster.Types.Version('1')) // ↦ 1.0.0
 * </script>
 * ```
 *
 * Alternatively, you can also integrate this class individually.
 *
 * ```
 * <script type="module">
 * import {Version} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.6.0/dist/modules/types/version.js';
 * console.log(new Version('1.2.3')) // ↦ 1.2.3
 * console.log(new Version('1')) // ↦ 1.0.0
 * </script>
 * ```
 *
 * some examples
 *
 * ```
 * new Monster.Types.Version('1.0.0') // 1.0.0
 * new Monster.Types.Version(1)  // 1.0.0
 * new Monster.Types.Version(1, 0, 0) // 1.0.0
 * new Monster.Types.Version('1.2.3', 4, 5) // 1.4.5
 * ```
 *
 * @since 1.0.0
 * @author schukai GmbH
 * @copyright schukai GmbH
 * @memberOf Monster/Types
 */
class Version extends Base {

    /**
     *
     * @param major
     * @param minor
     * @param patch
     * @throws major is not a number
     * @throws minor is not a number
     * @throws patch is not a number
     */
    constructor(major, minor, patch) {
        super();

        if (typeof major === 'string' && minor === undefined && patch === undefined) {

            let parts = major.toString().split('.');
            major = parseInt(parts[0] || 0);
            minor = parseInt(parts[1] || 0);
            patch = parseInt(parts[2] || 0);
        }

        if (major === undefined) {
            throw  new Error("major version is undefined");
        }

        if (minor === undefined) {
            minor = 0;
        }

        if (patch === undefined) {
            patch = 0;
        }

        this.major = parseInt(major);
        this.minor = parseInt(minor);
        this.patch = parseInt(patch);

        if (isNaN(this.major)) {
            throw  new Error("major is not a number");
        }

        if (isNaN(this.minor)) {
            throw  new Error("minor is not a number");
        }

        if (isNaN(this.patch)) {
            throw  new Error("patch is not a number");
        }

    }

    /**
     *
     * @returns {string}
     */
    toString() {
        return this.major + '.' + this.minor + '.' + this.patch;
    }

    /**
     * returns 0 if equal, -1 if the object version is less and 1 if greater
     * then the compared version
     *
     * @param {string|Version} version Version to compare
     * @returns {number}
     */
    compareTo(version) {

        if (version instanceof Version) {
            version = version.toString();
        }

        if (typeof version !== 'string') {
            throw  new Error("type exception");
        }

        if (version === this.toString()) {
            return 0;
        }

        let a = [this.major, this.minor, this.patch];
        let b = version.split('.');
        let len = Math.max(a.length, b.length);

        for (let i = 0; i < len; i += 1) {
            if ((a[i] && !b[i] && parseInt(a[i]) > 0) || (parseInt(a[i]) > parseInt(b[i]))) {
                return 1;
            } else if ((b[i] && !a[i] && parseInt(b[i]) > 0) || (parseInt(a[i]) < parseInt(b[i]))) {
                return -1;
            }
        }

        return 0;
    };

}

Monster.assignToNamespace('Monster.Types', Version);


let monsterVersion;

/**
 * Version of monster
 *
 * you can call the method via the monster namespace `Monster.getVersion()`.
 *
 * ```
 * <script type="module">
 * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.6.0/dist/modules/types/version.js';
 * console.log(Monster.getVersion())
 * console.log(Monster.getVersion())
 * </script>
 * ```
 *
 * Alternatively, you can also integrate this function individually.
 *
 * ```
 * <script type="module">
 * import {getVersion} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.6.0/dist/modules/types/version.js';
 * console.log(getVersion())
 * console.log(getVersion())
 * </script>
 * ```
 *
 * @returns {Monster.Types.Version}
 * @since 1.0.0
 * @copyright schukai GmbH
 * @author schukai GmbH
 * @memberOf Monster
 */
function getVersion() {
    if (monsterVersion instanceof Version) {
        return monsterVersion;
    }
    /**#@+ dont touch, replaced by make with package.json version */
    monsterVersion = new Version('1.6.0')
    /**#@-*/
    return monsterVersion;

}

Monster.assignToNamespace('Monster', getVersion);
export {Monster, Version, getVersion}