packages/pluginutils/src/plugin-logger.ts
import { isString } from 'lodash';
import { LogLevel, Logger } from 'typedoc';
import type { ABasePlugin } from './base-plugin';
export class PluginLogger extends Logger {
public constructor( private readonly _parent: Logger, private readonly _plugin: ABasePlugin, private readonly _context?: string ){
super();
this.level = this._parent.level;
}
/**
* Create a new {@link PluginLogger} for the given context.
*
* @param context - The new logger context.
* @returns the new logger.
*/
public makeChildLogger( context?: string ){
const newLogger = new PluginLogger( this._parent, this._plugin, context );
newLogger.level = this.level;
return newLogger;
}
/**
* Log the given verbose message.
*
* @param text - The message that should be logged.
*/
public verbose( text: string | ( () => string ) ): void {
this.log( text, LogLevel.Verbose );
}
/**
* Log the given info message.
*
* @param text - The message that should be logged.
*/
public info( text: string | ( () => string ) ): void {
this.log( text, LogLevel.Info );
}
/**
* Log the given warning message.
*
* @param text - The warning that should be logged.
*/
public warn( text: string | ( () => string ) ): void {
this.log( text, LogLevel.Warn );
}
/**
* Log the given deprecation message.
*
* @param text - The message that should be logged.
* @param addStack - TODO: Not sure why ?
*/
public deprecated( text: string | ( () => string ), addStack?: boolean ): void {
if ( addStack ) {
const stack = new Error().stack?.split( '\n' );
if ( stack && stack.length >= 4 ) {
text = () => `${text}\n${stack[3]}`;
}
}
this.warn( text );
}
/**
* Log the given error message.
*
* @param text - The error that should be logged.
*/
public error( text: string | ( () => string ) ): void {
this.log( text, LogLevel.Error );
}
/**
* Print a log message.
*
* @param message - The message itself.
* @param level - The urgency of the log message.
*/
public log( message: string | ( () => string ), level: LogLevel ): void {
if( level < this.level ){
return;
}
this._logThroughParent( message, level );
}
/**
* Pass a log message to the parent.
*
* @param message - The message itself.
* @param level - The urgency of the log message.
*/
private _logThroughParent( message: string | ( () => string ), level: LogLevel ){
if( this._parent instanceof PluginLogger ){
this._parent._logThroughParent( message, level );
} else {
const loggerMethodMapper = {
[LogLevel.Error]: 'error',
[LogLevel.Warn]: 'warn',
[LogLevel.Info]: 'info',
[LogLevel.Verbose]: 'verbose',
} as const;
const parentMethod = loggerMethodMapper[level];
const orignalLevel = this._parent.level;
this._parent.level = LogLevel.Verbose;
this._parent[parentMethod]( this._formatMessage( isString( message ) ? message : message() ) );
this._parent.level = orignalLevel;
}
}
/**
* Format the given message.
*
* @param message - The message to format.
* @returns the formatted message;
*/
private _formatMessage( message: string ){
let fullMessage = `[${this._plugin.package.name}]`;
if( this._context ){
fullMessage += ': ';
fullMessage += this._context;
}
fullMessage += ' ⇒ ';
fullMessage += message;
return fullMessage;
}
}