import semver from 'semver';
import isNil from 'lodash/isNil';
import { getVersionInfo } from './versionInfo';
import * as providers from './providers';
import { IVersionAndStoreUrl } from './providers/types';
import {
getLatestVersion,
defaultOption as defaultOptionForLatestVersion,
} from './getLatestVersion';
const DELIMITER = '.';
function getVersionWithDepth(version: string, depth: number): string {
let versionArray = null;
if (version.indexOf(DELIMITER) === -1) {
versionArray = [version];
} else {
versionArray = version
.split(DELIMITER)
.slice(0, Math.min(depth, version.length));
}
return [...versionArray, ...[0, 0, 0].slice(0, 3 - versionArray.length)].join(
DELIMITER
);
}
export type NeedUpdateOption = {
currentVersion?: string,
latestVersion?: string,
depth?: number,
ignoreErrors?: boolean,
};
export type NeedUpdateResult = {
isNeeded: boolean,
storeUrl: string,
currentVersion: string,
latestVersion: string,
};
export default async function needUpdate(
needUpdateOption: ?NeedUpdateOption = {}
): Promise<NeedUpdateResult> {
const option = {
currentVersion: null,
latestVersion: null,
depth: Infinity,
ignoreErrors: true,
...defaultOptionForLatestVersion,
...needUpdateOption,
};
try {
if (isNil(option.currentVersion)) {
option.currentVersion = getVersionInfo().getCurrentVersion();
}
let latestVersion;
let providerStoreUrl = '';
if (isNil(option.latestVersion)) {
if (option.provider.getVersion) {
const {
version,
storeUrl,
}: IVersionAndStoreUrl = await option.provider.getVersion(option);
latestVersion = version;
providerStoreUrl = storeUrl;
}
if (providers[option.provider]) {
const { version, storeUrl }: IVersionAndStoreUrl = await providers[
option.provider
].getVersion(option);
latestVersion = version;
providerStoreUrl = storeUrl;
}
option.latestVersion = latestVersion || (await getLatestVersion(option));
}
return checkIfUpdateNeeded(
option.currentVersion,
option.latestVersion,
option,
providerStoreUrl
);
} catch (e) {
if (option.ignoreErrors) {
console.warn(e);
} else {
throw e;
}
}
}
function checkIfUpdateNeeded(
currentVersion,
latestVersion,
option,
providerStoreUrl
) {
const currentVersionWithDepth = getVersionWithDepth(
currentVersion,
option.depth
);
const latestVersionWithDepth = getVersionWithDepth(
latestVersion,
option.depth
);
const response = {
isNeeded: semver.gt(latestVersionWithDepth, currentVersionWithDepth),
storeUrl: providerStoreUrl,
currentVersion,
latestVersion,
};
return Promise.resolve(response);
}