@redocly/cli
Version:
[@Redocly](https://redocly.com) CLI is your all-in-one OpenAPI utility. It builds, manages, improves, and quality-checks your OpenAPI descriptions, all of which comes in handy for various phases of the API Lifecycle. Create your own rulesets to make API g
100 lines • 3.74 kB
JavaScript
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import * as process from 'node:process';
import { existsSync, writeFileSync, readFileSync, statSync } from 'node:fs';
import { compare } from 'semver';
import { logger } from '@redocly/openapi-core';
import fetch from './fetch-with-timeout.js';
import { DEFAULT_FETCH_TIMEOUT } from './constants.js';
import { cyan, green, yellow } from 'colorette';
import { cleanColors } from './miscellaneous.js';
import { version, name } from './package.js';
const VERSION_CACHE_FILE = 'redocly-cli-version';
const SPACE_TO_BORDER = 4;
const INTERVAL_TO_CHECK = 1000 * 60 * 60 * 12;
const SHOULD_NOT_NOTIFY = process.env.NODE_ENV === 'test' ||
process.env.CI ||
!!process.env.LAMBDA_TASK_ROOT ||
process.env.REDOCLY_SUPPRESS_UPDATE_NOTICE === 'true';
export const notifyUpdateCliVersion = () => {
if (SHOULD_NOT_NOTIFY) {
return;
}
try {
const latestVersion = readFileSync(join(tmpdir(), VERSION_CACHE_FILE)).toString();
if (isNewVersionAvailable(version, latestVersion)) {
renderUpdateBanner(version, latestVersion);
}
}
catch (e) {
return;
}
};
const isNewVersionAvailable = (current, latest) => compare(current, latest) < 0;
const getLatestVersion = async (packageName) => {
const latestUrl = `http://registry.npmjs.org/${packageName}/latest`;
try {
const response = await fetch(latestUrl, { timeout: DEFAULT_FETCH_TIMEOUT });
const info = await response.json();
return info.version;
}
catch {
// Do nothing
return;
}
};
export const cacheLatestVersion = () => {
if (!isNeedToBeCached() || SHOULD_NOT_NOTIFY) {
return;
}
getLatestVersion(name)
.then((version) => {
if (version) {
const lastCheckFile = join(tmpdir(), VERSION_CACHE_FILE);
writeFileSync(lastCheckFile, version);
}
})
.catch(() => { });
};
const renderUpdateBanner = (current, latest) => {
const messageLines = [
`A new version of ${cyan('Redocly CLI')} (${green(latest)}) is available.`,
`Update now: \`${cyan('npm i -g @redocly/cli@latest')}\`.`,
`Changelog: https://redocly.com/docs/cli/changelog/`,
];
const maxLength = Math.max(...messageLines.map((line) => cleanColors(line).length));
const border = yellow('═'.repeat(maxLength + SPACE_TO_BORDER));
const extraSpaces = ' '.repeat(SPACE_TO_BORDER);
const banner = [
'',
extraSpaces + yellow('╔' + border + '╗'),
extraSpaces + yellow('║' + ' '.repeat(maxLength + SPACE_TO_BORDER) + '║'),
messageLines.map(getLineWithPadding(maxLength, extraSpaces)).join('\n'),
extraSpaces + yellow('║' + ' '.repeat(maxLength + SPACE_TO_BORDER) + '║'),
extraSpaces + yellow('╚' + border + '╝'),
'',
'',
].join('\n');
logger.info(banner);
};
const getLineWithPadding = (maxLength, extraSpaces) => (line) => {
const padding = ' '.repeat(maxLength - cleanColors(line).length);
return `${extraSpaces}${yellow('║')} ${line}${padding} ${yellow('║')}`;
};
const isNeedToBeCached = () => {
try {
// Last version from npm is stored in a file in the OS temp folder
const versionFile = join(tmpdir(), VERSION_CACHE_FILE);
if (!existsSync(versionFile)) {
return true;
}
const now = new Date().getTime();
const stats = statSync(versionFile);
const lastCheck = stats.mtime.getTime();
return now - lastCheck >= INTERVAL_TO_CHECK;
}
catch (e) {
return false;
}
};
//# sourceMappingURL=update-version-notifier.js.map