update
This commit is contained in:
169
ts/smartupdate.classes.notifier.ts
Normal file
169
ts/smartupdate.classes.notifier.ts
Normal file
@@ -0,0 +1,169 @@
|
||||
import * as plugins from './smartupdate.plugins.js';
|
||||
import {
|
||||
LOG_LEVELS,
|
||||
type TLogLevel,
|
||||
DEFAULT_MESSAGE_COLOR,
|
||||
MESSAGE_PREFIXES,
|
||||
} from './smartupdate.constants.js';
|
||||
import type { INotificationOptions, IUpdateCheckResult } from './smartupdate.interfaces.js';
|
||||
|
||||
/**
|
||||
* Handles all user-facing notifications and console output
|
||||
*/
|
||||
export class UpdateNotifier {
|
||||
private logLevel: TLogLevel;
|
||||
private useColors: boolean;
|
||||
private customLogger?: (level: TLogLevel, message: string) => void;
|
||||
|
||||
constructor(options: INotificationOptions) {
|
||||
this.logLevel = options.logLevel;
|
||||
this.useColors = options.useColors && !process.env.NO_COLOR;
|
||||
this.customLogger = options.customLogger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a message at the given level should be logged
|
||||
*/
|
||||
private shouldLog(level: TLogLevel): boolean {
|
||||
return LOG_LEVELS[level] <= LOG_LEVELS[this.logLevel];
|
||||
}
|
||||
|
||||
/**
|
||||
* Colorize a string if colors are enabled
|
||||
*/
|
||||
private colorize(text: string, color: any = DEFAULT_MESSAGE_COLOR): string {
|
||||
if (!this.useColors) {
|
||||
return text;
|
||||
}
|
||||
return plugins.consolecolor.coloredString(text, color as any);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log a message at the specified level
|
||||
*/
|
||||
private log(level: TLogLevel, message: string): void {
|
||||
if (!this.shouldLog(level)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.customLogger) {
|
||||
this.customLogger(level, message);
|
||||
} else {
|
||||
console.log(message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Log a debug message
|
||||
*/
|
||||
public debug(message: string): void {
|
||||
this.log('DEBUG', `${MESSAGE_PREFIXES.INFO} ${message}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log an info message
|
||||
*/
|
||||
public info(message: string): void {
|
||||
this.log('INFO', `${MESSAGE_PREFIXES.SMARTUPDATE} ${message}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log a warning message
|
||||
*/
|
||||
public warn(message: string): void {
|
||||
this.log('WARN', `${MESSAGE_PREFIXES.WARN} ${message}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log an error message
|
||||
*/
|
||||
public error(message: string): void {
|
||||
this.log('ERROR', `${MESSAGE_PREFIXES.ERROR} ${message}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify about checking for updates
|
||||
*/
|
||||
public notifyCheckingForUpdate(packageName: string): void {
|
||||
this.info(
|
||||
`checking for newer version of ${this.colorize(packageName)}...`
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify that the package is up to date
|
||||
*/
|
||||
public notifyUpToDate(packageName: string): void {
|
||||
this.info(
|
||||
`You are running the latest version of ${this.colorize(packageName)}`
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify that an update is available
|
||||
*/
|
||||
public notifyUpdateAvailable(packageName: string, currentVersion: string, latestVersion: string): void {
|
||||
this.warn(`There is a newer version of ${packageName} available on npm.`);
|
||||
this.warn(`Your version: ${currentVersion} | version on npm: ${latestVersion}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify that a check was skipped due to rate limiting
|
||||
*/
|
||||
public notifyCheckSkipped(packageName: string, nextCheckMinutes: number): void {
|
||||
const minutes = Math.floor(nextCheckMinutes) + 1;
|
||||
this.info(
|
||||
`Already checked recently. Next check available in ${minutes} minute${minutes !== 1 ? 's' : ''}: ` +
|
||||
this.colorize(packageName)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify that the changelog is being opened
|
||||
*/
|
||||
public notifyOpeningChangelog(): void {
|
||||
this.info('Opening changelog in browser...');
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify about a registry error
|
||||
*/
|
||||
public notifyRegistryError(): void {
|
||||
this.warn('Failed to retrieve package information.');
|
||||
this.info('Is the registry down?');
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify with a complete update check result
|
||||
*/
|
||||
public notifyUpdateCheckResult(result: IUpdateCheckResult): void {
|
||||
switch (result.status) {
|
||||
case 'up-to-date':
|
||||
this.notifyUpToDate(result.packageName);
|
||||
break;
|
||||
|
||||
case 'update-available':
|
||||
if (result.latestVersion) {
|
||||
this.notifyUpdateAvailable(
|
||||
result.packageName,
|
||||
result.currentVersion,
|
||||
result.latestVersion
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'check-skipped':
|
||||
if (result.nextCheckTime && result.reason) {
|
||||
const minutesUntilNext = (result.nextCheckTime.getTime() - result.checkTime.getTime()) / 60000;
|
||||
this.notifyCheckSkipped(result.packageName, minutesUntilNext);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'error':
|
||||
if (result.error) {
|
||||
this.error(result.error.message);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user